mirror of
https://github.com/luxfi/safe-ios.git
synced 2026-10-30 15:19:20 +00:00
206 lines
7.8 KiB
Swift
206 lines
7.8 KiB
Swift
//
|
|
// SwitchSafesViewController.swift
|
|
// Multisig
|
|
//
|
|
// Created by Dmitry Bespalov on 30.10.20.
|
|
// Copyright © 2020 Gnosis Ltd. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
final class SwitchSafesViewController: UITableViewController {
|
|
var notificationCenter = NotificationCenter.default
|
|
|
|
private var chainSafes = Chain.ChainSafes()
|
|
private let addSafeSection = 0
|
|
|
|
var onCreateSafe: (() -> ())?
|
|
var onAddSafe: (() -> ())?
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
title = "Switch Safe Accounts"
|
|
navigationItem.leftBarButtonItem = UIBarButtonItem(
|
|
barButtonSystemItem: .close, target: self, action: #selector(didTapCloseButton))
|
|
|
|
if #unavailable(iOS 15) {
|
|
// explicitly set background color to prevent transparent background in dark mode (iOS 14)
|
|
navigationController?.navigationBar.backgroundColor = .backgroundSecondary
|
|
}
|
|
tableView.register(AddSafeTableViewCell.nib(), forCellReuseIdentifier: "AddSafe")
|
|
tableView.register(SafeEntryTableViewCell.nib(), forCellReuseIdentifier: "SafeEntry")
|
|
tableView.registerHeaderFooterView(NetworkIndicatorHeaderView.self)
|
|
|
|
if #available(iOS 15.0, *) {
|
|
tableView.sectionHeaderTopPadding = 0
|
|
}
|
|
|
|
notificationCenter.addObserver(
|
|
self, selector: #selector(reloadData), name: .selectedSafeChanged, object: nil)
|
|
notificationCenter.addObserver(
|
|
self, selector: #selector(reloadData), name: .selectedSafeUpdated, object: nil)
|
|
|
|
reloadData()
|
|
}
|
|
|
|
override func viewDidAppear(_ animated: Bool) {
|
|
super.viewDidAppear(animated)
|
|
Tracker.trackEvent(.safeSwitch)
|
|
}
|
|
|
|
@objc private func reloadData() {
|
|
chainSafes = Chain.chainSafes()
|
|
tableView.reloadData()
|
|
}
|
|
|
|
@objc override func closeModal() {
|
|
// this will close this controller when the load Safe Account modal is closed
|
|
presentingViewController?.dismiss(animated: true, completion: nil)
|
|
}
|
|
|
|
@objc private func didTapCloseButton() {
|
|
dismiss(animated: true, completion: nil)
|
|
}
|
|
|
|
// MARK: - UITableViewDataSource
|
|
|
|
override func numberOfSections(in tableView: UITableView) -> Int {
|
|
chainSafes.count + 1 /* for Add Safe button */
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
|
if section == addSafeSection {
|
|
return 1
|
|
} else {
|
|
return chainSafes[section - 1].safes.count
|
|
}
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
|
if indexPath.section == addSafeSection {
|
|
return tableView.dequeueReusableCell(withIdentifier: "AddSafe", for: indexPath)
|
|
}
|
|
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: "SafeEntry", for: indexPath) as! SafeEntryTableViewCell
|
|
let safe = chainSafes[indexPath.section - 1].safes[indexPath.row]
|
|
cell.setName(safe.displayName)
|
|
cell.setProgress(enabled: false)
|
|
|
|
switch safe.safeStatus {
|
|
case .deployed:
|
|
cell.setAddress(safe.addressValue)
|
|
cell.setDetail(address: safe.addressValue, prefix: safe.chain!.shortName)
|
|
|
|
case .deploying, .indexing:
|
|
cell.setAddress(safe.addressValue, grayscale: true)
|
|
cell.setDetail(text: "Creating in progress...", style: .bodyTertiary)
|
|
cell.setProgress(enabled: true)
|
|
|
|
case .deploymentFailed:
|
|
cell.setAddress(safe.addressValue, grayscale: true)
|
|
cell.setDetail(text: "Failed to create", style: .bodyError)
|
|
}
|
|
|
|
cell.setSelection(safe.isSelected)
|
|
return cell
|
|
}
|
|
|
|
// MARK: - UITableViewDelegate
|
|
|
|
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
|
|
indexPath.section == addSafeSection ? 54 : 66
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
tableView.deselectRow(at: indexPath, animated: true)
|
|
if indexPath.section == addSafeSection {
|
|
let alertController = UIAlertController(
|
|
title: nil,
|
|
message: nil,
|
|
preferredStyle: .multiplatformActionSheet)
|
|
|
|
let addSafe = UIAlertAction(title: "Load existing Safe Account", style: .default) { [weak self] _ in
|
|
self?.onAddSafe?()
|
|
}
|
|
|
|
let createSafe = UIAlertAction(title: "Create new Safe Account", style: .default) { [weak self] _ in
|
|
self?.onCreateSafe?()
|
|
}
|
|
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
|
|
alertController.addAction(addSafe)
|
|
alertController.addAction(createSafe)
|
|
alertController.addAction(cancel)
|
|
|
|
if let popoverPresentationController = alertController.popoverPresentationController {
|
|
popoverPresentationController.sourceView = tableView
|
|
popoverPresentationController.sourceRect = tableView.rectForRow(at: indexPath)
|
|
}
|
|
|
|
self.present(alertController, animated: true)
|
|
} else {
|
|
let safe = chainSafes[indexPath.section - 1].safes[indexPath.row]
|
|
if !safe.isSelected {
|
|
safe.select()
|
|
didTapCloseButton()
|
|
}
|
|
}
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
|
guard section != addSafeSection else { return nil }
|
|
|
|
let view = tableView.dequeueHeaderFooterView(NetworkIndicatorHeaderView.self)
|
|
let chain = chainSafes[section - 1].chain
|
|
view.text = chain.name
|
|
view.dotColor = chain.backgroundColor
|
|
return view
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
|
section == addSafeSection ? 0 : NetworkIndicatorHeaderView.height
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
|
|
indexPath.section != addSafeSection
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
|
|
let safe = chainSafes[indexPath.section - 1].safes[indexPath.row]
|
|
|
|
var actions = [UIContextualAction]()
|
|
|
|
let deleteAction = UIContextualAction(style: .destructive, title: "Remove") { [weak self] _, _, completion in
|
|
self?.remove(safe: safe, sourceIndexPath: indexPath)
|
|
completion(true)
|
|
}
|
|
actions.append(deleteAction)
|
|
|
|
return UISwipeActionsConfiguration(actions: actions)
|
|
}
|
|
|
|
private func remove(safe: Safe, sourceIndexPath: IndexPath) {
|
|
let title = safe.safeStatus == .deployed ?
|
|
"Removing a Safe only removes it from this app. It does not delete the Safe from the blockchain. Funds will not get lost." :
|
|
"Are you sure you want to remove this Safe? The transaction fees will not be returned."
|
|
let alertController = UIAlertController(
|
|
title: nil,
|
|
message: title,
|
|
preferredStyle: .multiplatformActionSheet)
|
|
|
|
let remove = UIAlertAction(title: "Remove", style: .destructive) { _ in
|
|
Safe.remove(safe: safe)
|
|
}
|
|
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
|
|
alertController.addAction(remove)
|
|
alertController.addAction(cancel)
|
|
|
|
if let popoverPresentationController = alertController.popoverPresentationController {
|
|
popoverPresentationController.sourceView = tableView
|
|
popoverPresentationController.sourceRect = tableView.rectForRow(at: sourceIndexPath)
|
|
}
|
|
|
|
self.present(alertController, animated: true)
|
|
}
|
|
}
|