123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884 |
- import UIKit
- import ALCameraViewController
- import Photos
- import MobileCoreServices
- import DcCore
- class AppCoordinator: NSObject, Coordinator {
- private let window: UIWindow
- private let dcContext: DcContext
- private let qrTab = 0
- private let chatsTab = 1
- private let settingsTab = 2
- private let appStateRestorer = AppStateRestorer.shared
- private var childCoordinators: [Coordinator] = []
- private lazy var tabBarController: UITabBarController = {
- let tabBarController = UITabBarController()
- tabBarController.delegate = appStateRestorer
- tabBarController.viewControllers = [qrController, chatListController, settingsController]
- tabBarController.tabBar.tintColor = DcColors.primary
- return tabBarController
- }()
- private lazy var welcomeController: WelcomeViewController = {
- let welcomeController = WelcomeViewController(dcContext: dcContext)
- welcomeController.coordinator = self
- return welcomeController
- }()
- private lazy var loginController: UIViewController = {
- let accountSetupController = AccountSetupController(dcContext: dcContext, editView: false)
- let nav = UINavigationController(rootViewController: accountSetupController)
- let coordinator = AccountSetupCoordinator(dcContext: dcContext, navigationController: nav)
- coordinator.onLoginSuccess = {
- [unowned self] in
- self.loginController.dismiss(animated: true) {
- self.presentTabBarController()
- }
- }
- childCoordinators.append(coordinator)
- accountSetupController.coordinator = coordinator
- return nav
- }()
- // MARK: viewControllers
- private lazy var qrController: UIViewController = {
- let controller = QrViewController(dcContext: dcContext)
- let nav = UINavigationController(rootViewController: controller)
- let settingsImage = UIImage(named: "qr_code")
- nav.tabBarItem = UITabBarItem(title: String.localized("qr_code"), image: settingsImage, tag: qrTab)
- let coordinator = QrViewCoordinator(navigationController: nav)
- self.childCoordinators.append(coordinator)
- controller.coordinator = coordinator
- return nav
- }()
- private lazy var chatListController: UIViewController = {
- let viewModel = ChatListViewModel(dcContext: dcContext, isArchive: false)
- let controller = ChatListController(dcContext: dcContext, viewModel: viewModel)
- let nav = UINavigationController(rootViewController: controller)
- let settingsImage = UIImage(named: "ic_chat")
- nav.tabBarItem = UITabBarItem(title: String.localized("pref_chats"), image: settingsImage, tag: chatsTab)
- let coordinator = ChatListCoordinator(dcContext: dcContext, navigationController: nav)
- self.childCoordinators.append(coordinator)
- controller.coordinator = coordinator
- return nav
- }()
- private lazy var settingsController: UIViewController = {
- let controller = SettingsViewController(dcContext: dcContext)
- let nav = UINavigationController(rootViewController: controller)
- let settingsImage = UIImage(named: "settings")
- nav.tabBarItem = UITabBarItem(title: String.localized("menu_settings"), image: settingsImage, tag: settingsTab)
- let coordinator = SettingsCoordinator(dcContext: dcContext, navigationController: nav)
- self.childCoordinators.append(coordinator)
- controller.coordinator = coordinator
- return nav
- }()
- init(window: UIWindow, dcContext: DcContext) {
- self.window = window
- self.dcContext = dcContext
- super.init()
- if dcContext.isConfigured() {
- presentTabBarController()
- } else {
- showWelcomeController()
- }
- }
- public func start() {
- let lastActiveTab = appStateRestorer.restoreLastActiveTab()
- if lastActiveTab == -1 {
- // no stored tab
- showTab(index: chatsTab)
- } else {
- showTab(index: lastActiveTab)
- if let lastActiveChatId = appStateRestorer.restoreLastActiveChatId(), lastActiveTab == 1 {
- showChat(chatId: lastActiveChatId, animated: false)
- }
- }
- }
- func showTab(index: Int) {
- tabBarController.selectedIndex = index
- }
- func showChat(chatId: Int, animated: Bool = true) {
- showTab(index: chatsTab)
- guard let navController = self.chatListController as? UINavigationController else {
- assertionFailure("huh? why no nav controller?")
- return
- }
- let chatVC = ChatViewController(dcContext: dcContext, chatId: chatId)
- let coordinator = ChatViewCoordinator(dcContext: dcContext, navigationController: navController, chatId: chatId)
- chatVC.coordinator = coordinator
- navController.pushViewController(chatVC, animated: animated)
- }
- func handleQRCode(_ code: String) {
- showTab(index: qrTab)
- if let navController = qrController as? UINavigationController,
- let topViewController = navController.topViewController,
- let qrViewController = topViewController as? QrViewController {
- qrViewController.handleQrCode(code)
- }
- }
- func presentWelcomeController(animated: Bool) {
- if animated {
- welcomeController.activateSpinner(true)
- showWelcomeController()
- DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
- self.welcomeController.activateSpinner(false)
- }
- } else {
- showWelcomeController()
- }
- }
- private func showWelcomeController() {
- // the applicationIconBadgeNumber is remembered by the system even on reinstalls (just tested on ios 13.3.1),
- // to avoid appearing an old number of a previous installation, we reset the counter manually.
- // but even when this changes in ios, we need the reset as we allow account-deletion also in-app.
- UIApplication.shared.applicationIconBadgeNumber = 0
- window.rootViewController = welcomeController
- window.makeKeyAndVisible()
- }
- func presentTabBarController() {
- window.rootViewController = tabBarController
- window.makeKeyAndVisible()
- showTab(index: chatsTab)
- }
- }
- extension AppCoordinator: WelcomeCoordinator {
- func showLogin() {
- // add cancel button item to accountSetupController
- if let nav = loginController as? UINavigationController, let loginController = nav.topViewController as? AccountSetupController {
- loginController.navigationItem.leftBarButtonItem = UIBarButtonItem(
- title: String.localized("cancel"),
- style: .done,
- target: self, action: #selector(cancelButtonPressed(_:))
- )
- loginController.coordinator?.onLoginSuccess = handleLoginSuccess
- }
- loginController.modalPresentationStyle = .fullScreen
- welcomeController.present(loginController, animated: true, completion: nil)
- }
-
- func handleLoginSuccess() {
- welcomeController.activateSpinner(true) // this will hide welcomeController's content
- DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
- self.loginController.dismiss(animated: true) { // this is ignored if loginController is not shown
- self.presentTabBarController()
- self.welcomeController.activateSpinner(false)
- }
- }
- }
- func handleQRAccountCreationSuccess() {
- self.presentTabBarController()
- self.welcomeController.activateSpinner(false)
- }
- @objc private func cancelButtonPressed(_ sender: UIBarButtonItem) {
- loginController.dismiss(animated: true, completion: nil)
- }
- }
- // since mailbox and chatView -tab both use ChatViewController we want to be able to assign different functionality via coordinators -> therefore we override unneeded functions such as showChatDetail -> maybe find better solution in longterm
- class MailboxCoordinator: ChatViewCoordinator {
- init(dcContext: DcContext, navigationController: UINavigationController) {
- super.init(dcContext: dcContext, navigationController: navigationController, chatId: -1)
- }
- override func showChatDetail(chatId _: Int) {
- // ignore for now
- }
- override func showCameraViewController(delegate: MediaPickerDelegate) {
- // ignore
- }
- override func showChat(chatId: Int) {
- if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
- navigationController.popToRootViewController(animated: false)
- appDelegate.appCoordinator.showChat(chatId: chatId)
- }
- }
- }
- class QrViewCoordinator: Coordinator {
- var navigationController: UINavigationController
- init(navigationController: UINavigationController) {
- self.navigationController = navigationController
- }
- func showChat(chatId: Int) {
- if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
- appDelegate.appCoordinator.showChat(chatId: chatId)
- }
- }
- }
- class ChatListCoordinator: Coordinator {
- var dcContext: DcContext
- let navigationController: UINavigationController
- var childCoordinators: [Coordinator] = []
- init(dcContext: DcContext, navigationController: UINavigationController) {
- self.dcContext = dcContext
- self.navigationController = navigationController
- }
- func showNewChatController() {
- let newChatVC = NewChatViewController(dcContext: dcContext)
- let coordinator = NewChatCoordinator(dcContext: dcContext, navigationController: navigationController)
- childCoordinators.append(coordinator)
- newChatVC.coordinator = coordinator
- navigationController.pushViewController(newChatVC, animated: true)
- }
- func showChat(chatId: Int) {
- let chatVC = ChatViewController(dcContext: dcContext, chatId: chatId)
- let coordinator = ChatViewCoordinator(dcContext: dcContext, navigationController: navigationController, chatId: chatId)
- childCoordinators.append(coordinator)
- chatVC.coordinator = coordinator
- navigationController.pushViewController(chatVC, animated: true)
- }
- func showArchive() {
- let viewModel = ChatListViewModel(dcContext: dcContext, isArchive: true)
- let controller = ChatListController(dcContext: dcContext, viewModel: viewModel)
- let coordinator = ChatListCoordinator(dcContext: dcContext, navigationController: navigationController)
- childCoordinators.append(coordinator)
- controller.coordinator = coordinator
- navigationController.pushViewController(controller, animated: true)
- }
- func showNewChat(contactId: Int) {
- let chatId = dcContext.createChatByContactId(contactId: contactId)
- showChat(chatId: Int(chatId))
- }
- }
- class SettingsCoordinator: Coordinator {
- let dcContext: DcContext
- let navigationController: UINavigationController
- var childCoordinators: [Coordinator] = []
- init(dcContext: DcContext, navigationController: UINavigationController) {
- self.dcContext = dcContext
- self.navigationController = navigationController
- }
- func showEditSettingsController() {
- let editController = EditSettingsController(dcContext: dcContext)
- let coordinator = EditSettingsCoordinator(dcContext: dcContext, navigationController: navigationController)
- childCoordinators.append(coordinator)
- editController.coordinator = coordinator
- navigationController.pushViewController(editController, animated: true)
- }
- func showClassicMail() {
- let settingsClassicViewController = SettingsClassicViewController(dcContext: dcContext)
- navigationController.pushViewController(settingsClassicViewController, animated: true)
- }
- func showBlockedContacts() {
- let blockedContactsController = BlockedContactsViewController()
- navigationController.pushViewController(blockedContactsController, animated: true)
- }
- func showAutodelOptions() {
- let settingsAutodelOverviewController = SettingsAutodelOverviewController(dcContext: dcContext)
- navigationController.pushViewController(settingsAutodelOverviewController, animated: true)
- }
- func showContactRequests() {
- let deaddropViewController = MailboxViewController(dcContext: dcContext, chatId: Int(DC_CHAT_ID_DEADDROP))
- let deaddropCoordinator = MailboxCoordinator(dcContext: dcContext, navigationController: navigationController)
- deaddropViewController.coordinator = deaddropCoordinator
- childCoordinators.append(deaddropCoordinator)
- navigationController.pushViewController(deaddropViewController, animated: true)
- }
- func showHelp() {
- let helpViewController = HelpViewController()
- navigationController.pushViewController(helpViewController, animated: true)
- }
- }
- class EditSettingsCoordinator: Coordinator {
- var dcContext: DcContext
- let navigationController: UINavigationController
- let mediaPicker: MediaPicker
- init(dcContext: DcContext, navigationController: UINavigationController) {
- self.dcContext = dcContext
- self.navigationController = navigationController
- self.mediaPicker = MediaPicker(navigationController: navigationController)
- }
- func showPhotoPicker(delegate: MediaPickerDelegate) {
- mediaPicker.showPhotoGallery(delegate: delegate)
- }
- func showCamera(delegate: MediaPickerDelegate) {
- mediaPicker.showCamera(delegate: delegate)
- }
- }
- class AccountSetupCoordinator: Coordinator {
- var dcContext: DcContext
- let navigationController: UINavigationController
- var onLoginSuccess: (() -> Void)?
- init(dcContext: DcContext, navigationController: UINavigationController) {
- self.dcContext = dcContext
- self.navigationController = navigationController
- }
- func showCertCheckOptions() {
- let certificateCheckController = CertificateCheckController(dcContext: dcContext, sectionTitle: String.localized("login_certificate_checks"))
- navigationController.pushViewController(certificateCheckController, animated: true)
- }
- func showImapSecurityOptions() {
- let securitySettingsController = SecuritySettingsController(dcContext: dcContext, title: String.localized("login_imap_security"),
- type: SecurityType.IMAPSecurity)
- navigationController.pushViewController(securitySettingsController, animated: true)
- }
- func showSmptpSecurityOptions() {
- let securitySettingsController = SecuritySettingsController(dcContext: dcContext,
- title: String.localized("login_imap_security"),
- type: SecurityType.SMTPSecurity)
- navigationController.pushViewController(securitySettingsController, animated: true)
- }
- func openProviderInfo(provider: DcProvider) {
- guard let url = URL(string: provider.getOverviewPage) else { return }
- UIApplication.shared.open(url)
- }
- func navigateBack() {
- navigationController.popViewController(animated: true)
- }
- }
- class NewChatCoordinator: Coordinator {
- var dcContext: DcContext
- let navigationController: UINavigationController
- private var childCoordinators: [Coordinator] = []
- init(dcContext: DcContext, navigationController: UINavigationController) {
- self.dcContext = dcContext
- self.navigationController = navigationController
- }
- func showNewGroupController(isVerified: Bool) {
- let newGroupController = NewGroupController(dcContext: dcContext, isVerified: isVerified)
- let coordinator = NewGroupCoordinator(dcContext: dcContext, navigationController: navigationController)
- childCoordinators.append(coordinator)
- newGroupController.coordinator = coordinator
- navigationController.pushViewController(newGroupController, animated: true)
- }
- func showNewContactController() {
- let newContactController = NewContactController(dcContext: dcContext)
- let coordinator = EditContactCoordinator(dcContext: dcContext, navigationController: navigationController)
- childCoordinators.append(coordinator)
- newContactController.coordinator = coordinator
- navigationController.pushViewController(newContactController, animated: true)
- }
- func showNewChat(contactId: Int) {
- let chatId = dcContext.createChatByContactId(contactId: contactId)
- showChat(chatId: Int(chatId))
- }
- func showChat(chatId: Int) {
- let chatViewController = ChatViewController(dcContext: dcContext, chatId: chatId)
- let coordinator = ChatViewCoordinator(dcContext: dcContext, navigationController: navigationController, chatId: chatId)
- childCoordinators.append(coordinator)
- chatViewController.coordinator = coordinator
- navigationController.pushViewController(chatViewController, animated: true)
- navigationController.viewControllers.remove(at: 1)
- }
- func showContactDetail(contactId: Int) {
- let viewModel = ContactDetailViewModel(contactId: contactId, chatId: nil, context: dcContext)
- let contactDetailController = ContactDetailViewController(viewModel: viewModel)
- let coordinator = ContactDetailCoordinator(dcContext: dcContext, chatId: nil, navigationController: navigationController)
- childCoordinators.append(coordinator)
- contactDetailController.coordinator = coordinator
- navigationController.pushViewController(contactDetailController, animated: true)
- }
-
- }
- class GroupChatDetailCoordinator: Coordinator {
- var dcContext: DcContext
- let navigationController: UINavigationController
- let chatId: Int
- private var childCoordinators: [Coordinator] = []
- private var previewController: PreviewController?
- init(dcContext: DcContext, chatId: Int, navigationController: UINavigationController) {
- self.dcContext = dcContext
- self.chatId = chatId
- self.navigationController = navigationController
- }
- func showSingleChatEdit(contactId: Int) {
- let editContactController = EditContactController(dcContext: dcContext, contactIdForUpdate: contactId)
- let coordinator = EditContactCoordinator(dcContext: dcContext, navigationController: navigationController)
- childCoordinators.append(coordinator)
- editContactController.coordinator = coordinator
- navigationController.pushViewController(editContactController, animated: true)
- }
- func showAddGroupMember(chatId: Int) {
- let groupMemberViewController = AddGroupMembersViewController(chatId: chatId)
- let coordinator = AddGroupMembersCoordinator(dcContext: dcContext, navigationController: navigationController)
- childCoordinators.append(coordinator)
- groupMemberViewController.coordinator = coordinator
- navigationController.pushViewController(groupMemberViewController, animated: true)
- }
- func showQrCodeInvite(chatId: Int) {
- let qrInviteCodeController = QrInviteViewController(dcContext: dcContext, chatId: chatId)
- navigationController.pushViewController(qrInviteCodeController, animated: true)
- }
- func showGroupChatEdit(chat: DcChat) {
- let editGroupViewController = EditGroupViewController(chat: chat)
- let coordinator = EditGroupCoordinator(dcContext: dcContext, navigationController: navigationController)
- childCoordinators.append(coordinator)
- editGroupViewController.coordinator = coordinator
- navigationController.pushViewController(editGroupViewController, animated: true)
- }
- func showContactDetail(of contactId: Int) {
- let viewModel = ContactDetailViewModel(contactId: contactId, chatId: nil, context: dcContext)
- let contactDetailController = ContactDetailViewController(viewModel: viewModel)
- let coordinator = ContactDetailCoordinator(dcContext: dcContext, chatId: nil, navigationController: navigationController)
- childCoordinators.append(coordinator)
- contactDetailController.coordinator = coordinator
- navigationController.pushViewController(contactDetailController, animated: true)
- }
- func showDocuments() {
- presentPreview(for: DC_MSG_FILE, messageType2: DC_MSG_AUDIO, messageType3: 0)
- }
- func showGallery() {
- presentPreview(for: DC_MSG_IMAGE, messageType2: DC_MSG_GIF, messageType3: DC_MSG_VIDEO)
- }
- private func presentPreview(for messageType: Int32, messageType2: Int32, messageType3: Int32) {
- let messageIds = dcContext.getChatMedia(chatId: chatId, messageType: messageType, messageType2: messageType2, messageType3: messageType3)
- var mediaUrls: [URL] = []
- for messageId in messageIds {
- let message = DcMsg.init(id: messageId)
- if let url = message.fileURL {
- mediaUrls.insert(url, at: 0)
- }
- }
- previewController = PreviewController(currentIndex: 0, urls: mediaUrls)
- if let previewController = previewController {
- navigationController.pushViewController(previewController, animated: true)
- }
- }
- func deleteChat() {
- /*
- app will navigate to chatlist or archive and delete the chat there
- notify chatList/archiveList to delete chat AFTER is is visible
- */
- func notifyToDeleteChat() {
- NotificationCenter.default.post(name: dcNotificationChatDeletedInChatDetail, object: nil, userInfo: ["chat_id": self.chatId])
- }
- func showArchive() {
- self.navigationController.popToRootViewController(animated: false) // in main ChatList now
- let viewModel = ChatListViewModel(dcContext: dcContext, isArchive: true)
- let controller = ChatListController(dcContext: dcContext, viewModel: viewModel)
- let coordinator = ChatListCoordinator(dcContext: dcContext, navigationController: navigationController)
- childCoordinators.append(coordinator)
- controller.coordinator = coordinator
- navigationController.pushViewController(controller, animated: false)
- }
- CATransaction.begin()
- CATransaction.setCompletionBlock(notifyToDeleteChat)
- let chat = dcContext.getChat(chatId: chatId)
- if chat.isArchived {
- showArchive()
- } else {
- self.navigationController.popToRootViewController(animated: true) // in main ChatList now
- }
- CATransaction.commit()
- }
- }
- class ChatViewCoordinator: NSObject, Coordinator {
- var dcContext: DcContext
- let navigationController: UINavigationController
- let chatId: Int
- var chatViewController: ChatViewController!
- var childCoordinators: [Coordinator] = []
- let mediaPicker: MediaPicker
- init(dcContext: DcContext, navigationController: UINavigationController, chatId: Int) {
- self.dcContext = dcContext
- self.navigationController = navigationController
- self.chatId = chatId
- self.mediaPicker = MediaPicker(navigationController: self.navigationController)
- }
- func navigateBack() {
- navigationController.popViewController(animated: true)
- }
- func showChatDetail(chatId: Int) {
- let chat = dcContext.getChat(chatId: chatId)
- switch chat.chatType {
- case .SINGLE:
- if let contactId = chat.contactIds.first {
- let viewModel = ContactDetailViewModel(contactId: contactId, chatId: chatId, context: dcContext)
- let contactDetailController = ContactDetailViewController(viewModel: viewModel)
- let coordinator = ContactDetailCoordinator(dcContext: dcContext, chatId: chatId, navigationController: navigationController)
- childCoordinators.append(coordinator)
- contactDetailController.coordinator = coordinator
- navigationController.pushViewController(contactDetailController, animated: true)
- }
- case .GROUP, .VERIFIEDGROUP:
- let groupChatDetailViewController = GroupChatDetailViewController(chatId: chatId, context: dcContext) // inherits from ChatDetailViewController
- let coordinator = GroupChatDetailCoordinator(dcContext: dcContext, chatId: chatId, navigationController: navigationController)
- childCoordinators.append(coordinator)
- groupChatDetailViewController.coordinator = coordinator
- navigationController.pushViewController(groupChatDetailViewController, animated: true)
- }
- }
- func showContactDetail(of contactId: Int, in chatOfType: ChatType, chatId: Int?) {
- let viewModel = ContactDetailViewModel(contactId: contactId, chatId: chatId, context: dcContext )
- let contactDetailController = ContactDetailViewController(viewModel: viewModel)
- let coordinator = ContactDetailCoordinator(dcContext: dcContext, chatId: chatId, navigationController: navigationController)
- childCoordinators.append(coordinator)
- contactDetailController.coordinator = coordinator
- navigationController.pushViewController(contactDetailController, animated: true)
- }
- func showChat(chatId: Int) {
- let chatViewController = ChatViewController(dcContext: dcContext, chatId: chatId)
- let coordinator = ChatViewCoordinator(dcContext: dcContext, navigationController: navigationController, chatId: chatId)
- childCoordinators.append(coordinator)
- chatViewController.coordinator = coordinator
- navigationController.popToRootViewController(animated: false)
- navigationController.pushViewController(chatViewController, animated: true)
- }
- func showDocumentLibrary(delegate: MediaPickerDelegate) {
- mediaPicker.showDocumentLibrary(delegate: delegate)
- }
- func showVoiceMessageRecorder(delegate: MediaPickerDelegate) {
- mediaPicker.showVoiceRecorder(delegate: delegate)
- }
- func showCameraViewController(delegate: MediaPickerDelegate) {
- mediaPicker.showCamera(delegate: delegate, allowCropping: false)
- }
- func showPhotoVideoLibrary(delegate: MediaPickerDelegate) {
- mediaPicker.showPhotoVideoLibrary(delegate: delegate)
- }
- func showMediaGallery(currentIndex: Int, mediaUrls urls: [URL]) {
- let betterPreviewController = PreviewController(currentIndex: currentIndex, urls: urls)
- let nav = UINavigationController(rootViewController: betterPreviewController)
- nav.modalPresentationStyle = .fullScreen
- navigationController.present(nav, animated: true)
- }
- }
- class NewGroupAddMembersCoordinator: Coordinator {
- var dcContext: DcContext
- let navigationController: UINavigationController
- private var childCoordinators: [Coordinator] = []
- init(dcContext: DcContext, navigationController: UINavigationController) {
- self.dcContext = dcContext
- self.navigationController = navigationController
- }
- }
- class AddGroupMembersCoordinator: Coordinator {
- var dcContext: DcContext
- let navigationController: UINavigationController
- private var childCoordinators: [Coordinator] = []
- init(dcContext: DcContext, navigationController: UINavigationController) {
- self.dcContext = dcContext
- self.navigationController = navigationController
- }
- func showNewContactController() {
- let newContactController = NewContactController(dcContext: dcContext)
- newContactController.openChatOnSave = false
- let coordinator = EditContactCoordinator(dcContext: dcContext, navigationController: navigationController)
- childCoordinators.append(coordinator)
- newContactController.coordinator = coordinator
- navigationController.pushViewController(newContactController, animated: true)
- }
- }
- class NewGroupCoordinator: Coordinator {
- var dcContext: DcContext
- let navigationController: UINavigationController
- let mediaPicker: MediaPicker
- private var childCoordinators: [Coordinator] = []
- init(dcContext: DcContext, navigationController: UINavigationController) {
- self.dcContext = dcContext
- self.navigationController = navigationController
- self.mediaPicker = MediaPicker(navigationController: self.navigationController)
- }
- func showGroupChat(chatId: Int) {
- let chatViewController = ChatViewController(dcContext: dcContext, chatId: chatId)
- let coordinator = ChatViewCoordinator(dcContext: dcContext, navigationController: navigationController, chatId: chatId)
- childCoordinators.append(coordinator)
- chatViewController.coordinator = coordinator
- navigationController.popToRootViewController(animated: false)
- navigationController.pushViewController(chatViewController, animated: true)
- }
- func showPhotoPicker(delegate: MediaPickerDelegate) {
- mediaPicker.showPhotoGallery(delegate: delegate)
- }
- func showCamera(delegate: MediaPickerDelegate) {
- mediaPicker.showCamera(delegate: delegate)
- }
- func showQrCodeInvite(chatId: Int) {
- let qrInviteCodeController = QrInviteViewController(dcContext: dcContext, chatId: chatId)
- qrInviteCodeController.onDismissed = onQRInviteCodeControllerDismissed
- navigationController.pushViewController(qrInviteCodeController, animated: true)
- }
- func showAddMembers(preselectedMembers: Set<Int>, isVerified: Bool) {
- let newGroupController = NewGroupAddMembersViewController(preselected: preselectedMembers,
- isVerified: isVerified)
- let coordinator = NewGroupAddMembersCoordinator(dcContext: dcContext, navigationController: navigationController)
- childCoordinators.append(coordinator)
- newGroupController.coordinator = coordinator
- newGroupController.onMembersSelected = onGroupMembersSelected(_:)
- navigationController.pushViewController(newGroupController, animated: true)
- }
- func onQRInviteCodeControllerDismissed() {
- if let groupNameController = navigationController.topViewController as? NewGroupController {
- groupNameController.updateGroupContactIdsOnQRCodeInvite()
- }
- }
- func onGroupMembersSelected(_ memberIds: Set<Int>) {
- navigationController.popViewController(animated: true)
- if let groupNameController = navigationController.topViewController as? NewGroupController {
- groupNameController.updateGroupContactIdsOnListSelection(memberIds)
- }
- }
- }
- class ContactDetailCoordinator: Coordinator, ContactDetailCoordinatorProtocol {
- var dcContext: DcContext
- let navigationController: UINavigationController
- var previewController: PreviewController?
- let chatId: Int?
- private var childCoordinators: [Coordinator] = []
- init(dcContext: DcContext, chatId: Int?, navigationController: UINavigationController) {
- self.chatId = chatId
- self.dcContext = dcContext
- self.navigationController = navigationController
- }
- func showChat(chatId: Int) {
- let chatViewController = ChatViewController(dcContext: dcContext, chatId: chatId)
- let coordinator = ChatViewCoordinator(dcContext: dcContext, navigationController: navigationController, chatId: chatId)
- childCoordinators.append(coordinator)
- chatViewController.coordinator = coordinator
- navigationController.popToRootViewController(animated: false)
- navigationController.pushViewController(chatViewController, animated: true)
- }
- func showEditContact(contactId: Int) {
- let editContactController = EditContactController(dcContext: dcContext, contactIdForUpdate: contactId)
- let coordinator = EditContactCoordinator(dcContext: dcContext, navigationController: navigationController)
- childCoordinators.append(coordinator)
- editContactController.coordinator = coordinator
- navigationController.pushViewController(editContactController, animated: true)
- }
- func showDocuments() {
- presentPreview(for: DC_MSG_FILE, messageType2: DC_MSG_AUDIO, messageType3: 0)
- }
- func showGallery() {
- presentPreview(for: DC_MSG_IMAGE, messageType2: DC_MSG_GIF, messageType3: DC_MSG_VIDEO)
- }
- private func presentPreview(for messageType: Int32, messageType2: Int32, messageType3: Int32) {
- guard let chatId = self.chatId else { return }
- let messageIds = dcContext.getChatMedia(chatId: chatId, messageType: messageType, messageType2: messageType2, messageType3: messageType3)
- var mediaUrls: [URL] = []
- for messageId in messageIds {
- let message = DcMsg.init(id: messageId)
- if let url = message.fileURL {
- mediaUrls.insert(url, at: 0)
- }
- }
- previewController = PreviewController(currentIndex: 0, urls: mediaUrls)
- if let previewController = previewController {
- navigationController.pushViewController(previewController, animated: true)
- }
- }
- func deleteChat() {
- guard let chatId = chatId else {
- return
- }
- /*
- app will navigate to chatlist or archive and delete the chat there
- notify chatList/archiveList to delete chat AFTER is is visible
- */
- func notifyToDeleteChat() {
- NotificationCenter.default.post(name: dcNotificationChatDeletedInChatDetail, object: nil, userInfo: ["chat_id": chatId])
- }
- func showArchive() {
- self.navigationController.popToRootViewController(animated: false) // in main ChatList now
- let viewModel = ChatListViewModel(dcContext: dcContext, isArchive: true)
- let controller = ChatListController(dcContext: dcContext, viewModel: viewModel)
- let coordinator = ChatListCoordinator(dcContext: dcContext, navigationController: navigationController)
- childCoordinators.append(coordinator)
- controller.coordinator = coordinator
- navigationController.pushViewController(controller, animated: false)
- }
- CATransaction.begin()
- CATransaction.setCompletionBlock(notifyToDeleteChat)
- let chat = dcContext.getChat(chatId: chatId)
- if chat.isArchived {
- showArchive()
- } else {
- self.navigationController.popToRootViewController(animated: true) // in main ChatList now
- }
- CATransaction.commit()
- }
- }
- class EditGroupCoordinator: Coordinator {
- let navigationController: UINavigationController
- let dcContext: DcContext
- let mediaPicker: MediaPicker
- init(dcContext: DcContext, navigationController: UINavigationController) {
- self.dcContext = dcContext
- self.navigationController = navigationController
- mediaPicker = MediaPicker(navigationController: self.navigationController)
- }
- func showPhotoPicker(delegate: MediaPickerDelegate) {
- mediaPicker.showPhotoGallery(delegate: delegate)
- }
- func showCamera(delegate: MediaPickerDelegate) {
- mediaPicker.showCamera(delegate: delegate)
- }
- func navigateBack() {
- navigationController.popViewController(animated: true)
- }
- }
- class EditContactCoordinator: Coordinator, EditContactCoordinatorProtocol {
- var dcContext: DcContext
- let navigationController: UINavigationController
- var childCoordinators: [Coordinator] = []
- init(dcContext: DcContext, navigationController: UINavigationController) {
- self.dcContext = dcContext
- self.navigationController = navigationController
- }
- func navigateBack() {
- navigationController.popViewController(animated: true)
- }
- func showChat(chatId: Int) {
- let chatViewController = ChatViewController(dcContext: dcContext, chatId: chatId)
- let coordinator = ChatViewCoordinator(dcContext: dcContext, navigationController: navigationController, chatId: chatId)
- coordinator.chatViewController = chatViewController
- childCoordinators.append(coordinator)
- chatViewController.coordinator = coordinator
- navigationController.popToRootViewController(animated: false)
- navigationController.pushViewController(chatViewController, animated: true)
- }
- }
- /*
- boilerplate - I tend to remove that interface (cyberta)
- */
- protocol ContactDetailCoordinatorProtocol: class {
- func showEditContact(contactId: Int)
- func showChat(chatId: Int)
- func deleteChat()
- func showDocuments()
- func showGallery()
- }
- protocol EditContactCoordinatorProtocol: class {
- func navigateBack()
- func showChat(chatId: Int)
- }
- protocol WelcomeCoordinator: class {
- func showLogin()
- func handleLoginSuccess()
- func handleQRAccountCreationSuccess()
- }
|