import UIKit import Shared import Combine import AppCore import Dependencies import AppResources import AppNavigation import DrawerFeature public final class MenuController: UIViewController { @Dependency(\.navigator) var navigator @Dependency(\.app.statusBar) var statusBar private lazy var screenView = MenuView() private let currentItem: MenuItem private let viewModel = MenuViewModel() private var cancellables = Set<AnyCancellable>() private var drawerCancellables = Set<AnyCancellable>() private var navController: UINavigationController? public init( _ currentItem: MenuItem, _ navController: UINavigationController? = nil ) { self.currentItem = currentItem self.navController = navController super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { nil } public override func loadView() { view = screenView } public override func viewDidLoad() { super.viewDidLoad() screenView.headerView.set( username: viewModel.username, image: viewModel.avatar ) switch currentItem { case .scan: screenView.scanButton.set(color: Asset.brandPrimary.color) case .chats: screenView.chatsButton.set(color: Asset.brandPrimary.color) case .contacts: screenView.contactsButton.set(color: Asset.brandPrimary.color) case .requests: screenView.requestsButton.set(color: Asset.brandPrimary.color) case .settings: screenView.settingsButton.set(color: Asset.brandPrimary.color) default: break } screenView.xxdkVersionLabel.text = "XXDK \(viewModel.xxdk)" screenView.buildLabel.text = Localized.Menu.build(viewModel.build) screenView.versionLabel.text = Localized.Menu.version(viewModel.version) setupBindings() } public override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) statusBar.set(.lightContent) } public override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) statusBar.set(.darkContent) } private func setupBindings() { screenView .headerView .scanButton .publisher(for: .touchUpInside) .receive(on: DispatchQueue.main) .sink { [unowned self] in navigator.perform(DismissModal(from: self)) { [weak self] in guard let self, self.currentItem != .scan else { return } self.navigator.perform(PresentScan(on: self.navController!)) } }.store(in: &cancellables) screenView .headerView .nameButton .publisher(for: .touchUpInside) .receive(on: DispatchQueue.main) .sink { [unowned self] in navigator.perform(DismissModal(from: self)) { [weak self] in guard let self, self.currentItem != .profile else { return } self.navigator.perform(PresentProfile(on: self.navController!)) } }.store(in: &cancellables) screenView .scanButton .publisher(for: .touchUpInside) .receive(on: DispatchQueue.main) .sink { [unowned self] in navigator.perform(DismissModal(from: self)) { [weak self] in guard let self, self.currentItem != .scan else { return } self.navigator.perform(PresentScan(on: self.navController!)) } }.store(in: &cancellables) screenView .chatsButton .publisher(for: .touchUpInside) .receive(on: DispatchQueue.main) .sink { [unowned self] in navigator.perform(DismissModal(from: self)) { [weak self] in guard let self, self.currentItem != .chats else { return } self.navigator.perform(PresentChatList(on: self.navController!)) } }.store(in: &cancellables) screenView .contactsButton .publisher(for: .touchUpInside) .receive(on: DispatchQueue.main) .sink { [unowned self] in navigator.perform(DismissModal(from: self)) { [weak self] in guard let self, self.currentItem != .contacts else { return } self.navigator.perform(PresentContactList(on: self.navController!)) } }.store(in: &cancellables) screenView .settingsButton .publisher(for: .touchUpInside) .receive(on: DispatchQueue.main) .sink { [unowned self] in navigator.perform(DismissModal(from: self)) { [weak self] in guard let self, self.currentItem != .settings else { return } self.navigator.perform(PresentSettings(on: self.navController!)) } }.store(in: &cancellables) screenView .dashboardButton .publisher(for: .touchUpInside) .receive(on: DispatchQueue.main) .sink { [unowned self] in navigator.perform(DismissModal(from: self)) { [weak self] in guard let self, self.currentItem != .dashboard else { return } self.presentDrawer( title: Localized.ChatList.Dashboard.title, subtitle: Localized.ChatList.Dashboard.subtitle, actionTitle: Localized.ChatList.Dashboard.open) { guard let url = URL(string: "https://dashboard.xx.network") else { return } UIApplication.shared.open(url, options: [:]) } } }.store(in: &cancellables) screenView .requestsButton .publisher(for: .touchUpInside) .receive(on: DispatchQueue.main) .sink { [unowned self] in navigator.perform(DismissModal(from: self)) { [weak self] in guard let self, self.currentItem != .requests else { return } self.navigator.perform(PresentRequests(on: self.navController!)) } }.store(in: &cancellables) screenView .joinButton .publisher(for: .touchUpInside) .receive(on: DispatchQueue.main) .sink { [unowned self] in navigator.perform(DismissModal(from: self)) { [weak self] in guard let self, self.currentItem != .join else { return } self.presentDrawer( title: Localized.ChatList.Join.title, subtitle: Localized.ChatList.Join.subtitle, actionTitle: Localized.ChatList.Dashboard.open) { guard let url = URL(string: "https://xx.network") else { return } UIApplication.shared.open(url, options: [:]) } } }.store(in: &cancellables) screenView .shareButton .publisher(for: .touchUpInside) .receive(on: DispatchQueue.main) .sink { [unowned self] in navigator.perform(DismissModal(from: self)) { [weak self] in guard let self, self.currentItem != .share else { return } self.navigator.perform(PresentActivitySheet(items: [ Localized.Menu.shareContent(self.viewModel.referralDeeplink) ], from: self.navController!.topViewController!)) } }.store(in: &cancellables) viewModel .requestCount .receive(on: DispatchQueue.main) .sink { [weak screenView] in screenView?.requestsButton.updateNotification($0) }.store(in: &cancellables) } private func presentDrawer( title: String, subtitle: String, actionTitle: String, action: @escaping () -> Void ) { let actionButton = DrawerCapsuleButton(model: .init( title: actionTitle, style: .red )) actionButton .action .receive(on: DispatchQueue.main) .sink { [unowned self] in navigator.perform(DismissModal(from: self)) { [weak self] in guard let self else { return } self.drawerCancellables.removeAll() action() } }.store(in: &drawerCancellables) navigator.perform(PresentDrawer(items: [ DrawerText( font: Fonts.Mulish.bold.font(size: 26.0), text: title, color: Asset.neutralActive.color, alignment: .left, spacingAfter: 19 ), DrawerText( font: Fonts.Mulish.regular.font(size: 16.0), text: subtitle, color: Asset.neutralBody.color, alignment: .left, lineHeightMultiple: 1.1, spacingAfter: 39 ), actionButton ], isDismissable: true, from: navController!.topViewController!)) } }