// // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only // import Foundation import UIKit import SafariServices import SignalServiceKit public class GroupViewUtils { public static func formatGroupMembersLabel(memberCount: Int) -> String { let format = OWSLocalizedString("GROUP_MEMBER_COUNT_LABEL_%d", tableName: "PluralAware", comment: "The 'group member count' indicator when there are no members in the group.") return String.localizedStringWithFormat(format, memberCount) } public static func updateGroupWithActivityIndicator( fromViewController: UIViewController, withThread thread: TSThread, updateDescription: String, updateBlock: @escaping () -> Promise, completion: ((T?) -> Void)? ) { updateGroupWithActivityIndicator( fromViewController: fromViewController, withMessageProcessingPromise: GroupManager.messageProcessingPromise( for: thread, description: updateDescription ), updateBlock: updateBlock, completion: completion ) } public static func updateGroupWithActivityIndicator( fromViewController: UIViewController, withGroupModel groupModel: TSGroupModel, updateDescription: String, updateBlock: @escaping () -> Promise, completion: ((T?) -> Void)? ) { updateGroupWithActivityIndicator( fromViewController: fromViewController, withMessageProcessingPromise: GroupManager.messageProcessingPromise( for: groupModel, description: updateDescription ), updateBlock: updateBlock, completion: completion ) } private static func updateGroupWithActivityIndicator( fromViewController: UIViewController, withMessageProcessingPromise messageProcessingPromise: Promise, updateBlock: @escaping () -> Promise, completion: ((T?) -> Void)? ) { // GroupsV2 TODO: Should we allow cancel here? ModalActivityIndicatorViewController.present(fromViewController: fromViewController, canCancel: false) { modalActivityIndicator in messageProcessingPromise.then(on: DispatchQueue.global()) { updateBlock() }.done(on: DispatchQueue.main) { (value: T) in modalActivityIndicator.dismiss { completion?(value) } }.catch { error in switch error { case GroupsV2Error.redundantChange: // Treat GroupsV2Error.redundantChange as a success. modalActivityIndicator.dismiss { completion?(nil) } default: owsFailDebugUnlessNetworkFailure(error) modalActivityIndicator.dismiss { GroupViewUtils.showUpdateErrorUI(error: error) } } } } } public class func showUpdateErrorUI(error: Error) { AssertIsOnMainThread() owsFailDebug(error.localizedDescription) if error.isNetworkFailureOrTimeout { OWSActionSheets.showActionSheet(title: OWSLocalizedString("ERROR_NETWORK_FAILURE", comment: "Error indicating network connectivity problems."), message: OWSLocalizedString("UPDATE_GROUP_FAILED_DUE_TO_NETWORK", comment: "Error indicating that a group could not be updated due to network connectivity problems.")) } else { OWSActionSheets.showActionSheet(title: OWSLocalizedString("UPDATE_GROUP_FAILED", comment: "Error indicating that a group could not be updated.")) } } public static func showInvalidGroupMemberAlert(fromViewController: UIViewController) { let actionSheet = ActionSheetController(title: CommonStrings.errorAlertTitle, message: OWSLocalizedString("EDIT_GROUP_ERROR_CANNOT_ADD_MEMBER", comment: "Error message indicating the a user can't be added to a group.")) actionSheet.addAction(ActionSheetAction(title: CommonStrings.learnMore, style: .default) { _ in self.showCantAddMemberView(fromViewController: fromViewController) }) actionSheet.addAction(OWSActionSheets.okayAction) fromViewController.presentActionSheet(actionSheet) } private static func showCantAddMemberView(fromViewController: UIViewController) { guard let url = URL(string: "https://support.signal.org/hc/articles/360007319331") else { owsFailDebug("Invalid url.") return } let vc = SFSafariViewController(url: url) fromViewController.present(vc, animated: true, completion: nil) } }