From 9e4e126ef3ed4352a51a92e02d82f91950d11a35 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 30 Nov 2021 15:51:15 +1100 Subject: [PATCH] add call missed tips --- Session.xcodeproj/project.pbxproj | 4 ++ .../Views & Modals/CallMissedTipsModal.swift | 57 ++++++++++++++++++ Session/Meta/AppDelegate.swift | 11 +++- .../Session/Tips.imageset/Contents.json | 12 ++++ .../Session/Tips.imageset/Tips.pdf | Bin 0 -> 5371 bytes .../Translations/en.lproj/Localizable.strings | 2 + 6 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 Session/Calls/Views & Modals/CallMissedTipsModal.swift create mode 100644 Session/Meta/Images.xcassets/Session/Tips.imageset/Contents.json create mode 100644 Session/Meta/Images.xcassets/Session/Tips.imageset/Tips.pdf diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index c423f2c19..3758930ff 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -140,6 +140,7 @@ 7B0EFDF0275084AA00FFAAE7 /* CallMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0EFDEF275084AA00FFAAE7 /* CallMessageCell.swift */; }; 7B0EFDF2275449AA00FFAAE7 /* TSInfoMessage+Calls.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0EFDF1275449AA00FFAAE7 /* TSInfoMessage+Calls.swift */; }; 7B0EFDF4275490EA00FFAAE7 /* ringing.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 7B0EFDF3275490EA00FFAAE7 /* ringing.mp3 */; }; + 7B0EFDF62755CC5400FFAAE7 /* CallMissedTipsModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0EFDF52755CC5400FFAAE7 /* CallMissedTipsModal.swift */; }; 7B1581E2271E743B00848B49 /* OWSSounds.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1581E1271E743B00848B49 /* OWSSounds.swift */; }; 7B1581E4271FC59D00848B49 /* CallModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1581E3271FC59C00848B49 /* CallModal.swift */; }; 7B1581E6271FD2A100848B49 /* VideoPreviewVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1581E5271FD2A100848B49 /* VideoPreviewVC.swift */; }; @@ -1133,6 +1134,7 @@ 7B0EFDEF275084AA00FFAAE7 /* CallMessageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallMessageCell.swift; sourceTree = ""; }; 7B0EFDF1275449AA00FFAAE7 /* TSInfoMessage+Calls.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSInfoMessage+Calls.swift"; sourceTree = ""; }; 7B0EFDF3275490EA00FFAAE7 /* ringing.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = ringing.mp3; sourceTree = ""; }; + 7B0EFDF52755CC5400FFAAE7 /* CallMissedTipsModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallMissedTipsModal.swift; sourceTree = ""; }; 7B1581E1271E743B00848B49 /* OWSSounds.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OWSSounds.swift; sourceTree = ""; }; 7B1581E3271FC59C00848B49 /* CallModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallModal.swift; sourceTree = ""; }; 7B1581E5271FD2A100848B49 /* VideoPreviewVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPreviewVC.swift; sourceTree = ""; }; @@ -2084,6 +2086,7 @@ 7B7CB18D270D066F0079FF93 /* IncomingCallBanner.swift */, 7B7CB18F270FB2150079FF93 /* MiniCallView.swift */, 7B1581E727210ECC00848B49 /* RenderView.swift */, + 7B0EFDF52755CC5400FFAAE7 /* CallMissedTipsModal.swift */, ); path = "Views & Modals"; sourceTree = ""; @@ -4899,6 +4902,7 @@ B84A89BC25DE328A0040017D /* ProfilePictureVC.swift in Sources */, 34386A54207D271D009F5D9C /* NeverClearView.swift in Sources */, 451166C01FD86B98000739BA /* AccountManager.swift in Sources */, + 7B0EFDF62755CC5400FFAAE7 /* CallMissedTipsModal.swift in Sources */, C374EEF425DB31D40073A857 /* VoiceMessageRecordingView.swift in Sources */, 7B1581E6271FD2A100848B49 /* VideoPreviewVC.swift in Sources */, B83F2B88240CB75A000A54AB /* UIImage+Scaling.swift in Sources */, diff --git a/Session/Calls/Views & Modals/CallMissedTipsModal.swift b/Session/Calls/Views & Modals/CallMissedTipsModal.swift new file mode 100644 index 000000000..9c4227398 --- /dev/null +++ b/Session/Calls/Views & Modals/CallMissedTipsModal.swift @@ -0,0 +1,57 @@ +import UIKit + +@objc +final class CallMissedTipsModal : Modal { + private let caller: String + + // MARK: Lifecycle + @objc + init(caller: String) { + self.caller = caller + super.init(nibName: nil, bundle: nil) + self.modalPresentationStyle = .overFullScreen + self.modalTransitionStyle = .crossDissolve + } + + required init?(coder: NSCoder) { + preconditionFailure("Use init(onCallEnabled:) instead.") + } + + override init(nibName: String?, bundle: Bundle?) { + preconditionFailure("Use init(onCallEnabled:) instead.") + } + + override func populateContentView() { + // Tips icon + let tipsIconImageView = UIImageView(image: UIImage(named: "Tips")?.withTint(Colors.text)) + tipsIconImageView.set(.width, to: 19) + tipsIconImageView.set(.height, to: 28) + // Title + let titleLabel = UILabel() + titleLabel.textColor = Colors.text + titleLabel.font = .boldSystemFont(ofSize: Values.largeFontSize) + titleLabel.text = NSLocalizedString("modal_call_missed_tips_title", comment: "") + titleLabel.textAlignment = .center + // Message + let messageLabel = UILabel() + messageLabel.textColor = Colors.text + messageLabel.font = .systemFont(ofSize: Values.smallFontSize) + let message = String(format: NSLocalizedString("modal_call_missed_tips_explanation", comment: ""), caller) + messageLabel.text = message + messageLabel.numberOfLines = 0 + messageLabel.lineBreakMode = .byWordWrapping + messageLabel.textAlignment = .natural + // Cancel Button + cancelButton.setTitle(NSLocalizedString("OK", comment: ""), for: .normal) + // Main stack view + let mainStackView = UIStackView(arrangedSubviews: [ tipsIconImageView, titleLabel, messageLabel, cancelButton ]) + mainStackView.axis = .vertical + mainStackView.alignment = .center + mainStackView.spacing = Values.largeSpacing + contentView.addSubview(mainStackView) + mainStackView.pin(.leading, to: .leading, of: contentView, withInset: Values.largeSpacing) + mainStackView.pin(.top, to: .top, of: contentView, withInset: Values.largeSpacing) + contentView.pin(.trailing, to: .trailing, of: mainStackView, withInset: Values.largeSpacing) + contentView.pin(.bottom, to: .bottom, of: mainStackView, withInset: Values.largeSpacing) + } +} diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index edfa8f2c2..59ec4e3ca 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -55,10 +55,12 @@ extension AppDelegate { return infoMessage } - private func showMissedCallTipsIfNeeded() { + private func showMissedCallTipsIfNeeded(caller: String) { let userDefaults = UserDefaults.standard guard !userDefaults[.hasSeenCallMissedTips] else { return } - + guard let presentingVC = CurrentAppContext().frontmostViewController() else { preconditionFailure() } + let callMissedTipsModal = CallMissedTipsModal(caller: caller) + presentingVC.present(callMissedTipsModal, animated: true, completion: nil) userDefaults[.hasSeenCallMissedTips] = true } @@ -75,7 +77,10 @@ extension AppDelegate { guard SSKPreferences.areCallsEnabled else { let infoMessage = self.insertCallInfoMessage(for: message, using: transaction) infoMessage.updateCallInfoMessage(.missed, using: transaction) - self.showMissedCallTipsIfNeeded() + let contactName = Storage.shared.getContact(with: message.sender!, using: transaction)?.displayName(for: Contact.Context.regular) ?? message.sender! + DispatchQueue.main.async { + self.showMissedCallTipsIfNeeded(caller: contactName) + } return } let callManager = AppEnvironment.shared.callManager diff --git a/Session/Meta/Images.xcassets/Session/Tips.imageset/Contents.json b/Session/Meta/Images.xcassets/Session/Tips.imageset/Contents.json new file mode 100644 index 000000000..aba19f854 --- /dev/null +++ b/Session/Meta/Images.xcassets/Session/Tips.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Tips.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Session/Meta/Images.xcassets/Session/Tips.imageset/Tips.pdf b/Session/Meta/Images.xcassets/Session/Tips.imageset/Tips.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2818f54cb5d77c0e31909d7261ce258f2b1dcd48 GIT binary patch literal 5371 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 literal 0 HcmV?d00001 diff --git a/Session/Meta/Translations/en.lproj/Localizable.strings b/Session/Meta/Translations/en.lproj/Localizable.strings index 5af272ffc..964cdd237 100644 --- a/Session/Meta/Translations/en.lproj/Localizable.strings +++ b/Session/Meta/Translations/en.lproj/Localizable.strings @@ -596,3 +596,5 @@ "light_mode_theme" = "Light"; "PIN_BUTTON_TEXT" = "Pin"; "UNPIN_BUTTON_TEXT" = "Unpin"; +"modal_call_missed_tips_title" = "Call missed"; +"modal_call_missed_tips_explanation" = "Call missed from '%@' because you needed to enable the 'Voice and video calls' permission in the Privacy Settings.";