Reduce code duplication, clean & fix path re-building bug

pull/200/head
nielsandriesse 5 years ago
parent faa1a37f81
commit 991c6eb477

@ -134,14 +134,14 @@ final class ConversationCell : UITableViewCell {
// MARK: Updating // MARK: Updating
private func update() { private func update() {
MentionsManager.populateUserHexEncodedPublicKeyCacheIfNeeded(for: threadViewModel.threadRecord.uniqueId!) // FIXME: This is a terrible place to do this MentionsManager.populateUserPublicKeyCacheIfNeeded(for: threadViewModel.threadRecord.uniqueId!) // FIXME: This is a terrible place to do this
unreadMessagesIndicatorView.alpha = threadViewModel.hasUnreadMessages ? 1 : 0.0001 // Setting the alpha to exactly 0 causes an issue on iOS 12 unreadMessagesIndicatorView.alpha = threadViewModel.hasUnreadMessages ? 1 : 0.0001 // Setting the alpha to exactly 0 causes an issue on iOS 12
if threadViewModel.isGroupThread { if threadViewModel.isGroupThread {
if threadViewModel.name == "Session Public Chat" { if threadViewModel.name == "Session Public Chat" {
profilePictureView.hexEncodedPublicKey = "" profilePictureView.hexEncodedPublicKey = ""
profilePictureView.isRSSFeed = true profilePictureView.isRSSFeed = true
} else { } else {
var users = MentionsManager.userHexEncodedPublicKeyCache[threadViewModel.threadRecord.uniqueId!] ?? [] var users = MentionsManager.userPublicKeyCache[threadViewModel.threadRecord.uniqueId!] ?? []
users.remove(getUserHexEncodedPublicKey()) users.remove(getUserHexEncodedPublicKey())
let randomUsers = users.sorted().prefix(2) // Sort to provide a level of stability let randomUsers = users.sorted().prefix(2) // Sort to provide a level of stability
if !randomUsers.isEmpty { if !randomUsers.isEmpty {

@ -18,7 +18,7 @@ public final class MentionUtilities : NSObject {
} }
var string = string var string = string
let regex = try! NSRegularExpression(pattern: "@[0-9a-fA-F]*", options: []) let regex = try! NSRegularExpression(pattern: "@[0-9a-fA-F]*", options: [])
let knownHexEncodedPublicKeys = MentionsManager.userHexEncodedPublicKeyCache[threadID] ?? [] // Should always be populated at this point let knownHexEncodedPublicKeys = MentionsManager.userPublicKeyCache[threadID] ?? [] // Should always be populated at this point
var mentions: [(range: NSRange, hexEncodedPublicKey: String)] = [] var mentions: [(range: NSRange, hexEncodedPublicKey: String)] = []
var outerMatch = regex.firstMatch(in: string, options: .withoutAnchoringBounds, range: NSRange(location: 0, length: string.count)) var outerMatch = regex.firstMatch(in: string, options: .withoutAnchoringBounds, range: NSRange(location: 0, length: string.count))
while let match = outerMatch { while let match = outerMatch {

@ -8,6 +8,37 @@ class BaseVC : UIViewController {
NotificationCenter.default.addObserver(self, selector: #selector(handleUnexpectedDeviceLinkRequestReceivedNotification), name: .unexpectedDeviceLinkRequestReceived, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(handleUnexpectedDeviceLinkRequestReceivedNotification), name: .unexpectedDeviceLinkRequestReceived, object: nil)
} }
internal func setUpGradientBackground() {
view.backgroundColor = .clear
let gradient = Gradients.defaultLokiBackground
view.setGradient(gradient)
}
internal func setUpNavBarStyle() {
let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
}
internal func setNavBarTitle(_ title: String, customFontSize: CGFloat? = nil) {
let titleLabel = UILabel()
titleLabel.text = title
titleLabel.textColor = Colors.text
titleLabel.font = .boldSystemFont(ofSize: customFontSize ?? Values.veryLargeFontSize)
navigationItem.titleView = titleLabel
}
internal func setUpNavBarSessionIcon() {
let logoImageView = UIImageView()
logoImageView.image = #imageLiteral(resourceName: "SessionGreen32")
logoImageView.contentMode = .scaleAspectFit
logoImageView.set(.width, to: 32)
logoImageView.set(.height, to: 32)
navigationItem.titleView = logoImageView
}
deinit { deinit {
NotificationCenter.default.removeObserver(self) NotificationCenter.default.removeObserver(self)
} }

@ -38,22 +38,9 @@ final class DeviceLinksVC : BaseVC, UITableViewDataSource, UITableViewDelegate,
// MARK: Lifecycle // MARK: Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear setUpNavBarStyle()
let gradient = Gradients.defaultLokiBackground setNavBarTitle(NSLocalizedString("Devices", comment: ""))
view.setGradient(gradient)
// Set navigation bar background color
let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Customize title
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("Devices", comment: "")
titleLabel.textColor = Colors.text
titleLabel.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
navigationItem.titleView = titleLabel
// Set up link new device button // Set up link new device button
let linkNewDeviceButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(linkNewDevice)) let linkNewDeviceButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(linkNewDevice))
linkNewDeviceButton.tintColor = Colors.text linkNewDeviceButton.tintColor = Colors.text

@ -15,23 +15,9 @@ final class DisplayNameVC : BaseVC {
// MARK: Lifecycle // MARK: Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear setUpNavBarStyle()
let gradient = Gradients.defaultLokiBackground setUpNavBarSessionIcon()
view.setGradient(gradient)
// Set up navigation bar
let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Set up logo image view
let logoImageView = UIImageView()
logoImageView.image = #imageLiteral(resourceName: "SessionGreen32")
logoImageView.contentMode = .scaleAspectFit
logoImageView.set(.width, to: 32)
logoImageView.set(.height, to: 32)
navigationItem.titleView = logoImageView
// Set up title label // Set up title label
let titleLabel = UILabel() let titleLabel = UILabel()
titleLabel.textColor = Colors.text titleLabel.textColor = Colors.text

@ -33,22 +33,9 @@ final class GroupMembersVC : BaseVC, UITableViewDataSource {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear setUpNavBarStyle()
let gradient = Gradients.defaultLokiBackground setNavBarTitle(NSLocalizedString("Group Members", comment: ""))
view.setGradient(gradient)
// Set navigation bar background color
let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Customize title
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("Group Members", comment: "")
titleLabel.textColor = Colors.text
titleLabel.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
navigationItem.titleView = titleLabel
// Set up explanation label // Set up explanation label
let explanationLabel = UILabel() let explanationLabel = UILabel()
explanationLabel.textColor = Colors.text.withAlphaComponent(Values.unimportantElementOpacity) explanationLabel.textColor = Colors.text.withAlphaComponent(Values.unimportantElementOpacity)

@ -85,25 +85,12 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
SignalApp.shared().homeViewController = self SignalApp.shared().homeViewController = self
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear if navigationController?.navigationBar != nil {
let gradient = Gradients.defaultLokiBackground setUpNavBarStyle()
view.setGradient(gradient)
// Set navigation bar background color
if let navigationBar = navigationController?.navigationBar {
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
} }
// Set up navigation bar buttons
updateNavigationBarButtons() updateNavigationBarButtons()
// Customize title setNavBarTitle(NSLocalizedString("Messages", comment: ""))
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("Messages", comment: "")
titleLabel.textColor = Colors.text
titleLabel.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
navigationItem.titleView = titleLabel
// Set up seed reminder view if needed // Set up seed reminder view if needed
let userDefaults = UserDefaults.standard let userDefaults = UserDefaults.standard
let hasViewedSeed = userDefaults[.hasViewedSeed] let hasViewedSeed = userDefaults[.hasViewedSeed]

@ -42,26 +42,14 @@ final class JoinPublicChatVC : BaseVC, UIPageViewControllerDataSource, UIPageVie
// MARK: Lifecycle // MARK: Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear setUpNavBarStyle()
let gradient = Gradients.defaultLokiBackground setNavBarTitle(NSLocalizedString("Join Open Group", comment: ""))
view.setGradient(gradient)
// Set navigation bar background color
let navigationBar = navigationController!.navigationBar let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Set up navigation bar buttons // Set up navigation bar buttons
let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close)) let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close))
closeButton.tintColor = Colors.text closeButton.tintColor = Colors.text
navigationItem.leftBarButtonItem = closeButton navigationItem.leftBarButtonItem = closeButton
// Customize title
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("Join Open Group", comment: "")
titleLabel.textColor = Colors.text
titleLabel.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
navigationItem.titleView = titleLabel
// Set up page VC // Set up page VC
let hasCameraAccess = (AVCaptureDevice.authorizationStatus(for: .video) == .authorized) let hasCameraAccess = (AVCaptureDevice.authorizationStatus(for: .video) == .authorized)
pages = [ enterChatURLVC, (hasCameraAccess ? scanQRCodeWrapperVC : scanQRCodePlaceholderVC) ] pages = [ enterChatURLVC, (hasCameraAccess ? scanQRCodeWrapperVC : scanQRCodePlaceholderVC) ]

@ -36,23 +36,9 @@ final class LandingVC : BaseVC, LinkDeviceVCDelegate, DeviceLinkingModalDelegate
// MARK: Lifecycle // MARK: Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear setUpNavBarStyle()
let gradient = Gradients.defaultLokiBackground setUpNavBarSessionIcon()
view.setGradient(gradient)
// Set up navigation bar
let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Set up logo image view
let logoImageView = UIImageView()
logoImageView.image = #imageLiteral(resourceName: "SessionGreen32")
logoImageView.contentMode = .scaleAspectFit
logoImageView.set(.width, to: 32)
logoImageView.set(.height, to: 32)
navigationItem.titleView = logoImageView
// Set up title label // Set up title label
let titleLabel = UILabel() let titleLabel = UILabel()
titleLabel.textColor = Colors.text titleLabel.textColor = Colors.text

@ -42,26 +42,14 @@ final class LinkDeviceVC : BaseVC, UIPageViewControllerDataSource, UIPageViewCon
// MARK: Lifecycle // MARK: Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear setUpNavBarStyle()
let gradient = Gradients.defaultLokiBackground setNavBarTitle(NSLocalizedString("Link Device", comment: ""))
view.setGradient(gradient)
// Set navigation bar background color
let navigationBar = navigationController!.navigationBar let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Set up navigation bar buttons // Set up navigation bar buttons
let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close)) let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close))
closeButton.tintColor = Colors.text closeButton.tintColor = Colors.text
navigationItem.leftBarButtonItem = closeButton navigationItem.leftBarButtonItem = closeButton
// Customize title
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("Link Device", comment: "")
titleLabel.textColor = Colors.text
titleLabel.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
navigationItem.titleView = titleLabel
// Set up page VC // Set up page VC
let hasCameraAccess = (AVCaptureDevice.authorizationStatus(for: .video) == .authorized) let hasCameraAccess = (AVCaptureDevice.authorizationStatus(for: .video) == .authorized)
pages = [ enterPublicKeyVC, (hasCameraAccess ? scanQRCodeWrapperVC : scanQRCodePlaceholderVC) ] pages = [ enterPublicKeyVC, (hasCameraAccess ? scanQRCodeWrapperVC : scanQRCodePlaceholderVC) ]

@ -45,16 +45,9 @@ final class NewClosedGroupVC : BaseVC, UITableViewDataSource, UITableViewDelegat
// MARK: Lifecycle // MARK: Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear setUpNavBarStyle()
let gradient = Gradients.defaultLokiBackground setNavBarTitle(NSLocalizedString("New Closed Group", comment: ""))
view.setGradient(gradient)
// Set navigation bar background color
let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Set up navigation bar buttons // Set up navigation bar buttons
let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close)) let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close))
closeButton.tintColor = Colors.text closeButton.tintColor = Colors.text
@ -62,13 +55,6 @@ final class NewClosedGroupVC : BaseVC, UITableViewDataSource, UITableViewDelegat
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(createClosedGroup)) let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(createClosedGroup))
doneButton.tintColor = Colors.text doneButton.tintColor = Colors.text
navigationItem.rightBarButtonItem = doneButton navigationItem.rightBarButtonItem = doneButton
// Customize title
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("New Closed Group", comment: "")
titleLabel.textColor = Colors.text
let titleLabelFontSize = isSmallScreen ? Values.mediumFontSize : Values.largeFontSize
titleLabel.font = .boldSystemFont(ofSize: titleLabelFontSize)
navigationItem.titleView = titleLabel
// Set up content // Set up content
if !contacts.isEmpty { if !contacts.isEmpty {
view.addSubview(nameTextField) view.addSubview(nameTextField)

@ -41,26 +41,14 @@ final class NewPrivateChatVC : BaseVC, UIPageViewControllerDataSource, UIPageVie
// MARK: Lifecycle // MARK: Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear setUpNavBarStyle()
let gradient = Gradients.defaultLokiBackground setNavBarTitle(NSLocalizedString("New Session", comment: ""))
view.setGradient(gradient)
// Set navigation bar background color
let navigationBar = navigationController!.navigationBar let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Set up navigation bar buttons // Set up navigation bar buttons
let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close)) let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close))
closeButton.tintColor = Colors.text closeButton.tintColor = Colors.text
navigationItem.leftBarButtonItem = closeButton navigationItem.leftBarButtonItem = closeButton
// Customize title
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("New Session", comment: "")
titleLabel.textColor = Colors.text
titleLabel.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
navigationItem.titleView = titleLabel
// Set up page VC // Set up page VC
let hasCameraAccess = (AVCaptureDevice.authorizationStatus(for: .video) == .authorized) let hasCameraAccess = (AVCaptureDevice.authorizationStatus(for: .video) == .authorized)
pages = [ enterPublicKeyVC, (hasCameraAccess ? scanQRCodeWrapperVC : scanQRCodePlaceholderVC) ] pages = [ enterPublicKeyVC, (hasCameraAccess ? scanQRCodeWrapperVC : scanQRCodePlaceholderVC) ]

@ -17,23 +17,9 @@ final class PNModeVC : BaseVC, OptionViewDelegate {
// MARK: Lifecycle // MARK: Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear setUpNavBarStyle()
let gradient = Gradients.defaultLokiBackground setUpNavBarSessionIcon()
view.setGradient(gradient)
// Set up navigation bar
let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Set up logo image view
let logoImageView = UIImageView()
logoImageView.image = #imageLiteral(resourceName: "SessionGreen32")
logoImageView.contentMode = .scaleAspectFit
logoImageView.set(.width, to: 32)
logoImageView.set(.height, to: 32)
navigationItem.titleView = logoImageView
// Set up title label // Set up title label
let titleLabel = UILabel() let titleLabel = UILabel()
titleLabel.textColor = Colors.text titleLabel.textColor = Colors.text

@ -26,25 +26,15 @@ final class PathVC : BaseVC {
// MARK: Lifecycle // MARK: Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
setUpBackground() setUpGradientBackground()
setUpNavBar() setUpNavBar()
setUpViewHierarchy() setUpViewHierarchy()
registerObservers() registerObservers()
} }
private func setUpBackground() {
view.backgroundColor = .clear
let gradient = Gradients.defaultLokiBackground
view.setGradient(gradient)
}
private func setUpNavBar() { private func setUpNavBar() {
// Set up navigation bar style setUpNavBarStyle()
let navigationBar = navigationController!.navigationBar setNavBarTitle(NSLocalizedString("Path", comment: ""))
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Set up close button // Set up close button
let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close)) let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close))
closeButton.tintColor = Colors.text closeButton.tintColor = Colors.text
@ -52,12 +42,6 @@ final class PathVC : BaseVC {
let learnMoreButton = UIBarButtonItem(image: #imageLiteral(resourceName: "QuestionMark").scaled(to: CGSize(width: 24, height: 24)), style: .plain, target: self, action: #selector(learnMore)) let learnMoreButton = UIBarButtonItem(image: #imageLiteral(resourceName: "QuestionMark").scaled(to: CGSize(width: 24, height: 24)), style: .plain, target: self, action: #selector(learnMore))
learnMoreButton.tintColor = Colors.text learnMoreButton.tintColor = Colors.text
navigationItem.rightBarButtonItem = learnMoreButton navigationItem.rightBarButtonItem = learnMoreButton
// Customize title
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("Path", comment: "")
titleLabel.textColor = Colors.text
titleLabel.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
navigationItem.titleView = titleLabel
} }
private func setUpViewHierarchy() { private func setUpViewHierarchy() {
@ -200,6 +184,13 @@ final class PathVC : BaseVC {
} }
@objc private func rebuildPath() { @objc private func rebuildPath() {
// Dispatch async on the main queue to avoid nested write transactions
DispatchQueue.main.async {
let storage = OWSPrimaryStorage.shared()
storage.dbReadWriteConnection.readWrite { transaction in
storage.clearOnionRequestPaths(in: transaction)
}
}
OnionRequestAPI.guardSnodes = [] OnionRequestAPI.guardSnodes = []
OnionRequestAPI.paths = [] OnionRequestAPI.paths = []
let _ = OnionRequestAPI.buildPaths() let _ = OnionRequestAPI.buildPaths()

@ -42,22 +42,10 @@ final class QRCodeVC : BaseVC, UIPageViewControllerDataSource, UIPageViewControl
// MARK: Lifecycle // MARK: Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear setUpNavBarStyle()
let gradient = Gradients.defaultLokiBackground setNavBarTitle(NSLocalizedString("QR Code", comment: ""))
view.setGradient(gradient)
// Set navigation bar background color
let navigationBar = navigationController!.navigationBar let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Customize title
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("QR Code", comment: "")
titleLabel.textColor = Colors.text
titleLabel.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
navigationItem.titleView = titleLabel
// Set up page VC // Set up page VC
let hasCameraAccess = (AVCaptureDevice.authorizationStatus(for: .video) == .authorized) let hasCameraAccess = (AVCaptureDevice.authorizationStatus(for: .video) == .authorized)
pages = [ viewMyQRCodeVC, (hasCameraAccess ? scanQRCodeWrapperVC : scanQRCodePlaceholderVC) ] pages = [ viewMyQRCodeVC, (hasCameraAccess ? scanQRCodeWrapperVC : scanQRCodePlaceholderVC) ]

@ -40,23 +40,9 @@ final class RegisterVC : BaseVC {
// MARK: Lifecycle // MARK: Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear setUpNavBarStyle()
let gradient = Gradients.defaultLokiBackground setUpNavBarSessionIcon()
view.setGradient(gradient)
// Set up navigation bar
let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Set up logo image view
let logoImageView = UIImageView()
logoImageView.image = #imageLiteral(resourceName: "SessionGreen32")
logoImageView.contentMode = .scaleAspectFit
logoImageView.set(.width, to: 32)
logoImageView.set(.height, to: 32)
navigationItem.titleView = logoImageView
// Set up title label // Set up title label
let titleLabel = UILabel() let titleLabel = UILabel()
titleLabel.textColor = Colors.text titleLabel.textColor = Colors.text

@ -32,23 +32,9 @@ final class RestoreVC : BaseVC {
// MARK: Lifecycle // MARK: Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear setUpNavBarStyle()
let gradient = Gradients.defaultLokiBackground setUpNavBarSessionIcon()
view.setGradient(gradient)
// Set up navigation bar
let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Set up logo image view
let logoImageView = UIImageView()
logoImageView.image = #imageLiteral(resourceName: "SessionGreen32")
logoImageView.contentMode = .scaleAspectFit
logoImageView.set(.width, to: 32)
logoImageView.set(.height, to: 32)
navigationItem.titleView = logoImageView
// Set up title label // Set up title label
let titleLabel = UILabel() let titleLabel = UILabel()
titleLabel.textColor = Colors.text titleLabel.textColor = Colors.text

@ -28,10 +28,7 @@ final class ScanQRCodeWrapperVC : BaseVC {
if isPresentedModally { if isPresentedModally {
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .stop, target: self, action: #selector(close)) navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .stop, target: self, action: #selector(close))
} }
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear
let gradient = Gradients.defaultLokiBackground
view.setGradient(gradient)
// Set up scan QR code VC // Set up scan QR code VC
scanQRCodeVC.scanDelegate = delegate scanQRCodeVC.scanDelegate = delegate
let scanQRCodeVCView = scanQRCodeVC.view! let scanQRCodeVCView = scanQRCodeVC.view!

@ -55,23 +55,9 @@ final class SeedVC : BaseVC {
// MARK: Lifecycle // MARK: Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear setUpNavBarStyle()
let gradient = Gradients.defaultLokiBackground setNavBarTitle(NSLocalizedString("Your Recovery Phrase", comment: ""))
view.setGradient(gradient)
// Set up navigation bar
let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Customize title
let navigationBarTitleLabel = UILabel()
navigationBarTitleLabel.text = NSLocalizedString("Your Recovery Phrase", comment: "")
navigationBarTitleLabel.textColor = Colors.text
let titleLabelFontSize = isSmallScreen ? Values.largeFontSize : Values.veryLargeFontSize
navigationBarTitleLabel.font = .boldSystemFont(ofSize: titleLabelFontSize)
navigationItem.titleView = navigationBarTitleLabel
// Set up navigation bar buttons // Set up navigation bar buttons
let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close)) let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close))
closeButton.tintColor = Colors.text closeButton.tintColor = Colors.text

@ -53,27 +53,14 @@ final class SettingsVC : BaseVC, AvatarViewHelperDelegate {
// MARK: Lifecycle // MARK: Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// Set gradient background setUpGradientBackground()
view.backgroundColor = .clear setUpNavBarStyle()
let gradient = Gradients.defaultLokiBackground setNavBarTitle(NSLocalizedString("Settings", comment: ""))
view.setGradient(gradient)
// Set navigation bar background color
let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.shadowImage = UIImage()
navigationBar.isTranslucent = false
navigationBar.barTintColor = Colors.navigationBarBackground
// Set up navigation bar buttons // Set up navigation bar buttons
let backButton = UIBarButtonItem(title: NSLocalizedString("Back", comment: ""), style: .plain, target: nil, action: nil) let backButton = UIBarButtonItem(title: NSLocalizedString("Back", comment: ""), style: .plain, target: nil, action: nil)
backButton.tintColor = Colors.text backButton.tintColor = Colors.text
navigationItem.backBarButtonItem = backButton navigationItem.backBarButtonItem = backButton
updateNavigationBarButtons() updateNavigationBarButtons()
// Customize title
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("Settings", comment: "")
titleLabel.textColor = Colors.text
titleLabel.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
navigationItem.titleView = titleLabel
// Set up profile picture view // Set up profile picture view
let profilePictureTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(showEditProfilePictureUI)) let profilePictureTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(showEditProfilePictureUI))
profilePictureView.addGestureRecognizer(profilePictureTapGestureRecognizer) profilePictureView.addGestureRecognizer(profilePictureTapGestureRecognizer)

@ -605,7 +605,7 @@ typedef enum : NSUInteger {
userInfo:nil userInfo:nil
repeats:YES]; repeats:YES];
[LKMentionsManager populateUserHexEncodedPublicKeyCacheIfNeededFor:thread.uniqueId in:nil]; [LKMentionsManager populateUserPublicKeyCacheIfNeededFor:thread.uniqueId in:nil];
} }
- (void)dealloc - (void)dealloc

@ -395,7 +395,7 @@ NS_ASSUME_NONNULL_BEGIN
} }
NSString *displayableText = thread.lastMessageText; NSString *displayableText = thread.lastMessageText;
if (displayableText) { if (displayableText) {
[LKMentionsManager populateUserHexEncodedPublicKeyCacheIfNeededFor:thread.threadRecord.uniqueId in:nil]; // TODO: Terrible place to do this, but okay for now [LKMentionsManager populateUserPublicKeyCacheIfNeededFor:thread.threadRecord.uniqueId in:nil]; // TODO: Terrible place to do this, but okay for now
displayableText = [LKMentionUtilities highlightMentionsIn:displayableText threadID:thread.threadRecord.uniqueId]; displayableText = [LKMentionUtilities highlightMentionsIn:displayableText threadID:thread.threadRecord.uniqueId];
[snippetText appendAttributedString:[[NSAttributedString alloc] [snippetText appendAttributedString:[[NSAttributedString alloc]
initWithString:displayableText initWithString:displayableText

@ -213,7 +213,7 @@ const CGFloat kContactCellAvatarTextMargin = 12;
{ {
if (self.thread.isGroupThread) { if (self.thread.isGroupThread) {
NSMutableArray<NSString *> *sortedUsers = @[].mutableCopy; NSMutableArray<NSString *> *sortedUsers = @[].mutableCopy;
NSSet<NSString *> *users = LKMentionsManager.userHexEncodedPublicKeyCache[self.thread.uniqueId]; NSSet<NSString *> *users = LKMentionsManager.userPublicKeyCache[self.thread.uniqueId];
if (users != nil) { if (users != nil) {
for (NSString *user in users) { for (NSString *user in users) {
[sortedUsers addObject:user]; [sortedUsers addObject:user];

@ -15,7 +15,7 @@ public extension LokiAPI {
// MARK: Caching // MARK: Caching
internal static var swarmCache: [String:[LokiAPITarget]] = [:] internal static var swarmCache: [String:[LokiAPITarget]] = [:]
internal static func dropIfNeeded(_ target: LokiAPITarget, hexEncodedPublicKey: String) { internal static func dropSnodeIfNeeded(_ target: LokiAPITarget, hexEncodedPublicKey: String) {
let swarm = LokiAPI.swarmCache[hexEncodedPublicKey] let swarm = LokiAPI.swarmCache[hexEncodedPublicKey]
if var swarm = swarm, let index = swarm.firstIndex(of: target) { if var swarm = swarm, let index = swarm.firstIndex(of: target) {
swarm.remove(at: index) swarm.remove(at: index)
@ -175,7 +175,7 @@ internal extension Promise {
print("[Loki] Couldn't reach snode at: \(target); setting failure count to \(newFailureCount).") print("[Loki] Couldn't reach snode at: \(target); setting failure count to \(newFailureCount).")
if newFailureCount >= LokiAPI.failureThreshold { if newFailureCount >= LokiAPI.failureThreshold {
print("[Loki] Failure threshold reached for: \(target); dropping it.") print("[Loki] Failure threshold reached for: \(target); dropping it.")
LokiAPI.dropIfNeeded(target, hexEncodedPublicKey: hexEncodedPublicKey) // Remove it from the swarm cache associated with the given public key LokiAPI.dropSnodeIfNeeded(target, hexEncodedPublicKey: hexEncodedPublicKey) // Remove it from the swarm cache associated with the given public key
LokiAPI.snodePool.remove(target) // Remove it from the snode pool LokiAPI.snodePool.remove(target) // Remove it from the snode pool
// Dispatch async on the main queue to avoid nested write transactions // Dispatch async on the main queue to avoid nested write transactions
DispatchQueue.main.async { DispatchQueue.main.async {
@ -192,7 +192,7 @@ internal extension Promise {
case 421: case 421:
// The snode isn't associated with the given public key anymore // The snode isn't associated with the given public key anymore
print("[Loki] Invalidating swarm for: \(hexEncodedPublicKey).") print("[Loki] Invalidating swarm for: \(hexEncodedPublicKey).")
LokiAPI.dropIfNeeded(target, hexEncodedPublicKey: hexEncodedPublicKey) LokiAPI.dropSnodeIfNeeded(target, hexEncodedPublicKey: hexEncodedPublicKey)
case 432: case 432:
// The PoW difficulty is too low // The PoW difficulty is too low
if case LokiHTTPClient.HTTPError.networkError(_, let result, _) = error, let json = result as? JSON, let powDifficulty = json["difficulty"] as? Int { if case LokiHTTPClient.HTTPError.networkError(_, let result, _) = error, let json = result as? JSON, let powDifficulty = json["difficulty"] as? Int {

@ -84,7 +84,7 @@ public final class LokiPoller : NSObject {
self?.pollCount = 0 self?.pollCount = 0
} else { } else {
print("[Loki] Polling \(nextSnode) failed; dropping it and switching to next snode.") print("[Loki] Polling \(nextSnode) failed; dropping it and switching to next snode.")
LokiAPI.dropIfNeeded(nextSnode, hexEncodedPublicKey: userHexEncodedPublicKey) LokiAPI.dropSnodeIfNeeded(nextSnode, hexEncodedPublicKey: userHexEncodedPublicKey)
} }
self?.pollNextSnode(seal: seal) self?.pollNextSnode(seal: seal)
} }

@ -275,7 +275,7 @@ private extension Promise where T == JSON {
print("[Loki] Couldn't reach snode at: \(snode); setting failure count to \(newFailureCount).") print("[Loki] Couldn't reach snode at: \(snode); setting failure count to \(newFailureCount).")
if newFailureCount >= LokiAPI.failureThreshold { if newFailureCount >= LokiAPI.failureThreshold {
print("[Loki] Failure threshold reached for: \(snode); dropping it.") print("[Loki] Failure threshold reached for: \(snode); dropping it.")
LokiAPI.dropIfNeeded(snode, hexEncodedPublicKey: hexEncodedPublicKey) // Remove it from the swarm cache associated with the given public key LokiAPI.dropSnodeIfNeeded(snode, hexEncodedPublicKey: hexEncodedPublicKey) // Remove it from the swarm cache associated with the given public key
LokiAPI.snodePool.remove(snode) // Remove it from the snode pool LokiAPI.snodePool.remove(snode) // Remove it from the snode pool
// Dispatch async on the main queue to avoid nested write transactions // Dispatch async on the main queue to avoid nested write transactions
DispatchQueue.main.async { DispatchQueue.main.async {
@ -292,7 +292,7 @@ private extension Promise where T == JSON {
case 421: case 421:
// The snode isn't associated with the given public key anymore // The snode isn't associated with the given public key anymore
print("[Loki] Invalidating swarm for: \(hexEncodedPublicKey).") print("[Loki] Invalidating swarm for: \(hexEncodedPublicKey).")
LokiAPI.dropIfNeeded(snode, hexEncodedPublicKey: hexEncodedPublicKey) LokiAPI.dropSnodeIfNeeded(snode, hexEncodedPublicKey: hexEncodedPublicKey)
case 432: case 432:
// The proof of work difficulty is too low // The proof of work difficulty is too low
if let powDifficulty = json["difficulty"] as? Int { if let powDifficulty = json["difficulty"] as? Int {

@ -3,8 +3,8 @@
public final class LokiDatabaseUtilities : NSObject { public final class LokiDatabaseUtilities : NSObject {
private override init() { } private override init() { }
// MARK: Quotes // MARK: - Quotes
@objc(getServerIDForQuoteWithID:quoteeHexEncodedPublicKey:threadID:transaction:) @objc(getServerIDForQuoteWithID:quoteeHexEncodedPublicKey:threadID:transaction:)
public static func getServerID(quoteID: UInt64, quoteeHexEncodedPublicKey: String, threadID: String, transaction: YapDatabaseReadTransaction) -> UInt64 { public static func getServerID(quoteID: UInt64, quoteeHexEncodedPublicKey: String, threadID: String, transaction: YapDatabaseReadTransaction) -> UInt64 {
guard let message = TSInteraction.interactions(withTimestamp: quoteID, filter: { interaction in guard let message = TSInteraction.interactions(withTimestamp: quoteID, filter: { interaction in
@ -20,8 +20,10 @@ public final class LokiDatabaseUtilities : NSObject {
}, with: transaction).first as! TSMessage? else { return 0 } }, with: transaction).first as! TSMessage? else { return 0 }
return message.openGroupServerMessageID return message.openGroupServerMessageID
} }
// MARK: Device Links
// MARK: - Device Links
@objc(getLinkedDeviceHexEncodedPublicKeysFor:in:) @objc(getLinkedDeviceHexEncodedPublicKeysFor:in:)
public static func getLinkedDeviceHexEncodedPublicKeys(for hexEncodedPublicKey: String, in transaction: YapDatabaseReadTransaction) -> Set<String> { public static func getLinkedDeviceHexEncodedPublicKeys(for hexEncodedPublicKey: String, in transaction: YapDatabaseReadTransaction) -> Set<String> {
let storage = OWSPrimaryStorage.shared() let storage = OWSPrimaryStorage.shared()
@ -54,8 +56,10 @@ public final class LokiDatabaseUtilities : NSObject {
public static func objc_getDeviceLinks(for masterHexEncodedPublicKey: String, in transaction: YapDatabaseReadTransaction) -> Set<DeviceLink> { public static func objc_getDeviceLinks(for masterHexEncodedPublicKey: String, in transaction: YapDatabaseReadTransaction) -> Set<DeviceLink> {
return OWSPrimaryStorage.shared().getDeviceLinks(for: masterHexEncodedPublicKey, in: transaction) return OWSPrimaryStorage.shared().getDeviceLinks(for: masterHexEncodedPublicKey, in: transaction)
} }
// MARK: Public Chats
// MARK: - Open Groups
private static let publicChatCollection = "LokiPublicChatCollection" private static let publicChatCollection = "LokiPublicChatCollection"
@objc(getAllPublicChats:) @objc(getAllPublicChats:)

@ -4,7 +4,7 @@ public final class MentionsManager : NSObject {
private static var _userHexEncodedPublicKeyCache: [String:Set<String>] = [:] private static var _userHexEncodedPublicKeyCache: [String:Set<String>] = [:]
/// A mapping from thread ID to set of user hex encoded public keys. /// A mapping from thread ID to set of user hex encoded public keys.
@objc public static var userHexEncodedPublicKeyCache: [String:Set<String>] { @objc public static var userPublicKeyCache: [String:Set<String>] {
get { LokiAPI.stateQueue.sync { _userHexEncodedPublicKeyCache } } get { LokiAPI.stateQueue.sync { _userHexEncodedPublicKeyCache } }
set { LokiAPI.stateQueue.sync { _userHexEncodedPublicKeyCache = newValue } } set { LokiAPI.stateQueue.sync { _userHexEncodedPublicKeyCache = newValue } }
} }
@ -21,16 +21,16 @@ public final class MentionsManager : NSObject {
// MARK: Implementation // MARK: Implementation
@objc public static func cache(_ hexEncodedPublicKey: String, for threadID: String) { @objc public static func cache(_ hexEncodedPublicKey: String, for threadID: String) {
if let cache = userHexEncodedPublicKeyCache[threadID] { if let cache = userPublicKeyCache[threadID] {
userHexEncodedPublicKeyCache[threadID] = cache.union([ hexEncodedPublicKey ]) userPublicKeyCache[threadID] = cache.union([ hexEncodedPublicKey ])
} else { } else {
userHexEncodedPublicKeyCache[threadID] = [ hexEncodedPublicKey ] userPublicKeyCache[threadID] = [ hexEncodedPublicKey ]
} }
} }
@objc public static func getMentionCandidates(for query: String, in threadID: String) -> [Mention] { @objc public static func getMentionCandidates(for query: String, in threadID: String) -> [Mention] {
// Prepare // Prepare
guard let cache = userHexEncodedPublicKeyCache[threadID] else { return [] } guard let cache = userPublicKeyCache[threadID] else { return [] }
var candidates: [Mention] = [] var candidates: [Mention] = []
// Gather candidates // Gather candidates
var publicChat: LokiPublicChat? var publicChat: LokiPublicChat?
@ -65,14 +65,14 @@ public final class MentionsManager : NSObject {
return candidates return candidates
} }
@objc public static func populateUserHexEncodedPublicKeyCacheIfNeeded(for threadID: String, in transaction: YapDatabaseReadTransaction? = nil) { @objc public static func populateUserPublicKeyCacheIfNeeded(for threadID: String, in transaction: YapDatabaseReadTransaction? = nil) {
var result: Set<String> = [] var result: Set<String> = []
func populate(in transaction: YapDatabaseReadTransaction) { func populate(in transaction: YapDatabaseReadTransaction) {
guard let thread = TSThread.fetch(uniqueId: threadID, transaction: transaction) else { return } guard let thread = TSThread.fetch(uniqueId: threadID, transaction: transaction) else { return }
if let groupThread = thread as? TSGroupThread, groupThread.groupModel.groupType == .closedGroup { if let groupThread = thread as? TSGroupThread, groupThread.groupModel.groupType == .closedGroup {
result = result.union(groupThread.groupModel.groupMemberIds) result = result.union(groupThread.groupModel.groupMemberIds)
} else { } else {
guard userHexEncodedPublicKeyCache[threadID] == nil else { return } guard userPublicKeyCache[threadID] == nil else { return }
let interactions = transaction.ext(TSMessageDatabaseViewExtensionName) as! YapDatabaseViewTransaction let interactions = transaction.ext(TSMessageDatabaseViewExtensionName) as! YapDatabaseViewTransaction
interactions.enumerateKeysAndObjects(inGroup: threadID) { _, _, object, index, _ in interactions.enumerateKeysAndObjects(inGroup: threadID) { _, _, object, index, _ in
guard let message = object as? TSIncomingMessage, index < userIDScanLimit else { return } guard let message = object as? TSIncomingMessage, index < userIDScanLimit else { return }
@ -88,6 +88,6 @@ public final class MentionsManager : NSObject {
} }
} }
result.insert(getUserHexEncodedPublicKey()) result.insert(getUserHexEncodedPublicKey())
userHexEncodedPublicKeyCache[threadID] = result userPublicKeyCache[threadID] = result
} }
} }

@ -1466,7 +1466,7 @@ NS_ASSUME_NONNULL_BEGIN
// Loki: Cache the user hex encoded public key (for mentions) // Loki: Cache the user hex encoded public key (for mentions)
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { [self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
[LKMentionsManager populateUserHexEncodedPublicKeyCacheIfNeededFor:oldGroupThread.uniqueId in:transaction]; [LKMentionsManager populateUserPublicKeyCacheIfNeededFor:oldGroupThread.uniqueId in:transaction];
[LKMentionsManager cache:incomingMessage.authorId for:oldGroupThread.uniqueId]; [LKMentionsManager cache:incomingMessage.authorId for:oldGroupThread.uniqueId];
}]; }];
}); });

Loading…
Cancel
Save