mirror of
https://github.com/signalapp/Signal-iOS.git
synced 2025-12-05 01:10:41 +00:00
Modernize "Group Link Promotion" screen.
This commit is contained in:
committed by
GitHub
parent
cc8d170a70
commit
04c7db77f9
@@ -348,7 +348,6 @@
|
||||
348EE28E25B897BF00814FC2 /* CVMediaCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 348EE28C25B897BF00814FC2 /* CVMediaCache.swift */; };
|
||||
348EE28F25B897BF00814FC2 /* ReusableMediaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 348EE28D25B897BF00814FC2 /* ReusableMediaView.swift */; };
|
||||
3490D57D25ADDC2A00F5F96C /* GroupLinkPromotionActionSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3490D57C25ADDC2900F5F96C /* GroupLinkPromotionActionSheet.swift */; };
|
||||
3490D57F25ADE49800F5F96C /* ActionSheetContentBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3490D57E25ADE49800F5F96C /* ActionSheetContentBuilder.swift */; };
|
||||
3491899B269CD68E008A18AF /* BlockingAnnouncementOnlyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3491899A269CD68D008A18AF /* BlockingAnnouncementOnlyView.swift */; };
|
||||
349439D624360C30001045F7 /* AddGroupMembersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349439D524360C30001045F7 /* AddGroupMembersViewController.swift */; };
|
||||
349439D824360D63001045F7 /* BaseGroupMemberViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349439D724360D63001045F7 /* BaseGroupMemberViewController.swift */; };
|
||||
@@ -4144,7 +4143,6 @@
|
||||
348EE28D25B897BF00814FC2 /* ReusableMediaView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReusableMediaView.swift; sourceTree = "<group>"; };
|
||||
348F2EAD1F0D21BC00D4ECE0 /* DeviceSleepManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceSleepManager.swift; sourceTree = "<group>"; };
|
||||
3490D57C25ADDC2900F5F96C /* GroupLinkPromotionActionSheet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GroupLinkPromotionActionSheet.swift; sourceTree = "<group>"; };
|
||||
3490D57E25ADE49800F5F96C /* ActionSheetContentBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetContentBuilder.swift; sourceTree = "<group>"; };
|
||||
3491899A269CD68D008A18AF /* BlockingAnnouncementOnlyView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlockingAnnouncementOnlyView.swift; sourceTree = "<group>"; };
|
||||
349439D524360C30001045F7 /* AddGroupMembersViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddGroupMembersViewController.swift; sourceTree = "<group>"; };
|
||||
349439D724360D63001045F7 /* BaseGroupMemberViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseGroupMemberViewController.swift; sourceTree = "<group>"; };
|
||||
@@ -8718,7 +8716,6 @@
|
||||
349767DE25B8744600ECE1B0 /* Stickers */,
|
||||
340FC897204DAC8D007AEB0F /* ThreadSettings */,
|
||||
88A51B9825BA079500CDB45C /* Wallpapers */,
|
||||
3490D57E25ADE49800F5F96C /* ActionSheetContentBuilder.swift */,
|
||||
4C46361022EB98EC00185951 /* CameraFirstCaptureSendFlow.swift */,
|
||||
348BB25C20A0C5530047AEC2 /* ContactShareViewHelper.swift */,
|
||||
34E88D252098C5AE00A608F4 /* ContactViewController.swift */,
|
||||
@@ -16750,7 +16747,6 @@
|
||||
files = (
|
||||
D91174562E8F35C1009EB756 /* AccountEntropyPoolTextView.swift in Sources */,
|
||||
88E728FF25F0241100A2E4A4 /* AccountSettingsViewController.swift in Sources */,
|
||||
3490D57F25ADE49800F5F96C /* ActionSheetContentBuilder.swift in Sources */,
|
||||
349439D624360C30001045F7 /* AddGroupMembersViewController.swift in Sources */,
|
||||
8835DE03230DEC6A00DC6B66 /* AddToBlockListViewController.swift in Sources */,
|
||||
882BDAAE249050F000C14587 /* AddToGroupViewController.swift in Sources */,
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SignalUI
|
||||
import UIKit
|
||||
|
||||
public class ActionSheetContentBuilder {
|
||||
|
||||
var subviews = [UIView]()
|
||||
|
||||
func buildLabel(text: String? = nil,
|
||||
textColor: UIColor? = nil,
|
||||
font: UIFont? = nil,
|
||||
textAlignment: NSTextAlignment = .natural) -> UILabel {
|
||||
let label = UILabel()
|
||||
label.text = text
|
||||
label.textColor = textColor ?? Theme.primaryTextColor
|
||||
label.font = font ?? UIFont.dynamicTypeBody
|
||||
label.numberOfLines = 0
|
||||
label.lineBreakMode = .byWordWrapping
|
||||
label.textAlignment = textAlignment
|
||||
return label
|
||||
}
|
||||
|
||||
func buildTitleLabel(text: String) -> UILabel {
|
||||
buildLabel(text: text,
|
||||
font: UIFont.dynamicTypeTitle2.semibold(),
|
||||
textAlignment: .center)
|
||||
}
|
||||
|
||||
func add(_ subview: UIView) {
|
||||
subviews.append(subview)
|
||||
}
|
||||
|
||||
func addVerticalSpacer(height: CGFloat) {
|
||||
add(UIView.spacer(withHeight: height))
|
||||
}
|
||||
|
||||
func addBottomButton(
|
||||
title: String,
|
||||
titleColor: UIColor,
|
||||
backgroundColor: UIColor,
|
||||
target: Any,
|
||||
selector: Selector
|
||||
) {
|
||||
let buttonFont = UIFont.dynamicTypeHeadlineClamped
|
||||
let buttonHeight = OWSFlatButton.heightForFont(buttonFont)
|
||||
let upgradeButton = OWSFlatButton.button(title: title,
|
||||
font: buttonFont,
|
||||
titleColor: titleColor,
|
||||
backgroundColor: backgroundColor,
|
||||
target: target,
|
||||
selector: selector)
|
||||
upgradeButton.autoSetDimension(.height, toSize: buttonHeight)
|
||||
subviews.append(upgradeButton)
|
||||
}
|
||||
}
|
||||
@@ -14,16 +14,141 @@ public class GroupLinkPromotionActionSheet: UIView {
|
||||
|
||||
weak var actionSheetController: ActionSheetController?
|
||||
|
||||
private let stackView = UIStackView()
|
||||
|
||||
init(groupThread: TSGroupThread,
|
||||
conversationViewController: ConversationViewController) {
|
||||
init(groupThread: TSGroupThread, conversationViewController: ConversationViewController) {
|
||||
self.groupThread = groupThread
|
||||
self.conversationViewController = conversationViewController
|
||||
|
||||
super.init(frame: .zero)
|
||||
|
||||
configure()
|
||||
let titleLabel = UILabel()
|
||||
titleLabel.text = OWSLocalizedString("GROUP_LINK_PROMOTION_ALERT_TITLE",
|
||||
comment: "Title for the 'group link promotion' alert view.")
|
||||
titleLabel.textColor = .Signal.label
|
||||
titleLabel.font = .dynamicTypeHeadline
|
||||
titleLabel.textAlignment = .natural
|
||||
|
||||
let subtitleLabel = UILabel()
|
||||
subtitleLabel.text = OWSLocalizedString("GROUP_LINK_PROMOTION_ALERT_SUBTITLE",
|
||||
comment: "Subtitle for the 'group link promotion' alert view.")
|
||||
subtitleLabel.textColor = .Signal.label
|
||||
subtitleLabel.font = .dynamicTypeBody
|
||||
subtitleLabel.textAlignment = .natural
|
||||
subtitleLabel.numberOfLines = 0
|
||||
subtitleLabel.lineBreakMode = .byWordWrapping
|
||||
|
||||
let topStack = UIStackView(arrangedSubviews: [ titleLabel, subtitleLabel ])
|
||||
topStack.axis = .vertical
|
||||
topStack.spacing = 4
|
||||
topStack.isLayoutMarginsRelativeArrangement = true
|
||||
topStack.directionalLayoutMargins = .init(top: 14, leading: 14, bottom: 20, trailing: 14)
|
||||
topStack.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(topStack)
|
||||
addConstraints([
|
||||
topStack.topAnchor.constraint(equalTo: topAnchor),
|
||||
topStack.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
topStack.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
])
|
||||
|
||||
let buttonStackTopAnchor: NSLayoutYAxisAnchor
|
||||
if isGroupLinkEnabled {
|
||||
buttonStackTopAnchor = topStack.bottomAnchor
|
||||
} else {
|
||||
let switchLabel = UILabel()
|
||||
switchLabel.text = OWSLocalizedString(
|
||||
"GROUP_LINK_PROMOTION_ALERT_APPROVE_NEW_MEMBERS_SWITCH",
|
||||
comment: "Label for the 'approve new group members' switch."
|
||||
)
|
||||
switchLabel.setCompressionResistanceHorizontalHigh()
|
||||
|
||||
memberApprovalSwitch.setCompressionResistanceHorizontalHigh()
|
||||
|
||||
let memberApprovalStack = UIStackView(arrangedSubviews: [
|
||||
switchLabel,
|
||||
.hStretchingSpacer(),
|
||||
memberApprovalSwitch,
|
||||
])
|
||||
memberApprovalStack.axis = .horizontal
|
||||
memberApprovalStack.alignment = .center
|
||||
memberApprovalStack.distribution = .fill
|
||||
memberApprovalStack.layoutMargins = UIEdgeInsets(hMargin: 16, vMargin: 10)
|
||||
memberApprovalStack.isLayoutMarginsRelativeArrangement = true
|
||||
memberApprovalStack.addBackgroundView(
|
||||
withBackgroundColor: .Signal.secondaryGroupedBackground,
|
||||
cornerRadius: OWSTableViewController2.cellRounding
|
||||
)
|
||||
|
||||
let captionLabel = UILabel()
|
||||
captionLabel.text = OWSLocalizedString("GROUP_LINK_PROMOTION_ALERT_APPROVE_NEW_MEMBERS_EXPLANATION",
|
||||
comment: "Explanation of the 'approve new group members' switch.")
|
||||
captionLabel.textColor = .Signal.secondaryLabel
|
||||
captionLabel.font = .dynamicTypeFootnote
|
||||
captionLabel.numberOfLines = 0
|
||||
captionLabel.lineBreakMode = .byWordWrapping
|
||||
captionLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
let captionContainer = UIView()
|
||||
captionContainer.directionalLayoutMargins = .init(top: 12, leading: 16, bottom: 12, trailing: 16)
|
||||
captionContainer.addSubview(captionLabel)
|
||||
captionContainer.addConstraints([
|
||||
captionLabel.topAnchor.constraint(equalTo: captionContainer.layoutMarginsGuide.topAnchor),
|
||||
captionLabel.leadingAnchor.constraint(equalTo: captionContainer.layoutMarginsGuide.leadingAnchor),
|
||||
captionLabel.trailingAnchor.constraint(equalTo: captionContainer.layoutMarginsGuide.trailingAnchor),
|
||||
captionLabel.bottomAnchor.constraint(equalTo: captionContainer.layoutMarginsGuide.bottomAnchor),
|
||||
])
|
||||
|
||||
let middleStack = UIStackView(arrangedSubviews: [memberApprovalStack, captionContainer])
|
||||
middleStack.axis = .vertical
|
||||
middleStack.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(middleStack)
|
||||
addConstraints([
|
||||
middleStack.topAnchor.constraint(equalTo: topStack.bottomAnchor),
|
||||
middleStack.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
middleStack.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
])
|
||||
|
||||
buttonStackTopAnchor = middleStack.bottomAnchor
|
||||
}
|
||||
|
||||
// Two buttons at the bottom
|
||||
let topButton: UIButton
|
||||
if isGroupLinkEnabled {
|
||||
topButton = UIButton(
|
||||
configuration: .largePrimary(title: OWSLocalizedString(
|
||||
"GROUP_LINK_PROMOTION_ALERT_SHARE_LINK",
|
||||
comment: "Label for the 'share link' button in the 'group link promotion' alert view."
|
||||
)),
|
||||
primaryAction: UIAction { [weak self] _ in
|
||||
self?.dismissAndShareLink()
|
||||
}
|
||||
)
|
||||
} else {
|
||||
topButton = UIButton(
|
||||
configuration: .largePrimary(title: OWSLocalizedString(
|
||||
"GROUP_LINK_PROMOTION_ALERT_ENABLE_AND_SHARE_LINK",
|
||||
comment: "Label for the 'enable and share link' button in the 'group link promotion' alert view."
|
||||
)),
|
||||
primaryAction: UIAction { [weak self] _ in
|
||||
self?.enableAndShareLink()
|
||||
}
|
||||
)
|
||||
}
|
||||
let cancelButton = UIButton(
|
||||
configuration: .largeSecondary(title: CommonStrings.cancelButton),
|
||||
primaryAction: UIAction { [weak self] _ in
|
||||
self?.dismissAlert()
|
||||
}
|
||||
)
|
||||
|
||||
let buttonStack = UIStackView.verticalButtonStack(buttons: [ topButton, cancelButton], isFullWidthButtons: true)
|
||||
buttonStack.directionalLayoutMargins = .zero
|
||||
buttonStack.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(buttonStack)
|
||||
addConstraints([
|
||||
buttonStack.topAnchor.constraint(equalTo: buttonStackTopAnchor, constant: 12),
|
||||
buttonStack.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
buttonStack.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
buttonStack.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
])
|
||||
}
|
||||
|
||||
required init(coder: NSCoder) {
|
||||
@@ -38,21 +163,6 @@ public class GroupLinkPromotionActionSheet: UIView {
|
||||
self.actionSheetController = actionSheetController
|
||||
}
|
||||
|
||||
public func configure() {
|
||||
let subviews = buildContents()
|
||||
|
||||
let stackView = UIStackView(arrangedSubviews: subviews)
|
||||
stackView.axis = .vertical
|
||||
stackView.alignment = .fill
|
||||
stackView.layoutMargins = UIEdgeInsets(top: 24, leading: 24, bottom: 8, trailing: 24)
|
||||
stackView.isLayoutMarginsRelativeArrangement = true
|
||||
|
||||
layoutMargins = .zero
|
||||
addSubview(stackView)
|
||||
stackView.autoPinEdgesToSuperviewMargins()
|
||||
stackView.setContentHuggingHorizontalLow()
|
||||
}
|
||||
|
||||
private var isGroupLinkEnabled: Bool {
|
||||
guard let groupModel = groupThread.groupModel as? TSGroupModelV2 else {
|
||||
owsFailDebug("Invalid groupModel.")
|
||||
@@ -68,101 +178,13 @@ public class GroupLinkPromotionActionSheet: UIView {
|
||||
|
||||
private let memberApprovalSwitch = UISwitch()
|
||||
|
||||
private func buildContents() -> [UIView] {
|
||||
let builder = ActionSheetContentBuilder()
|
||||
|
||||
builder.add(builder.buildTitleLabel(text: OWSLocalizedString("GROUP_LINK_PROMOTION_ALERT_TITLE",
|
||||
comment: "Title for the 'group link promotion' alert view.")))
|
||||
|
||||
builder.addVerticalSpacer(height: 2)
|
||||
|
||||
builder.add(builder.buildLabel(text: OWSLocalizedString("GROUP_LINK_PROMOTION_ALERT_SUBTITLE",
|
||||
comment: "Subtitle for the 'group link promotion' alert view."),
|
||||
textAlignment: .center))
|
||||
|
||||
let isGroupLinkEnabled = self.isGroupLinkEnabled
|
||||
|
||||
if isGroupLinkEnabled {
|
||||
builder.addVerticalSpacer(height: 88)
|
||||
|
||||
builder.addBottomButton(title: OWSLocalizedString("GROUP_LINK_PROMOTION_ALERT_SHARE_LINK",
|
||||
comment: "Label for the 'share link' button in the 'group link promotion' alert view."),
|
||||
titleColor: .white,
|
||||
backgroundColor: .ows_accentBlue,
|
||||
target: self,
|
||||
selector: #selector(dismissAndShareLink))
|
||||
} else {
|
||||
builder.addVerticalSpacer(height: 32)
|
||||
|
||||
let memberApprovalStack = UIStackView()
|
||||
memberApprovalStack.axis = .horizontal
|
||||
memberApprovalStack.alignment = .center
|
||||
memberApprovalStack.distribution = .fill
|
||||
memberApprovalStack.layoutMargins = UIEdgeInsets(hMargin: 16, vMargin: 10)
|
||||
memberApprovalStack.isLayoutMarginsRelativeArrangement = true
|
||||
|
||||
memberApprovalStack.addBackgroundView(withBackgroundColor: Theme.isDarkThemeEnabled ? .ows_gray65 : .ows_gray02, cornerRadius: 8)
|
||||
|
||||
let switchLabel = builder.buildLabel(text: OWSLocalizedString("GROUP_LINK_PROMOTION_ALERT_APPROVE_NEW_MEMBERS_SWITCH",
|
||||
comment: "Label for the 'approve new group members' switch."))
|
||||
memberApprovalStack.addArrangedSubview(switchLabel)
|
||||
switchLabel.setCompressionResistanceHorizontalHigh()
|
||||
|
||||
memberApprovalStack.addArrangedSubview(UIView.hStretchingSpacer())
|
||||
|
||||
memberApprovalStack.addArrangedSubview(memberApprovalSwitch)
|
||||
memberApprovalSwitch.setCompressionResistanceHorizontalHigh()
|
||||
|
||||
builder.add(memberApprovalStack)
|
||||
|
||||
builder.addVerticalSpacer(height: 8)
|
||||
|
||||
let captionLabel = builder.buildLabel(text: OWSLocalizedString("GROUP_LINK_PROMOTION_ALERT_APPROVE_NEW_MEMBERS_EXPLANATION",
|
||||
comment: "Explanation of the 'approve new group members' switch."),
|
||||
textColor: Theme.secondaryTextAndIconColor,
|
||||
font: .dynamicTypeCaption1)
|
||||
|
||||
let captionContainer = UIView()
|
||||
captionContainer.layoutMargins = UIEdgeInsets(hMargin: 8, vMargin: 0)
|
||||
captionContainer.addSubview(captionLabel)
|
||||
captionLabel.autoPinEdgesToSuperviewMargins()
|
||||
|
||||
builder.add(captionContainer)
|
||||
|
||||
builder.addVerticalSpacer(height: 44)
|
||||
|
||||
builder.addBottomButton(title: OWSLocalizedString("GROUP_LINK_PROMOTION_ALERT_ENABLE_AND_SHARE_LINK",
|
||||
comment: "Label for the 'enable and share link' button in the 'group link promotion' alert view."),
|
||||
titleColor: .white,
|
||||
backgroundColor: .ows_accentBlue,
|
||||
target: self,
|
||||
selector: #selector(enableAndShareLink))
|
||||
}
|
||||
|
||||
builder.addVerticalSpacer(height: 5)
|
||||
builder.addBottomButton(title: CommonStrings.cancelButton,
|
||||
titleColor: Theme.secondaryTextAndIconColor,
|
||||
backgroundColor: .clear,
|
||||
target: self,
|
||||
selector: #selector(dismissAlert))
|
||||
|
||||
return builder.subviews
|
||||
}
|
||||
|
||||
// MARK: - Events
|
||||
|
||||
@objc
|
||||
private func dismissAlert() {
|
||||
actionSheetController?.dismiss(animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
private extension GroupLinkPromotionActionSheet {
|
||||
|
||||
@objc
|
||||
func enableAndShareLink() {
|
||||
private func enableAndShareLink() {
|
||||
guard let actionSheetController = actionSheetController else {
|
||||
owsFailDebug("Missing actionSheetController.")
|
||||
return
|
||||
@@ -192,8 +214,7 @@ private extension GroupLinkPromotionActionSheet {
|
||||
)
|
||||
}
|
||||
|
||||
@objc
|
||||
func dismissAndShareLink() {
|
||||
private func dismissAndShareLink() {
|
||||
guard let groupModelV2 = groupThread.groupModel as? TSGroupModelV2 else {
|
||||
owsFailDebug("Invalid groupModel.")
|
||||
return
|
||||
|
||||
@@ -170,9 +170,8 @@ open class ActionSheetController: OWSViewController {
|
||||
/// strange when there's only slightly more space on the sides than below.
|
||||
let maxWidthWiggleRoom: CGFloat = 40
|
||||
|
||||
override public func loadView() {
|
||||
view = UIView()
|
||||
view.backgroundColor = .clear
|
||||
override open func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
// Depending on the number of actions, the sheet may need
|
||||
// to scroll to allow access to all options.
|
||||
|
||||
Reference in New Issue
Block a user