Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Threema/Threema/Settings/   (Social Medium ©)  Datei vom 26.9.2026 mit Größe 7 kB image not shown  

Quelle  MultiDeviceViewController.swift   Sprache: JAVA

 

import CocoaLumberjackSwift
import Foundation
import SwiftUI
import ThreemaMacros

final class MultiDeviceViewController: ThemedTableViewController {

    // MARK: - Properties

    let activityIndicator = UIActivityIndicatorView(style: .medium)

    // MARK: - Private properties

    private let refreshControlTableView = UIRefreshControl()

    var thisDevice: DeviceInfo?
    var otherDevices: [DeviceInfo]?

    // MARK: - Init

    init() {
        super.init(style: .insetGrouped)
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // MARK: - Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()

        setupViews()

        title = #localize("multi_device_linked_devices_title")
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(wizardUpdate),
            name: NSNotification.Name(rawValue: kNotificationMultiDeviceWizardDidUpdate),
            object: nil
        )
        
        registerHeaderAndCells()
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        refreshControlTableView.attributedTitle = NSAttributedString(
            string: #localize("multi_device_linked_devices_refresh")
        )
        refreshControlTableView.addTarget(self, action: #selector(refreshTableView), for: UIControl.Event.valueChanged)
        tableView?.addSubview(refreshControlTableView)
        
        tableView.estimatedRowHeight = 44.0
        tableView.rowHeight = UITableView.automaticDimension

        load()
    }
    
    // MARK: - Configuration

    func registerHeaderAndCells() {
        tableView.registerCell(MultiThisDeviceCell.self)
        tableView.registerCell(MultiDeviceCell.self)
    }
    
    // MARK: - Private functions
    
    /// Load this device, other devices and reload view
    func load() {
        DispatchQueue.main.async {
            self.activityIndicator.hidesWhenStopped = true
            self.activityIndicator.startAnimating()
        }

        let bi = BusinessInjector.ui
        thisDevice = bi.multiDeviceManager.thisDevice

        if bi.userSettings.enableMultiDevice {
            bi.multiDeviceManager.otherDevices()
                .done { items in
                    self.otherDevices = items
                }
                .ensure {
                    self.tableView.reloadData()
                    self.activityIndicator.stopAnimating()
                }
                .catch { error in
                    let msg = String.localizedStringWithFormat(
                        #localize("multi_device_linked_devices_loading_failed"),
                        error as CVarArg
                    )
                    DDLogError("\(msg)")

                    UIAlertTemplate.showOKAlert(
                        owner: self,
                        title: #localize("multi_device_linked_devices_failed_to_load_title"),
                        message: #localize(
                            "multi_device_linked_devices_failed_to_load_message"
                        )
                    )
                }
        }
        else {
            otherDevices = []

            DispatchQueue.main.async {
                self.tableView.reloadData()
                self.activityIndicator.stopAnimating()
            }
        }
    }

    func showAlertRemoveDeviceFailed() {
        UIAlertTemplate.showOKAlert(
            owner: self,
            title: #localize("multi_device_linked_devices_failed_remove_title"),
            message: #localize("multi_device_linked_devices_failed_remove_message_2")
        )
    }

    // MARK: - Helpers

    private func setupViews() {
        tableView.delegate = self
        tableView.dataSource = self
    }

    @objc private func wizardUpdate() {
        load()
    }
}

// MARK: - Table view

extension MultiDeviceViewController {

    override func numberOfSections(in tableView: UITableView) -> Int {
        guard let otherDevicesCount = otherDevices?.count else {
            return 1
        }
        
        guard otherDevicesCount > 0 else {
            return 1
        }
        
        return 2
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        section == 0 ? 1 : otherDevices?.count ?? 0
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.section == 0 {
            let cell = tableView.dequeueReusableCell(
                withIdentifier: "MultiThisDeviceCell",
                for: indexPath
            ) as! MultiThisDeviceCell
            cell.parentViewController = self
            cell.deviceInfo = thisDevice

            let bi = BusinessInjector.ui

            cell.enabled = bi.userSettings.enableMultiDevice
            return cell
        }
        else {
            let cell = tableView.dequeueReusableCell(
                withIdentifier: "MultiDeviceCell",
                for: indexPath
            ) as! MultiDeviceCell
            cell.deviceInfo = otherDevices?[indexPath.row]
            return cell
        }
    }

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        section == 0 ? #localize("multi_device_linked_devices_this") : #localize("multi_device_linked_devices_others")
    }

    override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
        if section == 0 {
            return #localize("multi_device_linked_devices_desc")
        }
        return nil
    }
    
    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        indexPath.section == 1
    }

    override func tableView(
        _ tableView: UITableView,
        commit editingStyle: UITableViewCell.EditingStyle,
        forRowAt indexPath: IndexPath
    ) {
        if editingStyle == .delete,
           let otherDevicesCount = otherDevices?.count {
            activityIndicator.hidesWhenStopped = true
            activityIndicator.startAnimating()

            let dl = DeviceLinking(businessInjector: BusinessInjector.ui)

            if otherDevicesCount == 1 {
                dl.disableMultiDevice()
                    .ensure {
                        self.load()
                        self.activityIndicator.stopAnimating()
                    }
                    .catch { error in
                        DDLogError("Disable Multi Device failed: \(error)")
                        self.showAlertRemoveDeviceFailed()
                    }
            }
            else if let item = otherDevices?[indexPath.row] {
                dl.drop(items: [item])
                    .ensure {
                        self.load()
                        self.activityIndicator.stopAnimating()
                    }
                    .catch { error in
                        DDLogError("Drop device failed: \(error)")
                        self.showAlertRemoveDeviceFailed()
                    }
            }
        }
    }
    
    override func tableView(
        _ tableView: UITableView,
        willDisplay cell: UITableViewCell,
        forRowAt indexPath: IndexPath
    ) {
        guard let multiDeviceCell = cell as? MultiDeviceCell else {
            return
        }
        
        // This a hack, because `ThemedTableViewController` resets all the colors. We should remove this behavior
        // of `ThemedTableViewController` in the future.
        multiDeviceCell.updateColors()
    }

    /// Pull to refresh
    @objc func refreshTableView(refreshControl: UIRefreshControl) {
        load()
        refreshControl.endRefreshing()
    }
}

// MARK: - UIViewControllerRepresentable

struct MultiDeviceViewControllerRepresentable: UIViewControllerRepresentable {
    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { }
    
    func makeUIViewController(context: Context) -> some UIViewController {
        MultiDeviceViewController()
    }
}

Messung
CHZG
849610093

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.