require profiles names -> profile name reminder
This commit is contained in:
parent
ea2e5f9e8d
commit
93ca9ff632
@ -628,8 +628,7 @@
|
||||
8889007123DBB39B00F40186 /* reactionMegaphone_6.png in Resources */ = {isa = PBXBuildFile; fileRef = 8889006923DBB39B00F40186 /* reactionMegaphone_6.png */; };
|
||||
8889007223DBB39B00F40186 /* reactionMegaphone_4.png in Resources */ = {isa = PBXBuildFile; fileRef = 8889006A23DBB39B00F40186 /* reactionMegaphone_4.png */; };
|
||||
8889007323DBB39B00F40186 /* reactionMegaphone_5.png in Resources */ = {isa = PBXBuildFile; fileRef = 8889006B23DBB39B00F40186 /* reactionMegaphone_5.png */; };
|
||||
8889007523DBD0B400F40186 /* RequiredProfileNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8889007423DBD0B400F40186 /* RequiredProfileNames.swift */; };
|
||||
8889007723DBD61200F40186 /* requiredProfileNamesSplash.json in Resources */ = {isa = PBXBuildFile; fileRef = 8889007623DBD61200F40186 /* requiredProfileNamesSplash.json */; };
|
||||
8889007523DBD0B400F40186 /* ProfileNameReminder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8889007423DBD0B400F40186 /* ProfileNameReminder.swift */; };
|
||||
888C828223D795FA0059464B /* pinCreationFail.json in Resources */ = {isa = PBXBuildFile; fileRef = 888C827F23D795F90059464B /* pinCreationFail.json */; };
|
||||
888C828323D795FA0059464B /* pinCreationInProgress.json in Resources */ = {isa = PBXBuildFile; fileRef = 888C828023D795FA0059464B /* pinCreationInProgress.json */; };
|
||||
88905E9E229CCA96004E4234 /* ExpirationNagView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88905E9D229CCA96004E4234 /* ExpirationNagView.swift */; };
|
||||
@ -1506,8 +1505,7 @@
|
||||
8889006923DBB39B00F40186 /* reactionMegaphone_6.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = reactionMegaphone_6.png; sourceTree = "<group>"; };
|
||||
8889006A23DBB39B00F40186 /* reactionMegaphone_4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = reactionMegaphone_4.png; sourceTree = "<group>"; };
|
||||
8889006B23DBB39B00F40186 /* reactionMegaphone_5.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = reactionMegaphone_5.png; sourceTree = "<group>"; };
|
||||
8889007423DBD0B400F40186 /* RequiredProfileNames.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequiredProfileNames.swift; sourceTree = "<group>"; };
|
||||
8889007623DBD61200F40186 /* requiredProfileNamesSplash.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = requiredProfileNamesSplash.json; sourceTree = "<group>"; };
|
||||
8889007423DBD0B400F40186 /* ProfileNameReminder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileNameReminder.swift; sourceTree = "<group>"; };
|
||||
888C827F23D795F90059464B /* pinCreationFail.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = pinCreationFail.json; sourceTree = "<group>"; };
|
||||
888C828023D795FA0059464B /* pinCreationInProgress.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = pinCreationInProgress.json; sourceTree = "<group>"; };
|
||||
88905E9D229CCA96004E4234 /* ExpirationNagView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpirationNagView.swift; sourceTree = "<group>"; };
|
||||
@ -2953,7 +2951,7 @@
|
||||
children = (
|
||||
88A505F923DBA1360005C012 /* IntroducingPINs.swift */,
|
||||
88A505FB23DBAE4F0005C012 /* Reactions.swift */,
|
||||
8889007423DBD0B400F40186 /* RequiredProfileNames.swift */,
|
||||
8889007423DBD0B400F40186 /* ProfileNameReminder.swift */,
|
||||
);
|
||||
path = "Upgrade Views";
|
||||
sourceTree = "<group>";
|
||||
@ -2970,7 +2968,6 @@
|
||||
888C827F23D795F90059464B /* pinCreationFail.json */,
|
||||
888C828023D795FA0059464B /* pinCreationInProgress.json */,
|
||||
8837F73C23D8DE8400772A32 /* pinCreationSuccess.json */,
|
||||
8889007623DBD61200F40186 /* requiredProfileNamesSplash.json */,
|
||||
);
|
||||
path = Lottie;
|
||||
sourceTree = "<group>";
|
||||
@ -3632,7 +3629,6 @@
|
||||
45B74A7F2044AAB600CD42F8 /* note-quiet.aifc in Resources */,
|
||||
4C9D349B2369F11F006A4307 /* notificationPermission1.png in Resources */,
|
||||
45B74A842044AAB600CD42F8 /* popcorn.aifc in Resources */,
|
||||
8889007723DBD61200F40186 /* requiredProfileNamesSplash.json in Resources */,
|
||||
45B74A7D2044AAB600CD42F8 /* popcorn-quiet.aifc in Resources */,
|
||||
45B74A822044AAB600CD42F8 /* pulse.aifc in Resources */,
|
||||
4C9D349D2369F11F006A4307 /* notificationPermission2.png in Resources */,
|
||||
@ -4400,7 +4396,7 @@
|
||||
34EA69402194933900702471 /* MediaDownloadView.swift in Sources */,
|
||||
340FC8AB204DAC8D007AEB0F /* DomainFrontingCountryViewController.m in Sources */,
|
||||
4C586926224FAB83003FD070 /* AVAudioSession+OWS.m in Sources */,
|
||||
8889007523DBD0B400F40186 /* RequiredProfileNames.swift in Sources */,
|
||||
8889007523DBD0B400F40186 /* ProfileNameReminder.swift in Sources */,
|
||||
3496744D2076768700080B5F /* OWSMessageBubbleView.m in Sources */,
|
||||
34B3F8751E8DF1700035BE1A /* CallViewController.swift in Sources */,
|
||||
4C4AE6A1224AF35700D4AF6F /* SendMediaNavigationController.swift in Sources */,
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -57,8 +57,7 @@ class ExperienceUpgradeManager: NSObject {
|
||||
|
||||
private static func hasSplash(forExperienceUpgrade experienceUpgrade: ExperienceUpgrade) -> Bool {
|
||||
switch experienceUpgrade.id {
|
||||
case .introducingPins,
|
||||
.requiredProfileNames:
|
||||
case .introducingPins:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@ -70,9 +69,6 @@ class ExperienceUpgradeManager: NSObject {
|
||||
case .introducingPins:
|
||||
let vc = IntroducingPinsSplash(experienceUpgrade: experienceUpgrade)
|
||||
return OWSNavigationController(rootViewController: vc)
|
||||
case .requiredProfileNames:
|
||||
let vc = RequiredProfileNamesSplash(experienceUpgrade: experienceUpgrade)
|
||||
return OWSNavigationController(rootViewController: vc)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
@ -84,7 +80,7 @@ class ExperienceUpgradeManager: NSObject {
|
||||
switch experienceUpgrade.id {
|
||||
case .introducingPins,
|
||||
.reactions,
|
||||
.requiredProfileNames:
|
||||
.profileNameReminder:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@ -97,8 +93,8 @@ class ExperienceUpgradeManager: NSObject {
|
||||
return IntroducingPinsMegaphone(experienceUpgrade: experienceUpgrade, fromViewController: fromViewController)
|
||||
case .reactions:
|
||||
return ReactionsMegaphone(experienceUpgrade: experienceUpgrade, fromViewController: fromViewController)
|
||||
case .requiredProfileNames:
|
||||
return RequiredProfileNamesMegaphone(experienceUpgrade: experienceUpgrade, fromViewController: fromViewController)
|
||||
case .profileNameReminder:
|
||||
return ProfileNameReminderMegaphone(experienceUpgrade: experienceUpgrade, fromViewController: fromViewController)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
//
|
||||
// Copyright (c) 2020 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Lottie
|
||||
|
||||
class ProfileNameReminderMegaphone: MegaphoneView {
|
||||
init(experienceUpgrade: ExperienceUpgrade, fromViewController: UIViewController) {
|
||||
super.init(experienceUpgrade: experienceUpgrade)
|
||||
|
||||
let hasProfileNameAlready = OWSProfileManager.shared().localFullName()?.isEmpty == false
|
||||
|
||||
titleText = hasProfileNameAlready
|
||||
? NSLocalizedString("REQUIRE_PROFILE_NAMES_MEGAPHONE_HAS_NAME_TITLE",
|
||||
comment: "Title for required profile name megaphone when user already has a profile name")
|
||||
: NSLocalizedString("REQUIRE_PROFILE_NAMES_MEGAPHONE_NO_NAME_TITLE",
|
||||
comment: "Title for required profile name megaphone when user doesn't have a profile name")
|
||||
bodyText = hasProfileNameAlready
|
||||
? NSLocalizedString("REQUIRE_PROFILE_NAMES_MEGAPHONE_HAS_NAME_BODY",
|
||||
comment: "Body for required profile name megaphone when user already has a profile name")
|
||||
: NSLocalizedString("REQUIRE_PROFILE_NAMES_MEGAPHONE_NO_NAME_BODY",
|
||||
comment: "Body for required profile name megaphone when user doesn't have a profile name")
|
||||
imageName = "profileMegaphone"
|
||||
|
||||
let primaryButton = MegaphoneView.Button(
|
||||
title: NSLocalizedString("REQUIRE_PROFILE_NAMES_MEGAPHONE_ACTION",
|
||||
comment: "Action text for required profile name megaphone")
|
||||
) { [weak self] in
|
||||
let vc = ProfileViewController.forExperienceUpgrade {
|
||||
self?.markAsComplete()
|
||||
fromViewController.navigationController?.popToViewController(fromViewController, animated: true) {
|
||||
fromViewController.navigationController?.setNavigationBarHidden(false, animated: false)
|
||||
self?.dismiss(animated: false)
|
||||
self?.presentToast(
|
||||
text: NSLocalizedString("REQUIRE_PROFILE_NAMES_MEGAPHONE_TOAST",
|
||||
comment: "Toast indicating that a PIN has been created."),
|
||||
fromViewController: fromViewController
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fromViewController.navigationController?.pushViewController(vc, animated: true)
|
||||
}
|
||||
|
||||
let secondaryButton = snoozeButton(fromViewController: fromViewController)
|
||||
setButtons(primary: primaryButton, secondary: secondaryButton)
|
||||
}
|
||||
|
||||
required init(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
@ -1,188 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2020 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Lottie
|
||||
|
||||
class RequiredProfileNamesMegaphone: MegaphoneView {
|
||||
init(experienceUpgrade: ExperienceUpgrade, fromViewController: UIViewController) {
|
||||
super.init(experienceUpgrade: experienceUpgrade)
|
||||
|
||||
let hasProfileNameAlready = OWSProfileManager.shared().localFullName()?.isEmpty == false
|
||||
|
||||
titleText = hasProfileNameAlready
|
||||
? NSLocalizedString("REQUIRE_PROFILE_NAMES_MEGAPHONE_HAS_NAME_TITLE",
|
||||
comment: "Title for required profile name megaphone when user already has a profile name")
|
||||
: NSLocalizedString("REQUIRE_PROFILE_NAMES_MEGAPHONE_NO_NAME_TITLE",
|
||||
comment: "Title for required profile name megaphone when user doesn't have a profile name")
|
||||
bodyText = hasProfileNameAlready
|
||||
? NSLocalizedString("REQUIRE_PROFILE_NAMES_MEGAPHONE_HAS_NAME_BODY",
|
||||
comment: "Body for required profile name megaphone when user already has a profile name")
|
||||
: NSLocalizedString("REQUIRE_PROFILE_NAMES_MEGAPHONE_NO_NAME_BODY",
|
||||
comment: "Body for required profile name megaphone when user doesn't have a profile name")
|
||||
imageName = "profileMegaphone"
|
||||
|
||||
let primaryButton = MegaphoneView.Button(
|
||||
title: NSLocalizedString("REQUIRE_PROFILE_NAMES_MEGAPHONE_ACTION",
|
||||
comment: "Action text for required profile name megaphone")
|
||||
) { [weak self] in
|
||||
let vc = ProfileViewController.forExperienceUpgrade {
|
||||
self?.markAsComplete()
|
||||
fromViewController.navigationController?.popToViewController(fromViewController, animated: true) {
|
||||
fromViewController.navigationController?.setNavigationBarHidden(false, animated: false)
|
||||
self?.dismiss(animated: false)
|
||||
self?.presentToast(
|
||||
text: NSLocalizedString("REQUIRE_PROFILE_NAMES_MEGAPHONE_TOAST",
|
||||
comment: "Toast indicating that a PIN has been created."),
|
||||
fromViewController: fromViewController
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fromViewController.navigationController?.pushViewController(vc, animated: true)
|
||||
}
|
||||
|
||||
let secondaryButton = snoozeButton(fromViewController: fromViewController)
|
||||
setButtons(primary: primaryButton, secondary: secondaryButton)
|
||||
}
|
||||
|
||||
required init(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
|
||||
class RequiredProfileNamesSplash: SplashViewController {
|
||||
|
||||
let animationView = AnimationView(name: "requiredProfileNamesSplash")
|
||||
|
||||
var ows2FAManager: OWS2FAManager {
|
||||
return .shared()
|
||||
}
|
||||
|
||||
var hasProfileNameAlready: Bool {
|
||||
return OWSProfileManager.shared().localFullName()?.isEmpty == false
|
||||
}
|
||||
|
||||
override var canDismissWithGesture: Bool { return false }
|
||||
|
||||
// MARK: - View lifecycle
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
animationView.play()
|
||||
navigationController?.setNavigationBarHidden(true, animated: false)
|
||||
}
|
||||
|
||||
override func viewWillDisappear(_ animated: Bool) {
|
||||
super.viewWillDisappear(animated)
|
||||
navigationController?.setNavigationBarHidden(false, animated: false)
|
||||
}
|
||||
|
||||
override func loadView() {
|
||||
|
||||
self.view = UIView.container()
|
||||
self.view.backgroundColor = Theme.backgroundColor
|
||||
|
||||
animationView.contentMode = .scaleAspectFit
|
||||
animationView.loopMode = .playOnce
|
||||
animationView.backgroundBehavior = .forceFinish
|
||||
|
||||
view.addSubview(animationView)
|
||||
animationView.autoPinTopToSuperviewMargin(withInset: 10)
|
||||
animationView.autoPinWidthToSuperview()
|
||||
animationView.setContentHuggingLow()
|
||||
animationView.setCompressionResistanceLow()
|
||||
|
||||
let title: String
|
||||
let body: String
|
||||
|
||||
if hasProfileNameAlready {
|
||||
title = NSLocalizedString("REQUIRE_PROFILE_NAMES_SPLASH_CONFIRMATION_TITLE",
|
||||
comment: "Header for required profile names splash screen when the user already has a profile name")
|
||||
body = NSLocalizedString("REQUIRE_PROFILE_NAMES_SPLASH_CONFIRMATION_DESCRIPTION",
|
||||
comment: "Body text for required profile names splash screen when the user already has a profile name")
|
||||
} else {
|
||||
title = NSLocalizedString("REQUIRE_PROFILE_NAMES_SPLASH_CREATION_TITLE",
|
||||
comment: "Header for required profile names splash screen when the user doesn't have a profile name")
|
||||
body = NSLocalizedString("REQUIRE_PROFILE_NAMES_SPLASH_CREATION_DESCRIPTION",
|
||||
comment: "Body text for required profile names splash screen when the user doesn't have a profile name")
|
||||
}
|
||||
|
||||
let hMargin: CGFloat = ScaleFromIPhone5To7Plus(16, 24)
|
||||
|
||||
// Title label
|
||||
let titleLabel = UILabel()
|
||||
titleLabel.text = title
|
||||
titleLabel.textAlignment = .center
|
||||
titleLabel.font = UIFont.ows_dynamicTypeTitle1.ows_semibold()
|
||||
titleLabel.textColor = Theme.primaryTextColor
|
||||
titleLabel.minimumScaleFactor = 0.5
|
||||
titleLabel.adjustsFontSizeToFitWidth = true
|
||||
view.addSubview(titleLabel)
|
||||
titleLabel.autoPinWidthToSuperview(withMargin: hMargin)
|
||||
// The title label actually overlaps the hero image because it has a long shadow
|
||||
// and we want the text to partially sit on top of this.
|
||||
titleLabel.autoPinEdge(.top, to: .bottom, of: animationView, withOffset: -10)
|
||||
titleLabel.setContentHuggingVerticalHigh()
|
||||
|
||||
// Body label
|
||||
let bodyLabel = UILabel()
|
||||
bodyLabel.text = body
|
||||
bodyLabel.font = UIFont.ows_dynamicTypeBody
|
||||
bodyLabel.textColor = Theme.primaryTextColor
|
||||
bodyLabel.numberOfLines = 0
|
||||
bodyLabel.lineBreakMode = .byWordWrapping
|
||||
bodyLabel.textAlignment = .center
|
||||
view.addSubview(bodyLabel)
|
||||
bodyLabel.autoPinWidthToSuperview(withMargin: hMargin)
|
||||
bodyLabel.autoPinEdge(.top, to: .bottom, of: titleLabel, withOffset: 6)
|
||||
bodyLabel.setContentHuggingVerticalHigh()
|
||||
|
||||
// Primary button
|
||||
let primaryButton = OWSFlatButton.button(title: primaryButtonTitle(),
|
||||
font: UIFont.ows_dynamicTypeBody.ows_semibold(),
|
||||
titleColor: .white,
|
||||
backgroundColor: .ows_signalBlue,
|
||||
target: self,
|
||||
selector: #selector(didTapPrimaryButton))
|
||||
primaryButton.autoSetHeightUsingFont()
|
||||
view.addSubview(primaryButton)
|
||||
|
||||
primaryButton.autoPinWidthToSuperview(withMargin: hMargin)
|
||||
primaryButton.autoPinEdge(.top, to: .bottom, of: bodyLabel, withOffset: 28)
|
||||
primaryButton.setContentHuggingVerticalHigh()
|
||||
primaryButton.autoPinBottomToSuperviewMargin(withInset: ScaleFromIPhone5(10))
|
||||
}
|
||||
|
||||
@objc
|
||||
func didTapPrimaryButton(_ sender: UIButton) {
|
||||
let vc = ProfileViewController.forExperienceUpgrade { [weak self] in
|
||||
self?.dismiss(animated: true)
|
||||
}
|
||||
navigationController?.pushViewController(vc, animated: true)
|
||||
}
|
||||
|
||||
func primaryButtonTitle() -> String {
|
||||
return hasProfileNameAlready
|
||||
? NSLocalizedString("REQUIRE_PROFILE_NAMES_SPLASH_CONFIRMATION_BUTTON",
|
||||
comment: "Button to start a confirm profile name flow from the one time splash screen that appears after upgrading")
|
||||
: NSLocalizedString("REQUIRE_PROFILE_NAMES_SPLASH_CREATION_BUTTON",
|
||||
comment: "Button to start a create profile name flow from the one time splash screen that appears after upgrading")
|
||||
}
|
||||
|
||||
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
|
||||
guard let fromViewController = presentingViewController else {
|
||||
return owsFailDebug("Trying to dismiss while not presented.")
|
||||
}
|
||||
|
||||
super.dismiss(animated: flag) { [weak self] in
|
||||
self?.presentToast(
|
||||
text: NSLocalizedString("REQUIRE_PROFILE_NAMES_MEGAPHONE_TOAST",
|
||||
comment: "Toast indicating that a PIN has been created."),
|
||||
fromViewController: fromViewController
|
||||
)
|
||||
completion?()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,7 +8,7 @@ import Reachability
|
||||
public enum ExperienceUpgradeId: String, CaseIterable {
|
||||
case introducingPins = "009"
|
||||
case reactions = "010"
|
||||
case requiredProfileNames = "011"
|
||||
case profileNameReminder = "011"
|
||||
|
||||
// Until this flag is true the upgrade won't display to users.
|
||||
var hasLaunched: Bool {
|
||||
@ -19,8 +19,8 @@ public enum ExperienceUpgradeId: String, CaseIterable {
|
||||
SSKEnvironment.shared.reachabilityManager.isReachable
|
||||
case .reactions:
|
||||
return FeatureFlags.reactionSend
|
||||
case .requiredProfileNames:
|
||||
return RemoteConfig.requiredProfileNames
|
||||
case .profileNameReminder:
|
||||
return RemoteConfig.profileNameReminder
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -22,8 +22,8 @@ public class RemoteConfig: NSObject {
|
||||
}
|
||||
|
||||
@objc
|
||||
public static var requiredProfileNames: Bool {
|
||||
return isEnabled("ios.requiredProfileNames")
|
||||
public static var profileNameReminder: Bool {
|
||||
return isEnabled("ios.profileNameReminder")
|
||||
}
|
||||
|
||||
private static func isEnabled(_ key: String, defaultValue: Bool = false) -> Bool {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user