257 lines
11 KiB
Swift
257 lines
11 KiB
Swift
//
|
|
// Copyright (c) 2020 Open Whisper Systems. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
import PromiseKit
|
|
|
|
class LegacyGroupView: UIView {
|
|
|
|
private let groupThread: TSGroupThread
|
|
private let migrationInfo: GroupsV2MigrationInfo
|
|
private weak var viewController: UIViewController?
|
|
|
|
required init(groupThread: TSGroupThread,
|
|
migrationInfo: GroupsV2MigrationInfo,
|
|
viewController: UIViewController) {
|
|
self.groupThread = groupThread
|
|
self.migrationInfo = migrationInfo
|
|
self.viewController = viewController
|
|
|
|
super.init(frame: .zero)
|
|
}
|
|
|
|
@available(*, unavailable, message: "use other init() instead.")
|
|
required public init(coder aDecoder: NSCoder) {
|
|
notImplemented()
|
|
}
|
|
|
|
private let label = UILabel()
|
|
|
|
func configureLabel(format: String, highlightedSubstring: String) {
|
|
let text = String(format: format, highlightedSubstring)
|
|
let attributedString = NSMutableAttributedString(string: text)
|
|
attributedString.setAttributes([
|
|
.foregroundColor: Theme.accentBlueColor
|
|
],
|
|
forSubstring: highlightedSubstring)
|
|
label.attributedText = attributedString
|
|
}
|
|
|
|
func configureDefaultLabelContents() {
|
|
let format = NSLocalizedString("GROUPS_LEGACY_GROUP_DESCRIPTION_FORMAT",
|
|
comment: "Brief explanation of legacy groups. Embeds {{ a \"learn more\" link. }}.")
|
|
let learnMoreText = CommonStrings.learnMore
|
|
configureLabel(format: format, highlightedSubstring: learnMoreText)
|
|
|
|
isUserInteractionEnabled = true
|
|
addGestureRecognizer(UITapGestureRecognizer(target: self,
|
|
action: #selector(didTapLearnMore)))
|
|
}
|
|
|
|
func configureCantUpgradeDueToMembersContents() {
|
|
let format = NSLocalizedString("GROUPS_LEGACY_GROUP_DESCRIPTION_MEMBERS_CANT_BE_MIGRATED_FORMAT",
|
|
comment: "Indicates that a legacy group can't be upgraded because some members can't be migrated. Embeds {{ an \"learn more\" link. }}.")
|
|
let learnMoreText = CommonStrings.learnMore
|
|
configureLabel(format: format, highlightedSubstring: learnMoreText)
|
|
|
|
isUserInteractionEnabled = true
|
|
addGestureRecognizer(UITapGestureRecognizer(target: self,
|
|
action: #selector(didTapCantUpgradeDueToMemberState)))
|
|
}
|
|
|
|
public func configure() {
|
|
backgroundColor = Theme.secondaryBackgroundColor
|
|
layer.cornerRadius = 4
|
|
layoutMargins = UIEdgeInsets(top: 10, leading: 12, bottom: 10, trailing: 12)
|
|
|
|
label.textColor = Theme.secondaryTextAndIconColor
|
|
label.font = .ows_dynamicTypeFootnote
|
|
label.numberOfLines = 0
|
|
label.lineBreakMode = .byWordWrapping
|
|
addSubview(label)
|
|
label.autoPinEdgesToSuperviewMargins()
|
|
|
|
switch migrationInfo.state {
|
|
case .canBeMigrated:
|
|
let format = NSLocalizedString("GROUPS_LEGACY_GROUP_DESCRIPTION_WITH_UPGRADE_OFFER_FORMAT",
|
|
comment: "Explanation of legacy groups. Embeds {{ an \"upgrade\" link. }}.")
|
|
let upgradeText = NSLocalizedString("GROUPS_LEGACY_GROUP_UPGRADE_LINK",
|
|
comment: "An \"upgrade\" link for upgrading legacy groups to new groups.")
|
|
configureLabel(format: format, highlightedSubstring: upgradeText)
|
|
|
|
isUserInteractionEnabled = true
|
|
addGestureRecognizer(UITapGestureRecognizer(target: self,
|
|
action: #selector(didTapUpgrade)))
|
|
case .cantBeMigrated_FeatureNotEnabled:
|
|
configureDefaultLabelContents()
|
|
case .cantBeMigrated_NotAV1Group:
|
|
owsFailDebug("Unexpected group.")
|
|
configureDefaultLabelContents()
|
|
case .cantBeMigrated_NotRegistered:
|
|
owsFailDebug("Not registered.")
|
|
configureDefaultLabelContents()
|
|
case .cantBeMigrated_LocalUserIsNotAMember:
|
|
Logger.verbose("Local user is not a member.")
|
|
configureDefaultLabelContents()
|
|
case .cantBeMigrated_NotInProfileWhitelist:
|
|
Logger.verbose("Local user has not accepted message request.")
|
|
configureDefaultLabelContents()
|
|
case .cantBeMigrated_TooManyMembers:
|
|
let format = NSLocalizedString("GROUPS_LEGACY_GROUP_DESCRIPTION_TOO_MANY_MEMBERS_FORMAT",
|
|
comment: "Indicates that a legacy group can't be upgraded because it has too many members. Embeds {{ an \"learn more\" link. }}.")
|
|
let learnMoreText = CommonStrings.learnMore
|
|
configureLabel(format: format, highlightedSubstring: learnMoreText)
|
|
|
|
isUserInteractionEnabled = true
|
|
addGestureRecognizer(UITapGestureRecognizer(target: self,
|
|
action: #selector(didTapTooManyMembers)))
|
|
case .cantBeMigrated_MembersWithoutUuids,
|
|
.cantBeMigrated_MembersWithoutCapabilities:
|
|
configureCantUpgradeDueToMembersContents()
|
|
case .cantBeMigrated_MembersWithoutProfileKey:
|
|
owsFailDebug("Manual migrations should ignore missing profile keys.")
|
|
configureCantUpgradeDueToMembersContents()
|
|
}
|
|
}
|
|
|
|
// MARK: - Events
|
|
|
|
@objc
|
|
public func didTapLearnMore() {
|
|
guard let viewController = viewController else {
|
|
owsFailDebug("Missing viewController.")
|
|
return
|
|
}
|
|
LegacyGroupViewLearnMoreView().present(fromViewController: viewController)
|
|
}
|
|
|
|
@objc
|
|
public func didTapUpgrade() {
|
|
showMigrationAlert(mode: .upgradeGroup(migrationInfo: migrationInfo))
|
|
}
|
|
|
|
@objc
|
|
public func didTapTooManyMembers() {
|
|
showMigrationAlert(mode: .tooManyMembers)
|
|
}
|
|
|
|
@objc
|
|
public func didTapCantUpgradeDueToMemberState() {
|
|
showMigrationAlert(mode: .someMembersCantMigrate)
|
|
}
|
|
|
|
private func showMigrationAlert(mode: GroupMigrationActionSheet.Mode) {
|
|
guard let viewController = viewController else {
|
|
owsFailDebug("Missing viewController.")
|
|
return
|
|
}
|
|
let view = GroupMigrationActionSheet(groupThread: groupThread, mode: mode)
|
|
view.present(fromViewController: viewController)
|
|
}
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
public class LegacyGroupViewLearnMoreView: UIView {
|
|
|
|
weak var actionSheetController: ActionSheetController?
|
|
|
|
init() {
|
|
super.init(frame: .zero)
|
|
}
|
|
|
|
required init(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
func present(fromViewController: UIViewController) {
|
|
let buildLabel = { () -> UILabel in
|
|
let label = UILabel()
|
|
label.textColor = Theme.primaryTextColor
|
|
label.numberOfLines = 0
|
|
label.lineBreakMode = .byWordWrapping
|
|
return label
|
|
}
|
|
|
|
let titleLabel = buildLabel()
|
|
titleLabel.font = UIFont.ows_dynamicTypeTitle2.ows_semibold
|
|
titleLabel.text = NSLocalizedString("GROUPS_LEGACY_GROUP_ALERT_TITLE",
|
|
comment: "Title for the 'legacy group' alert view.")
|
|
|
|
let section1TitleLabel = buildLabel()
|
|
section1TitleLabel.font = UIFont.ows_dynamicTypeBody.ows_semibold
|
|
section1TitleLabel.text = NSLocalizedString("GROUPS_LEGACY_GROUP_ALERT_SECTION_1_TITLE",
|
|
comment: "Title for the first section of the 'legacy group' alert view.")
|
|
|
|
let section1BodyLabel = buildLabel()
|
|
section1BodyLabel.font = .ows_dynamicTypeBody
|
|
section1BodyLabel.text = NSLocalizedString("GROUPS_LEGACY_GROUP_ALERT_SECTION_1_BODY",
|
|
comment: "Body text for the first section of the 'legacy group' alert view.")
|
|
|
|
let section2TitleLabel = buildLabel()
|
|
section2TitleLabel.font = UIFont.ows_dynamicTypeBody.ows_semibold
|
|
section2TitleLabel.text = NSLocalizedString("GROUPS_LEGACY_GROUP_ALERT_SECTION_2_TITLE",
|
|
comment: "Title for the second section of the 'legacy group' alert view.")
|
|
|
|
let section2BodyLabel = buildLabel()
|
|
section2BodyLabel.font = .ows_dynamicTypeBody
|
|
section2BodyLabel.text = NSLocalizedString("GROUPS_LEGACY_GROUP_ALERT_SECTION_2_BODY",
|
|
comment: "Body text for the second section of the 'legacy group' alert view.")
|
|
|
|
let section3BodyLabel = buildLabel()
|
|
section3BodyLabel.font = .ows_dynamicTypeBody
|
|
section3BodyLabel.text = NSLocalizedString("GROUPS_LEGACY_GROUP_ALERT_SECTION_3_BODY",
|
|
comment: "Body text for the third section of the 'legacy group' alert view.")
|
|
|
|
let buttonFont = UIFont.ows_dynamicTypeBodyClamped.ows_semibold
|
|
let buttonHeight = OWSFlatButton.heightForFont(buttonFont)
|
|
let okayButton = OWSFlatButton.button(title: CommonStrings.okayButton,
|
|
font: buttonFont,
|
|
titleColor: .white,
|
|
backgroundColor: .ows_accentBlue,
|
|
target: self,
|
|
selector: #selector(dismissAlert))
|
|
okayButton.autoSetDimension(.height, toSize: buttonHeight)
|
|
|
|
let stackView = UIStackView(arrangedSubviews: [
|
|
titleLabel,
|
|
UIView.spacer(withHeight: 28),
|
|
section1TitleLabel,
|
|
UIView.spacer(withHeight: 4),
|
|
section1BodyLabel,
|
|
UIView.spacer(withHeight: 21),
|
|
section2TitleLabel,
|
|
UIView.spacer(withHeight: 4),
|
|
section2BodyLabel,
|
|
UIView.spacer(withHeight: 24),
|
|
section3BodyLabel,
|
|
UIView.spacer(withHeight: 28),
|
|
okayButton
|
|
])
|
|
stackView.axis = .vertical
|
|
stackView.alignment = .fill
|
|
stackView.layoutMargins = UIEdgeInsets(top: 48, leading: 20, bottom: 38, trailing: 24)
|
|
stackView.isLayoutMarginsRelativeArrangement = true
|
|
stackView.addBackgroundView(withBackgroundColor: Theme.backgroundColor)
|
|
|
|
layoutMargins = .zero
|
|
addSubview(stackView)
|
|
stackView.autoPinEdgesToSuperviewMargins()
|
|
|
|
let actionSheetController = ActionSheetController()
|
|
actionSheetController.customHeader = self
|
|
actionSheetController.isCancelable = true
|
|
fromViewController.presentActionSheet(actionSheetController)
|
|
self.actionSheetController = actionSheetController
|
|
}
|
|
|
|
// MARK: - Events
|
|
|
|
@objc
|
|
func dismissAlert() {
|
|
actionSheetController?.dismiss(animated: true)
|
|
}
|
|
}
|