Merge branch 'dev' of https://github.com/loki-project/session-ios into notification-bugs

This commit is contained in:
Ryan ZHAO 2020-07-31 13:03:21 +10:00
commit 04c6610e10
10 changed files with 128 additions and 129 deletions

View File

@ -574,7 +574,6 @@
C31A6C5A247F214E001123EF /* UIView+Glow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31A6C59247F214E001123EF /* UIView+Glow.swift */; }; C31A6C5A247F214E001123EF /* UIView+Glow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31A6C59247F214E001123EF /* UIView+Glow.swift */; };
C31A6C5C247F2CF3001123EF /* CGRect+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31A6C5B247F2CF3001123EF /* CGRect+Utilities.swift */; }; C31A6C5C247F2CF3001123EF /* CGRect+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31A6C5B247F2CF3001123EF /* CGRect+Utilities.swift */; };
C34C8F7423A7830B00D82669 /* SpaceMono-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C34C8F7323A7830A00D82669 /* SpaceMono-Bold.ttf */; }; C34C8F7423A7830B00D82669 /* SpaceMono-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C34C8F7323A7830A00D82669 /* SpaceMono-Bold.ttf */; };
C353F8F7244808E90011121A /* PNModeSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C353F8F6244808E90011121A /* PNModeSheet.swift */; };
C353F8F9244809150011121A /* PNOptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C353F8F8244809150011121A /* PNOptionView.swift */; }; C353F8F9244809150011121A /* PNOptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C353F8F8244809150011121A /* PNOptionView.swift */; };
C3548F0624456447009433A8 /* PNModeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3548F0524456447009433A8 /* PNModeVC.swift */; }; C3548F0624456447009433A8 /* PNModeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3548F0524456447009433A8 /* PNModeVC.swift */; };
C3548F0824456AB6009433A8 /* UIView+Wrapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3548F0724456AB6009433A8 /* UIView+Wrapping.swift */; }; C3548F0824456AB6009433A8 /* UIView+Wrapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3548F0724456AB6009433A8 /* UIView+Wrapping.swift */; };
@ -584,6 +583,7 @@
C35E8AA92485C85800ACB629 /* GeoLite2-Country-Blocks-IPv4.csv in Resources */ = {isa = PBXBuildFile; fileRef = C35E8AA62485C85600ACB629 /* GeoLite2-Country-Blocks-IPv4.csv */; }; C35E8AA92485C85800ACB629 /* GeoLite2-Country-Blocks-IPv4.csv in Resources */ = {isa = PBXBuildFile; fileRef = C35E8AA62485C85600ACB629 /* GeoLite2-Country-Blocks-IPv4.csv */; };
C35E8AAE2485E51D00ACB629 /* IP2Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35E8AAD2485E51D00ACB629 /* IP2Country.swift */; }; C35E8AAE2485E51D00ACB629 /* IP2Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35E8AAD2485E51D00ACB629 /* IP2Country.swift */; };
C3638C0524C7F0B500AF29BC /* LK002RemoveFriendRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3638C0424C7F0B500AF29BC /* LK002RemoveFriendRequests.swift */; }; C3638C0524C7F0B500AF29BC /* LK002RemoveFriendRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3638C0424C7F0B500AF29BC /* LK002RemoveFriendRequests.swift */; };
C369549D24D27A3500CEB4E3 /* MultiDeviceRemovalSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C369549C24D27A3500CEB4E3 /* MultiDeviceRemovalSheet.swift */; };
C36B8707243C50C60049991D /* SignalMessaging.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 453518921FC63DBF00210559 /* SignalMessaging.framework */; }; C36B8707243C50C60049991D /* SignalMessaging.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 453518921FC63DBF00210559 /* SignalMessaging.framework */; };
C3DAB3242480CB2B00725F25 /* SRCopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */; }; C3DAB3242480CB2B00725F25 /* SRCopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */; };
C3DFFAC623E96F0D0058DAF8 /* Sheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */; }; C3DFFAC623E96F0D0058DAF8 /* Sheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */; };
@ -1362,7 +1362,6 @@
C31A6C59247F214E001123EF /* UIView+Glow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Glow.swift"; sourceTree = "<group>"; }; C31A6C59247F214E001123EF /* UIView+Glow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Glow.swift"; sourceTree = "<group>"; };
C31A6C5B247F2CF3001123EF /* CGRect+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGRect+Utilities.swift"; sourceTree = "<group>"; }; C31A6C5B247F2CF3001123EF /* CGRect+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGRect+Utilities.swift"; sourceTree = "<group>"; };
C34C8F7323A7830A00D82669 /* SpaceMono-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SpaceMono-Bold.ttf"; sourceTree = "<group>"; }; C34C8F7323A7830A00D82669 /* SpaceMono-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SpaceMono-Bold.ttf"; sourceTree = "<group>"; };
C353F8F6244808E90011121A /* PNModeSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PNModeSheet.swift; sourceTree = "<group>"; };
C353F8F8244809150011121A /* PNOptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PNOptionView.swift; sourceTree = "<group>"; }; C353F8F8244809150011121A /* PNOptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PNOptionView.swift; sourceTree = "<group>"; };
C3548F0524456447009433A8 /* PNModeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PNModeVC.swift; sourceTree = "<group>"; }; C3548F0524456447009433A8 /* PNModeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PNModeVC.swift; sourceTree = "<group>"; };
C3548F0724456AB6009433A8 /* UIView+Wrapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Wrapping.swift"; sourceTree = "<group>"; }; C3548F0724456AB6009433A8 /* UIView+Wrapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Wrapping.swift"; sourceTree = "<group>"; };
@ -1372,6 +1371,7 @@
C35E8AA62485C85600ACB629 /* GeoLite2-Country-Blocks-IPv4.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "GeoLite2-Country-Blocks-IPv4.csv"; sourceTree = "<group>"; }; C35E8AA62485C85600ACB629 /* GeoLite2-Country-Blocks-IPv4.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "GeoLite2-Country-Blocks-IPv4.csv"; sourceTree = "<group>"; };
C35E8AAD2485E51D00ACB629 /* IP2Country.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IP2Country.swift; sourceTree = "<group>"; }; C35E8AAD2485E51D00ACB629 /* IP2Country.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IP2Country.swift; sourceTree = "<group>"; };
C3638C0424C7F0B500AF29BC /* LK002RemoveFriendRequests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LK002RemoveFriendRequests.swift; sourceTree = "<group>"; }; C3638C0424C7F0B500AF29BC /* LK002RemoveFriendRequests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LK002RemoveFriendRequests.swift; sourceTree = "<group>"; };
C369549C24D27A3500CEB4E3 /* MultiDeviceRemovalSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiDeviceRemovalSheet.swift; sourceTree = "<group>"; };
C3AA6BB824CE8F1B002358B6 /* Migrating Translations from Android.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "Migrating Translations from Android.md"; sourceTree = "<group>"; }; C3AA6BB824CE8F1B002358B6 /* Migrating Translations from Android.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "Migrating Translations from Android.md"; sourceTree = "<group>"; };
C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRCopyableLabel.swift; sourceTree = "<group>"; }; C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRCopyableLabel.swift; sourceTree = "<group>"; };
C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sheet.swift; sourceTree = "<group>"; }; C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sheet.swift; sourceTree = "<group>"; };
@ -2710,12 +2710,12 @@
B85357C423A1F13800AAF6CD /* LinkDeviceVC.swift */, B85357C423A1F13800AAF6CD /* LinkDeviceVC.swift */,
B85357C623A1FB5100AAF6CD /* LinkDeviceVCDelegate.swift */, B85357C623A1FB5100AAF6CD /* LinkDeviceVCDelegate.swift */,
B86BD08323399ACF000F5AE3 /* Modal.swift */, B86BD08323399ACF000F5AE3 /* Modal.swift */,
C369549C24D27A3500CEB4E3 /* MultiDeviceRemovalSheet.swift */,
B80A579E23DFF1F300876683 /* NewClosedGroupVC.swift */, B80A579E23DFF1F300876683 /* NewClosedGroupVC.swift */,
B8CCF63623961D6D0091D419 /* NewPrivateChatVC.swift */, B8CCF63623961D6D0091D419 /* NewPrivateChatVC.swift */,
B894D0742339EDCF00B4D94D /* NukeDataModal.swift */, B894D0742339EDCF00B4D94D /* NukeDataModal.swift */,
C3DFFAC723E970080058DAF8 /* OpenGroupSuggestionSheet.swift */, C3DFFAC723E970080058DAF8 /* OpenGroupSuggestionSheet.swift */,
B879D448247E1BE300DB3608 /* PathVC.swift */, B879D448247E1BE300DB3608 /* PathVC.swift */,
C353F8F6244808E90011121A /* PNModeSheet.swift */,
C3548F0524456447009433A8 /* PNModeVC.swift */, C3548F0524456447009433A8 /* PNModeVC.swift */,
B886B4A62398B23E00211ABE /* QRCodeVC.swift */, B886B4A62398B23E00211ABE /* QRCodeVC.swift */,
B82B408B239A068800A248E7 /* RegisterVC.swift */, B82B408B239A068800A248E7 /* RegisterVC.swift */,
@ -3801,7 +3801,6 @@
4C4AEC4520EC343B0020E72B /* DismissableTextField.swift in Sources */, 4C4AEC4520EC343B0020E72B /* DismissableTextField.swift in Sources */,
4CB5F26720F6E1E2004D1B42 /* MenuActionsViewController.swift in Sources */, 4CB5F26720F6E1E2004D1B42 /* MenuActionsViewController.swift in Sources */,
3496955E219B605E00DCFE74 /* PhotoLibrary.swift in Sources */, 3496955E219B605E00DCFE74 /* PhotoLibrary.swift in Sources */,
C353F8F7244808E90011121A /* PNModeSheet.swift in Sources */,
45D231771DC7E8F10034FA89 /* SessionResetJob.swift in Sources */, 45D231771DC7E8F10034FA89 /* SessionResetJob.swift in Sources */,
340FC8A9204DAC8D007AEB0F /* NotificationSettingsOptionsViewController.m in Sources */, 340FC8A9204DAC8D007AEB0F /* NotificationSettingsOptionsViewController.m in Sources */,
C3548F0624456447009433A8 /* PNModeVC.swift in Sources */, C3548F0624456447009433A8 /* PNModeVC.swift in Sources */,
@ -3848,6 +3847,7 @@
4C21D5D8223AC60F00EF8A77 /* PhotoCapture.swift in Sources */, 4C21D5D8223AC60F00EF8A77 /* PhotoCapture.swift in Sources */,
4C13C9F620E57BA30089A98B /* ColorPickerViewController.swift in Sources */, 4C13C9F620E57BA30089A98B /* ColorPickerViewController.swift in Sources */,
4CC1ECFB211A553000CC13BE /* AppUpdateNag.swift in Sources */, 4CC1ECFB211A553000CC13BE /* AppUpdateNag.swift in Sources */,
C369549D24D27A3500CEB4E3 /* MultiDeviceRemovalSheet.swift in Sources */,
34B6A903218B3F63007C4606 /* TypingIndicatorView.swift in Sources */, 34B6A903218B3F63007C4606 /* TypingIndicatorView.swift in Sources */,
B8CCF639239721E20091D419 /* TabBar.swift in Sources */, B8CCF639239721E20091D419 /* TabBar.swift in Sources */,
458E38371D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m in Sources */, 458E38371D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m in Sources */,

View File

@ -5,9 +5,9 @@
<key>BuildDetails</key> <key>BuildDetails</key>
<dict> <dict>
<key>CarthageVersion</key> <key>CarthageVersion</key>
<string>0.34.0</string> <string>0.35.0</string>
<key>OSXVersion</key> <key>OSXVersion</key>
<string>10.15.5</string> <string>10.15.6</string>
<key>WebRTCCommit</key> <key>WebRTCCommit</key>
<string>1445d719bf05280270e9f77576f80f973fd847f8 M73</string> <string>1445d719bf05280270e9f77576f80f973fd847f8 M73</string>
</dict> </dict>

View File

@ -179,12 +179,16 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol
override func viewDidAppear(_ animated: Bool) { override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated) super.viewDidAppear(animated)
isViewVisible = true isViewVisible = true
let hasSeenPNModeSheet = UserDefaults.standard[.hasSeenPNModeSheet] let hasSeenMultiDeviceRemovalSheet = UserDefaults.standard[.hasSeenMultiDeviceRemovalSheet]
if !hasSeenPNModeSheet { if !hasSeenMultiDeviceRemovalSheet {
let pnModeSheet = PNModeSheet() let _ = FileServerAPI.getDeviceLinks(associatedWith: getUserHexEncodedPublicKey()).done(on: DispatchQueue.main) { [weak self] deviceLinks in
pnModeSheet.modalPresentationStyle = .overFullScreen guard !deviceLinks.isEmpty else { return }
pnModeSheet.modalTransitionStyle = .crossDissolve let multiDeviceRemovalSheet = MultiDeviceRemovalSheet()
present(pnModeSheet, animated: true, completion: nil) multiDeviceRemovalSheet.modalPresentationStyle = .overFullScreen
multiDeviceRemovalSheet.modalTransitionStyle = .crossDissolve
self?.present(multiDeviceRemovalSheet, animated: true, completion: nil)
}
UserDefaults.standard[.hasSeenMultiDeviceRemovalSheet] = true
} }
UserDefaults.standard[.hasLaunchedOnce] = true UserDefaults.standard[.hasLaunchedOnce] = true
} }
@ -214,16 +218,12 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol
isObservingDatabase = isViewVisible && CurrentAppContext().isAppForegroundAndActive() isObservingDatabase = isViewVisible && CurrentAppContext().isAppForegroundAndActive()
} }
private func updateYDBThreadMapping() { private func reload() {
AssertIsOnMainThread()
uiDatabaseConnection.beginLongLivedReadTransaction() uiDatabaseConnection.beginLongLivedReadTransaction()
uiDatabaseConnection.read { transaction in uiDatabaseConnection.read { transaction in
self.threads.update(with: transaction) self.threads.update(with: transaction)
} }
}
private func reload() {
AssertIsOnMainThread()
updateYDBThreadMapping()
threadViewModelCache.removeAll() threadViewModelCache.removeAll()
tableView.reloadData() tableView.reloadData()
emptyStateView.isHidden = (threadCount != 0) emptyStateView.isHidden = (threadCount != 0)
@ -244,17 +244,13 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol
} }
return return
} }
// Guard for changes made in Notification Service Extension // If changes were made in a different process (e.g. the Notification Service Extension) the thread mapping can be out of date
// Crashes may happen if there is some modification in NSE // at this point, causing the app to crash. The code below prevents that by force syncing the database before proceeding.
// The YapDBModificationNotification cannot cross process if notifications.count > 0 {
// So the thread mapping won't update itself if DB modification happened in other process like NSE if let firstChangeSet = notifications[0].userInfo {
// With these code we can sync the mapping before asking for changes from YapDB let firstSnapshot = firstChangeSet[YapDatabaseSnapshotKey] as! UInt64
if (notifications.count > 0) { if threads.snapshotOfLastUpdate != firstSnapshot - 1 {
if let firstChangeset = notifications[0].userInfo { return reload()
let firstSnapshot = firstChangeset[YapDatabaseSnapshotKey] as! UInt64
if (self.threads.snapshotOfLastUpdate != firstSnapshot - 1) {
reload()
return
} }
} }
} }

View File

@ -59,11 +59,11 @@ final class LandingVC : BaseVC, LinkDeviceVCDelegate, DeviceLinkingModalDelegate
// Set up link button container // Set up link button container
let linkButtonContainer = UIView() let linkButtonContainer = UIView()
linkButtonContainer.set(.height, to: Values.onboardingButtonBottomOffset) linkButtonContainer.set(.height, to: Values.onboardingButtonBottomOffset)
linkButtonContainer.addSubview(linkButton) // linkButtonContainer.addSubview(linkButton)
linkButton.pin(.leading, to: .leading, of: linkButtonContainer, withInset: Values.massiveSpacing) // linkButton.pin(.leading, to: .leading, of: linkButtonContainer, withInset: Values.massiveSpacing)
linkButton.pin(.top, to: .top, of: linkButtonContainer) // linkButton.pin(.top, to: .top, of: linkButtonContainer)
linkButtonContainer.pin(.trailing, to: .trailing, of: linkButton, withInset: Values.massiveSpacing) // linkButtonContainer.pin(.trailing, to: .trailing, of: linkButton, withInset: Values.massiveSpacing)
linkButtonContainer.pin(.bottom, to: .bottom, of: linkButton, withInset: isIPhone5OrSmaller ? 6 : 10) // linkButtonContainer.pin(.bottom, to: .bottom, of: linkButton, withInset: isIPhone5OrSmaller ? 6 : 10)
// Set up button stack view // Set up button stack view
let buttonStackView = UIStackView(arrangedSubviews: [ registerButton, restoreButton ]) let buttonStackView = UIStackView(arrangedSubviews: [ registerButton, restoreButton ])
buttonStackView.axis = .vertical buttonStackView.axis = .vertical

View File

@ -0,0 +1,93 @@
import PromiseKit
final class MultiDeviceRemovalSheet : Sheet {
private lazy var removalDate: Date = {
let calendar = Calendar(identifier: .gregorian)
let timezone = TimeZone(identifier: "Australia/Melbourne")
let components = DateComponents(calendar: calendar, timeZone: timezone, year: 2020, month: 8, day: 6, hour: 17)
return calendar.date(from: components)!
}()
private lazy var removalDateDescription: String = {
let formatter = DateFormatter()
formatter.dateFormat = "MMMM d"
return formatter.string(from: removalDate)
}()
private lazy var explanation: String = {
if UserDefaults.standard[.masterHexEncodedPublicKey] != nil {
let format = """
Youre seeing this because this is a secondary device in a multi-device setup. To improve reliability and stability, weve decided to temporarily disable Sessions multi-device functionality. Device linking has been disabled, and existing secondary clients will be erased on %@.
To read more about this change, visit the Session FAQ at getsession.org/faq.
"""
return String(format: format, removalDateDescription)
} else {
let format = """
Youre seeing this because you have a secondary device linked to your Session ID. To improve reliability and stability, weve decided to temporarily disable Sessions multi-device functionality. Device linking has been disabled, and existing secondary clients will be erased on %@.
To read more about this change, visit the Session FAQ at getsession.org/faq
"""
return String(format: format, removalDateDescription)
}
}()
private lazy var attributedExplanation: NSAttributedString = {
let result = NSMutableAttributedString(string: explanation)
result.addAttribute(.font, value: UIFont.boldSystemFont(ofSize: Values.smallFontSize), range: (explanation as NSString).range(of: removalDateDescription))
result.addAttribute(.foregroundColor, value: Colors.accent, range: (explanation as NSString).range(of: removalDateDescription))
result.addAttribute(.font, value: UIFont.boldSystemFont(ofSize: Values.smallFontSize), range: (explanation as NSString).range(of: "getsession.org/faq"))
result.addAttribute(.foregroundColor, value: Colors.accent, range: (explanation as NSString).range(of: "getsession.org/faq"))
return result
}()
private lazy var explanationLabel: UILabel = {
let result = UILabel()
result.textColor = Colors.text
result.font = .systemFont(ofSize: Values.smallFontSize)
result.attributedText = attributedExplanation
result.numberOfLines = 0
result.lineBreakMode = .byWordWrapping
return result
}()
override func populateContentView() {
// Set up title label
let titleLabel = UILabel()
titleLabel.textColor = Colors.text
titleLabel.font = .boldSystemFont(ofSize: isIPhone5OrSmaller ? Values.largeFontSize : Values.veryLargeFontSize)
titleLabel.text = "Changes to Multi-Device"
titleLabel.numberOfLines = 0
titleLabel.lineBreakMode = .byWordWrapping
// Set up explanation label
explanationLabel.isUserInteractionEnabled = true
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleExplanationLabelTapped))
explanationLabel.addGestureRecognizer(tapGestureRecognizer)
// Set up OK button
let okButton = Button(style: .prominentOutline, size: .large)
okButton.set(.width, to: 240)
okButton.setTitle(NSLocalizedString("OK", comment: ""), for: UIControl.State.normal)
okButton.addTarget(self, action: #selector(close), for: UIControl.Event.touchUpInside)
// Set up main stack view
let stackView = UIStackView(arrangedSubviews: [ titleLabel, explanationLabel, okButton ])
stackView.axis = .vertical
stackView.spacing = Values.veryLargeSpacing
stackView.alignment = .center
// Set up constraints
contentView.addSubview(stackView)
stackView.pin(.leading, to: .leading, of: contentView, withInset: Values.veryLargeSpacing)
stackView.pin(.top, to: .top, of: contentView, withInset: Values.largeSpacing)
contentView.pin(.trailing, to: .trailing, of: stackView, withInset: Values.veryLargeSpacing)
contentView.pin(.bottom, to: .bottom, of: stackView, withInset: Values.veryLargeSpacing + overshoot)
}
@objc private func handleExplanationLabelTapped(_ tapGestureRecognizer: UITapGestureRecognizer) {
let range = (explanationLabel.text! as NSString).range(of: "getsession.org/faq")
let touchInExplanationLabelCoordinates = tapGestureRecognizer.location(in: explanationLabel)
let characterIndex = explanationLabel.characterIndex(for: touchInExplanationLabelCoordinates)
guard range.contains(characterIndex) else { return }
let url = URL(string: "https://getsession.org/faq")!
UIApplication.shared.open(url)
}
}

View File

@ -1,89 +0,0 @@
import PromiseKit
final class PNModeSheet : Sheet, OptionViewDelegate {
private var optionViews: [OptionView] {
[ apnsOptionView, backgroundPollingOptionView ]
}
private var selectedOptionView: OptionView? {
return optionViews.first { $0.isSelected }
}
// MARK: Components
private lazy var apnsOptionView = OptionView(title: NSLocalizedString("Apple Push Notification Service", comment: ""), explanation: NSLocalizedString("Session will use the Apple Push Notification service to receive push notifications. You'll be notified of new messages reliably and immediately. Using APNs means that your IP address and device token will be exposed to Apple. If you use push notifications for other apps, this will already be the case. Your IP address and device token will also be exposed to Loki, but your messages will still be onion-routed and end-to-end encrypted, so the contents of your messages will remain completely private.", comment: ""), delegate: self, isRecommended: true)
private lazy var backgroundPollingOptionView = OptionView(title: NSLocalizedString("Background Polling", comment: ""), explanation: NSLocalizedString("Session will occasionally check for new messages in the background. This guarantees full metadata protection, but message notifications may be significantly delayed.", comment: ""), delegate: self)
// MARK: Lifecycle
override func populateContentView() {
// Set up title label
let titleLabel = UILabel()
titleLabel.textColor = Colors.text
titleLabel.font = .boldSystemFont(ofSize: isIPhone5OrSmaller ? Values.largeFontSize : Values.veryLargeFontSize)
titleLabel.text = NSLocalizedString("Push Notifications", comment: "")
titleLabel.numberOfLines = 0
titleLabel.lineBreakMode = .byWordWrapping
// Set up explanation label
let explanationLabel = UILabel()
explanationLabel.textColor = Colors.text
explanationLabel.font = .systemFont(ofSize: Values.smallFontSize)
explanationLabel.text = NSLocalizedString("Session now features two ways to handle push notifications. Make sure to read the descriptions carefully before you choose.", comment: "")
explanationLabel.numberOfLines = 0
explanationLabel.lineBreakMode = .byWordWrapping
// Set up options stack view
let optionsStackView = UIStackView(arrangedSubviews: optionViews)
optionsStackView.axis = .vertical
optionsStackView.spacing = Values.smallSpacing
optionsStackView.alignment = .fill
// Set up confirm button
let confirmButton = Button(style: .prominentOutline, size: .medium)
confirmButton.set(.width, to: 240)
confirmButton.setTitle(NSLocalizedString("Confirm", comment: ""), for: UIControl.State.normal)
confirmButton.addTarget(self, action: #selector(confirm), for: UIControl.Event.touchUpInside)
// Set up dismiss button
let skipButton = Button(style: .regular, size: .medium)
skipButton.set(.width, to: 240)
skipButton.setTitle(NSLocalizedString("Skip", comment: ""), for: UIControl.State.normal)
skipButton.addTarget(self, action: #selector(close), for: UIControl.Event.touchUpInside)
// Set up button stack view
let bottomStackView = UIStackView(arrangedSubviews: [ confirmButton, skipButton ])
bottomStackView.axis = .vertical
bottomStackView.spacing = isIPhone5OrSmaller ? Values.smallSpacing : Values.mediumSpacing
bottomStackView.alignment = .fill
// Set up main stack view
let stackView = UIStackView(arrangedSubviews: [ titleLabel, explanationLabel, optionsStackView, bottomStackView ])
stackView.axis = .vertical
stackView.spacing = isIPhone5OrSmaller ? 12 : Values.largeSpacing
stackView.alignment = .center
// Set up constraints
contentView.addSubview(stackView)
stackView.pin(.leading, to: .leading, of: contentView, withInset: isIPhone5OrSmaller ? Values.mediumSpacing : Values.largeSpacing)
stackView.pin(.top, to: .top, of: contentView, withInset: isIPhone5OrSmaller ? Values.mediumSpacing : Values.largeSpacing)
contentView.pin(.trailing, to: .trailing, of: stackView, withInset: isIPhone5OrSmaller ? Values.mediumSpacing : Values.largeSpacing)
contentView.pin(.bottom, to: .bottom, of: stackView, withInset: (isIPhone5OrSmaller ? Values.mediumSpacing : Values.veryLargeSpacing) + overshoot)
}
// MARK: Interaction
func optionViewDidActivate(_ optionView: OptionView) {
optionViews.filter { $0 != optionView }.forEach { $0.isSelected = false }
}
@objc private func confirm() {
guard selectedOptionView != nil else {
let title = NSLocalizedString("Please Pick an Option", comment: "")
let alert = UIAlertController(title: title, message: nil, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .default, handler: nil))
return present(alert, animated: true, completion: nil)
}
UserDefaults.standard[.isUsingFullAPNs] = (selectedOptionView == apnsOptionView)
let syncTokensJob = SyncPushTokensJob(accountManager: AppEnvironment.shared.accountManager, preferences: Environment.shared.preferences)
syncTokensJob.uploadOnlyIfStale = false
let _: Promise<Void> = syncTokensJob.run()
close()
}
override func close() {
UserDefaults.standard[.hasSeenPNModeSheet] = true
super.close()
}
}

View File

@ -89,7 +89,7 @@ final class PNModeVC : BaseVC, OptionViewDelegate {
return present(alert, animated: true, completion: nil) return present(alert, animated: true, completion: nil)
} }
UserDefaults.standard[.isUsingFullAPNs] = (selectedOptionView == apnsOptionView) UserDefaults.standard[.isUsingFullAPNs] = (selectedOptionView == apnsOptionView)
UserDefaults.standard[.hasSeenPNModeSheet] = true // Shouldn't be shown to users who've done the new onboarding UserDefaults.standard[.hasSeenMultiDeviceRemovalSheet] = true
TSAccountManager.sharedInstance().didRegister() TSAccountManager.sharedInstance().didRegister()
let homeVC = HomeVC() let homeVC = HomeVC()
navigationController!.setViewControllers([ homeVC ], animated: true) navigationController!.setViewControllers([ homeVC ], animated: true)

View File

@ -167,8 +167,8 @@ final class SettingsVC : BaseVC, AvatarViewHelperDelegate {
] ]
let isMasterDevice = UserDefaults.standard.isMasterDevice let isMasterDevice = UserDefaults.standard.isMasterDevice
if isMasterDevice { if isMasterDevice {
result.append(getSeparator()) // result.append(getSeparator())
result.append(getSettingButton(withTitle: NSLocalizedString("vc_settings_devices_button_title", comment: ""), color: Colors.text, action: #selector(showLinkedDevices))) // result.append(getSettingButton(withTitle: NSLocalizedString("vc_settings_devices_button_title", comment: ""), color: Colors.text, action: #selector(showLinkedDevices)))
result.append(getSeparator()) result.append(getSeparator())
result.append(getSettingButton(withTitle: NSLocalizedString("vc_settings_recovery_phrase_button_title", comment: ""), color: Colors.text, action: #selector(showSeed))) result.append(getSettingButton(withTitle: NSLocalizedString("vc_settings_recovery_phrase_button_title", comment: ""), color: Colors.text, action: #selector(showSeed)))
} }

View File

@ -157,7 +157,6 @@ NSString *const ReportedApplicationStateDidChangeNotification = @"ReportedApplic
- (BOOL)isMainAppAndActive - (BOOL)isMainAppAndActive
{ {
if (![NSThread isMainThread]) { return NO; }
return [UIApplication sharedApplication].applicationState == UIApplicationStateActive; return [UIApplication sharedApplication].applicationState == UIApplicationStateActive;
} }

View File

@ -5,8 +5,8 @@ public enum LKUserDefaults {
public enum Bool : Swift.String { public enum Bool : Swift.String {
case hasLaunchedOnce case hasLaunchedOnce
case hasSeenGIFMetadataWarning case hasSeenGIFMetadataWarning
case hasSeenMultiDeviceRemovalSheet
case hasSeenOpenGroupSuggestionSheet case hasSeenOpenGroupSuggestionSheet
case hasSeenPNModeSheet
case hasViewedSeed case hasViewedSeed
/// Whether the device was unlinked as a slave device (used to notify the user on the landing screen). /// Whether the device was unlinked as a slave device (used to notify the user on the landing screen).
case wasUnlinked case wasUnlinked