mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
typing indicator upgrade screen
This commit is contained in:
parent
13ab75fea9
commit
d9a4c6e837
4 changed files with 146 additions and 3 deletions
|
@ -425,6 +425,7 @@
|
||||||
4C090A1B210FD9C7001FD7F9 /* HapticFeedback.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C090A1A210FD9C7001FD7F9 /* HapticFeedback.swift */; };
|
4C090A1B210FD9C7001FD7F9 /* HapticFeedback.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C090A1A210FD9C7001FD7F9 /* HapticFeedback.swift */; };
|
||||||
4C11AA5020FD59C700351FBD /* MessageStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C11AA4F20FD59C700351FBD /* MessageStatusView.swift */; };
|
4C11AA5020FD59C700351FBD /* MessageStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C11AA4F20FD59C700351FBD /* MessageStatusView.swift */; };
|
||||||
4C13C9F620E57BA30089A98B /* ColorPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C13C9F520E57BA30089A98B /* ColorPickerViewController.swift */; };
|
4C13C9F620E57BA30089A98B /* ColorPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C13C9F520E57BA30089A98B /* ColorPickerViewController.swift */; };
|
||||||
|
4C1D233D218B96A000A0598F /* typing-animation.gif in Resources */ = {isa = PBXBuildFile; fileRef = 4C1D233C218B96A000A0598F /* typing-animation.gif */; };
|
||||||
4C20B2B720CA0034001BAC90 /* ThreadViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4542DF51208B82E9007B4E76 /* ThreadViewModel.swift */; };
|
4C20B2B720CA0034001BAC90 /* ThreadViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4542DF51208B82E9007B4E76 /* ThreadViewModel.swift */; };
|
||||||
4C20B2B920CA10DE001BAC90 /* ConversationSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C20B2B820CA10DE001BAC90 /* ConversationSearchViewController.swift */; };
|
4C20B2B920CA10DE001BAC90 /* ConversationSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C20B2B820CA10DE001BAC90 /* ConversationSearchViewController.swift */; };
|
||||||
4C23A5F2215C4ADE00534937 /* SheetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C23A5F1215C4ADE00534937 /* SheetViewController.swift */; };
|
4C23A5F2215C4ADE00534937 /* SheetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C23A5F1215C4ADE00534937 /* SheetViewController.swift */; };
|
||||||
|
@ -1115,6 +1116,7 @@
|
||||||
4C090A1A210FD9C7001FD7F9 /* HapticFeedback.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = HapticFeedback.swift; path = UserInterface/HapticFeedback.swift; sourceTree = "<group>"; };
|
4C090A1A210FD9C7001FD7F9 /* HapticFeedback.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = HapticFeedback.swift; path = UserInterface/HapticFeedback.swift; sourceTree = "<group>"; };
|
||||||
4C11AA4F20FD59C700351FBD /* MessageStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageStatusView.swift; sourceTree = "<group>"; };
|
4C11AA4F20FD59C700351FBD /* MessageStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageStatusView.swift; sourceTree = "<group>"; };
|
||||||
4C13C9F520E57BA30089A98B /* ColorPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerViewController.swift; sourceTree = "<group>"; };
|
4C13C9F520E57BA30089A98B /* ColorPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerViewController.swift; sourceTree = "<group>"; };
|
||||||
|
4C1D233C218B96A000A0598F /* typing-animation.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = "typing-animation.gif"; path = "../../../../../Downloads/typing-animation.gif"; sourceTree = "<group>"; };
|
||||||
4C20B2B820CA10DE001BAC90 /* ConversationSearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationSearchViewController.swift; sourceTree = "<group>"; };
|
4C20B2B820CA10DE001BAC90 /* ConversationSearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationSearchViewController.swift; sourceTree = "<group>"; };
|
||||||
4C23A5F1215C4ADE00534937 /* SheetViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SheetViewController.swift; sourceTree = "<group>"; };
|
4C23A5F1215C4ADE00534937 /* SheetViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SheetViewController.swift; sourceTree = "<group>"; };
|
||||||
4C2F454E214C00E1004871FF /* AvatarTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarTableViewCell.swift; sourceTree = "<group>"; };
|
4C2F454E214C00E1004871FF /* AvatarTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
|
@ -2261,6 +2263,7 @@
|
||||||
B633C4FD1A1D190B0059AC12 /* Images */ = {
|
B633C4FD1A1D190B0059AC12 /* Images */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
4C1D233C218B96A000A0598F /* typing-animation.gif */,
|
||||||
AD83FF461A73428300B5C81A /* audio_play_button_blue.png */,
|
AD83FF461A73428300B5C81A /* audio_play_button_blue.png */,
|
||||||
AD83FF381A73426500B5C81A /* audio_pause_button_blue.png */,
|
AD83FF381A73426500B5C81A /* audio_pause_button_blue.png */,
|
||||||
AD83FF391A73426500B5C81A /* audio_pause_button_blue@2x.png */,
|
AD83FF391A73426500B5C81A /* audio_pause_button_blue@2x.png */,
|
||||||
|
@ -2856,6 +2859,7 @@
|
||||||
45B74A742044AAB600CD42F8 /* aurora-quiet.aifc in Resources */,
|
45B74A742044AAB600CD42F8 /* aurora-quiet.aifc in Resources */,
|
||||||
45B74A852044AAB600CD42F8 /* bamboo.aifc in Resources */,
|
45B74A852044AAB600CD42F8 /* bamboo.aifc in Resources */,
|
||||||
45B74A782044AAB600CD42F8 /* bamboo-quiet.aifc in Resources */,
|
45B74A782044AAB600CD42F8 /* bamboo-quiet.aifc in Resources */,
|
||||||
|
4C1D233D218B96A000A0598F /* typing-animation.gif in Resources */,
|
||||||
45B74A7B2044AAB600CD42F8 /* chord.aifc in Resources */,
|
45B74A7B2044AAB600CD42F8 /* chord.aifc in Resources */,
|
||||||
45B74A812044AAB600CD42F8 /* chord-quiet.aifc in Resources */,
|
45B74A812044AAB600CD42F8 /* chord-quiet.aifc in Resources */,
|
||||||
45B74A832044AAB600CD42F8 /* circles.aifc in Resources */,
|
45B74A832044AAB600CD42F8 /* circles.aifc in Resources */,
|
||||||
|
|
|
@ -225,6 +225,125 @@ private class IntroductingReadReceiptsExperienceUpgradeViewController: Experienc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class IntroductingTypingIndicatorsExperienceUpgradeViewController: ExperienceUpgradeViewController {
|
||||||
|
|
||||||
|
var buttonAction: ((UIButton) -> Void)?
|
||||||
|
|
||||||
|
override func loadView() {
|
||||||
|
self.view = UIView.container()
|
||||||
|
|
||||||
|
/// Create Views
|
||||||
|
|
||||||
|
// Title label
|
||||||
|
let titleLabel = UILabel()
|
||||||
|
view.addSubview(titleLabel)
|
||||||
|
titleLabel.text = header
|
||||||
|
titleLabel.textAlignment = .center
|
||||||
|
titleLabel.font = UIFont.ows_regularFont(withSize: ScaleFromIPhone5(24))
|
||||||
|
titleLabel.textColor = UIColor.white
|
||||||
|
titleLabel.minimumScaleFactor = 0.5
|
||||||
|
titleLabel.adjustsFontSizeToFitWidth = true
|
||||||
|
|
||||||
|
// Body label
|
||||||
|
let bodyLabel = UILabel()
|
||||||
|
self.bodyLabel = bodyLabel
|
||||||
|
view.addSubview(bodyLabel)
|
||||||
|
bodyLabel.text = body
|
||||||
|
bodyLabel.font = UIFont.ows_lightFont(withSize: ScaleFromIPhone5To7Plus(17, 22))
|
||||||
|
bodyLabel.textColor = Theme.primaryColor
|
||||||
|
bodyLabel.numberOfLines = 0
|
||||||
|
bodyLabel.lineBreakMode = .byWordWrapping
|
||||||
|
bodyLabel.textAlignment = .center
|
||||||
|
|
||||||
|
// Image
|
||||||
|
|
||||||
|
let imageView: UIView
|
||||||
|
if let gifPath = Bundle.main.path(forResource: "typing-animation", ofType: "gif") {
|
||||||
|
let animatedImage = YYImage(contentsOfFile: gifPath)
|
||||||
|
imageView = YYAnimatedImageView(image: animatedImage)
|
||||||
|
} else {
|
||||||
|
owsFailDebug("gifPath was unexpectedly nil")
|
||||||
|
imageView = UIImageView(image: image)
|
||||||
|
}
|
||||||
|
|
||||||
|
view.addSubview(imageView)
|
||||||
|
imageView.contentMode = .scaleAspectFit
|
||||||
|
|
||||||
|
let buttonTitle = NSLocalizedString("UPGRADE_EXPERIENCE_INTRODUCING_TYPING_INDICATOR_PRIVACY_SETTINGS", comment: "button label shown one time, after upgrade")
|
||||||
|
let button = addButton(title: buttonTitle) { _ in
|
||||||
|
// dismiss the modally presented view controller, then proceed.
|
||||||
|
self.experienceUpgradesPageViewController.dismiss(animated: true) {
|
||||||
|
guard let fromViewController = UIApplication.shared.frontmostViewController as? HomeViewController else {
|
||||||
|
owsFailDebug("unexpected frontmostViewController: \(String(describing: UIApplication.shared.frontmostViewController))")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct the "settings" view & push the "privacy settings" view.
|
||||||
|
let navigationController = AppSettingsViewController.inModalNavigationController()
|
||||||
|
navigationController.pushViewController(PrivacySettingsTableViewController(), animated: false)
|
||||||
|
|
||||||
|
fromViewController.present(navigationController, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let bottomSpacer = UIView()
|
||||||
|
view.addSubview(bottomSpacer)
|
||||||
|
|
||||||
|
/// Layout Views
|
||||||
|
|
||||||
|
// Image layout
|
||||||
|
imageView.autoAlignAxis(toSuperviewAxis: .vertical)
|
||||||
|
imageView.autoPinToSquareAspectRatio()
|
||||||
|
imageView.autoPinEdge(.top, to: .bottom, of: titleLabel, withOffset: ScaleFromIPhone5To7Plus(36, 40))
|
||||||
|
imageView.autoSetDimension(.width, toSize: ScaleFromIPhone5(180))
|
||||||
|
|
||||||
|
// Title label layout
|
||||||
|
titleLabel.autoSetDimension(.height, toSize: ScaleFromIPhone5(40))
|
||||||
|
titleLabel.autoPinWidthToSuperview(withMargin: ScaleFromIPhone5To7Plus(16, 24))
|
||||||
|
titleLabel.autoPinTopToSuperviewMargin()
|
||||||
|
|
||||||
|
// Body label layout
|
||||||
|
bodyLabel.autoPinEdge(.top, to: .bottom, of: imageView, withOffset: ScaleFromIPhone5To7Plus(18, 28))
|
||||||
|
bodyLabel.autoPinWidthToSuperview(withMargin: bodyMargin)
|
||||||
|
bodyLabel.setContentHuggingVerticalHigh()
|
||||||
|
|
||||||
|
// Button layout
|
||||||
|
button.autoPinEdge(.top, to: .bottom, of: bodyLabel, withOffset: ScaleFromIPhone5(16))
|
||||||
|
button.autoPinWidthToSuperview(withMargin: ScaleFromIPhone5(32))
|
||||||
|
|
||||||
|
bottomSpacer.autoPinEdge(.top, to: .bottom, of: button, withOffset: ScaleFromIPhone5(16))
|
||||||
|
bottomSpacer.autoPinEdge(toSuperviewEdge: .bottom)
|
||||||
|
bottomSpacer.autoPinWidthToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Actions
|
||||||
|
|
||||||
|
func addButton(title: String, action: @escaping (UIButton) -> Void) -> UIButton {
|
||||||
|
self.buttonAction = action
|
||||||
|
let button = MultiLineButton()
|
||||||
|
view.addSubview(button)
|
||||||
|
button.setTitle(title, for: .normal)
|
||||||
|
button.setTitleColor(UIColor.ows_signalBrandBlue, for: .normal)
|
||||||
|
button.isUserInteractionEnabled = true
|
||||||
|
button.addTarget(self, action: #selector(didTapButton), for: .touchUpInside)
|
||||||
|
button.contentEdgeInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
|
||||||
|
button.titleLabel?.textAlignment = .center
|
||||||
|
button.titleLabel?.font = UIFont.ows_mediumFont(withSize: ScaleFromIPhone5(18))
|
||||||
|
return button
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func didTapButton(sender: UIButton) {
|
||||||
|
Logger.debug("")
|
||||||
|
|
||||||
|
guard let buttonAction = self.buttonAction else {
|
||||||
|
owsFailDebug("button action was nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonAction(sender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows multiple lines of button text, and ensures the buttons intrinsic content size reflects that of it's label.
|
* Allows multiple lines of button text, and ensures the buttons intrinsic content size reflects that of it's label.
|
||||||
*/
|
*/
|
||||||
|
@ -667,6 +786,8 @@ public class ExperienceUpgradesPageViewController: OWSViewController, UIPageView
|
||||||
return IntroductingReadReceiptsExperienceUpgradeViewController(experienceUpgrade: experienceUpgrade, experienceUpgradesPageViewController: self)
|
return IntroductingReadReceiptsExperienceUpgradeViewController(experienceUpgrade: experienceUpgrade, experienceUpgradesPageViewController: self)
|
||||||
case .introducingCustomNotificationAudio:
|
case .introducingCustomNotificationAudio:
|
||||||
return IntroducingCustomNotificationAudioExperienceUpgradeViewController(experienceUpgrade: experienceUpgrade, experienceUpgradesPageViewController: self)
|
return IntroducingCustomNotificationAudioExperienceUpgradeViewController(experienceUpgrade: experienceUpgrade, experienceUpgradesPageViewController: self)
|
||||||
|
case .introducingTypingIndicators:
|
||||||
|
return IntroductingTypingIndicatorsExperienceUpgradeViewController(experienceUpgrade: experienceUpgrade, experienceUpgradesPageViewController: self)
|
||||||
default:
|
default:
|
||||||
return ExperienceUpgradeViewController(experienceUpgrade: experienceUpgrade, experienceUpgradesPageViewController: self)
|
return ExperienceUpgradeViewController(experienceUpgrade: experienceUpgrade, experienceUpgradesPageViewController: self)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,8 @@ enum ExperienceUpgradeId: String {
|
||||||
callKit = "002",
|
callKit = "002",
|
||||||
introducingProfiles = "003",
|
introducingProfiles = "003",
|
||||||
introducingReadReceipts = "004",
|
introducingReadReceipts = "004",
|
||||||
introducingCustomNotificationAudio = "005"
|
introducingCustomNotificationAudio = "005",
|
||||||
|
introducingTypingIndicators = "006"
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public class ExperienceUpgradeFinder: NSObject {
|
@objc public class ExperienceUpgradeFinder: NSObject {
|
||||||
|
@ -61,6 +62,13 @@ enum ExperienceUpgradeId: String {
|
||||||
image: #imageLiteral(resourceName: "introductory_splash_custom_audio"))
|
image: #imageLiteral(resourceName: "introductory_splash_custom_audio"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var typingIndicators: ExperienceUpgrade {
|
||||||
|
return ExperienceUpgrade(uniqueId: ExperienceUpgradeId.introducingTypingIndicators.rawValue,
|
||||||
|
title: NSLocalizedString("UPGRADE_EXPERIENCE_INTRODUCING_TYPING_INDICATORS_TITLE", comment: "Header for upgrading users"),
|
||||||
|
body: NSLocalizedString("UPGRADE_EXPERIENCE_INTRODUCING_TYPING_INDICATORS_DESCRIPTION", comment: "Body text for upgrading users"),
|
||||||
|
image: #imageLiteral(resourceName: "introductory_splash_custom_audio"))
|
||||||
|
}
|
||||||
|
|
||||||
// Keep these ordered by increasing uniqueId.
|
// Keep these ordered by increasing uniqueId.
|
||||||
@objc
|
@objc
|
||||||
public var allExperienceUpgrades: [ExperienceUpgrade] {
|
public var allExperienceUpgrades: [ExperienceUpgrade] {
|
||||||
|
@ -73,7 +81,8 @@ enum ExperienceUpgradeId: String {
|
||||||
// (UIDevice.current.supportsCallKit ? callKit : nil),
|
// (UIDevice.current.supportsCallKit ? callKit : nil),
|
||||||
// introducingProfiles,
|
// introducingProfiles,
|
||||||
// introducingReadReceipts,
|
// introducingReadReceipts,
|
||||||
configurableNotificationAudio
|
// configurableNotificationAudio
|
||||||
|
typingIndicators
|
||||||
].compactMap { $0 }
|
].compactMap { $0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1161,7 +1161,7 @@
|
||||||
/* Confirmation button text to delete selected media message from the gallery */
|
/* Confirmation button text to delete selected media message from the gallery */
|
||||||
"MEDIA_GALLERY_DELETE_SINGLE_MESSAGE" = "Delete Message";
|
"MEDIA_GALLERY_DELETE_SINGLE_MESSAGE" = "Delete Message";
|
||||||
|
|
||||||
/* embeds {{sender name}} and {{sent date}}, e.g. 'Sarah on 10/30/18, 3:29' */
|
/* embeds {{sender name}} and {{sent datetime}}, e.g. 'Sarah on 10/30/18, 3:29' */
|
||||||
"MEDIA_GALLERY_LANDSCAPE_TITLE_FORMAT" = "%@ on %@";
|
"MEDIA_GALLERY_LANDSCAPE_TITLE_FORMAT" = "%@ on %@";
|
||||||
|
|
||||||
/* Short sender label for media sent by you */
|
/* Short sender label for media sent by you */
|
||||||
|
@ -2303,6 +2303,15 @@
|
||||||
/* Header for upgrade experience */
|
/* Header for upgrade experience */
|
||||||
"UPGRADE_EXPERIENCE_INTRODUCING_READ_RECEIPTS_TITLE" = "Introducing Read Receipts";
|
"UPGRADE_EXPERIENCE_INTRODUCING_READ_RECEIPTS_TITLE" = "Introducing Read Receipts";
|
||||||
|
|
||||||
|
/* button label shown one time, after upgrade */
|
||||||
|
"UPGRADE_EXPERIENCE_INTRODUCING_TYPING_INDICATOR_PRIVACY_SETTINGS" = "Enable typing indicators in your privacy settings.";
|
||||||
|
|
||||||
|
/* Body text for upgrading users */
|
||||||
|
"UPGRADE_EXPERIENCE_INTRODUCING_TYPING_INDICATORS_DESCRIPTION" = "Now you can optionally see and share when messages are being typed.";
|
||||||
|
|
||||||
|
/* Header for upgrading users */
|
||||||
|
"UPGRADE_EXPERIENCE_INTRODUCING_TYPING_INDICATORS_TITLE" = "Introducing Typing Indicators";
|
||||||
|
|
||||||
/* Description of video calling to upgrading (existing) users */
|
/* Description of video calling to upgrading (existing) users */
|
||||||
"UPGRADE_EXPERIENCE_VIDEO_DESCRIPTION" = "Signal now supports secure video calling. Just start a call like normal, tap the camera button, and wave hello.";
|
"UPGRADE_EXPERIENCE_VIDEO_DESCRIPTION" = "Signal now supports secure video calling. Just start a call like normal, tap the camera button, and wave hello.";
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue