diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index d4466f77c..d88236ef9 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -567,6 +567,8 @@ B821F2F82272CED3002C88C0 /* DisplayNameVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F72272CED3002C88C0 /* DisplayNameVC.swift */; }; B821F2FA2272CEEE002C88C0 /* SeedVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F92272CEEE002C88C0 /* SeedVC.swift */; }; B82584A02315024B001B41CB /* LokiRSSFeedPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */; }; + B82B40882399EB0E00A248E7 /* LandingVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B82B40872399EB0E00A248E7 /* LandingVC.swift */; }; + B82B408A2399EC0600A248E7 /* FakeChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B82B40892399EC0600A248E7 /* FakeChatView.swift */; }; B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; }; B84664F5235022F30083A1CD /* MentionUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84664F4235022F30083A1CD /* MentionUtilities.swift */; }; B86BD08423399ACF000F5AE3 /* Modal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08323399ACF000F5AE3 /* Modal.swift */; }; @@ -1397,6 +1399,8 @@ B821F2F72272CED3002C88C0 /* DisplayNameVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayNameVC.swift; sourceTree = ""; }; B821F2F92272CEEE002C88C0 /* SeedVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedVC.swift; sourceTree = ""; }; B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiRSSFeedPoller.swift; sourceTree = ""; }; + B82B40872399EB0E00A248E7 /* LandingVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandingVC.swift; sourceTree = ""; }; + B82B40892399EC0600A248E7 /* FakeChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeChatView.swift; sourceTree = ""; }; B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = ""; }; B84664F4235022F30083A1CD /* MentionUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MentionUtilities.swift; sourceTree = ""; }; B86BD08323399ACF000F5AE3 /* Modal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modal.swift; sourceTree = ""; }; @@ -2770,6 +2774,7 @@ children = ( B8B5BCEB2394D869003823C9 /* Button.swift */, B8BB82AA238F669C00BA5194 /* ConversationCell.swift */, + B82B40892399EC0600A248E7 /* FakeChatView.swift */, B8BB82AC238F734800BA5194 /* ProfilePictureView.swift */, B8BB82B02390C37000BA5194 /* SearchBar.swift */, B8BB82B82394911B00BA5194 /* Separator.swift */, @@ -2797,6 +2802,7 @@ B80C6B582384C4E700FDBC8B /* DeviceNameModal.swift */, B80C6B5A2384C7F900FDBC8B /* DeviceNameModalDelegate.swift */, B8BB82A4238F627000BA5194 /* HomeVC.swift */, + B82B40872399EB0E00A248E7 /* LandingVC.swift */, B86BD08323399ACF000F5AE3 /* Modal.swift */, B8CCF63623961D6D0091D419 /* NewPrivateChatVC.swift */, B894D0742339EDCF00B4D94D /* NukeDataModal.swift */, @@ -3846,8 +3852,10 @@ 34B6A907218B5241007C4606 /* TypingIndicatorCell.swift in Sources */, 4CFD151D22415AA400F2450F /* CallVideoHintView.swift in Sources */, 34D1F0AB1F867BFC0066283D /* OWSContactOffersCell.m in Sources */, + B82B408A2399EC0600A248E7 /* FakeChatView.swift in Sources */, B8BB82B92394911B00BA5194 /* Separator.swift in Sources */, 343A65981FC4CFE7000477A1 /* ConversationScrollButton.m in Sources */, + B82B40882399EB0E00A248E7 /* LandingVC.swift in Sources */, 34386A51207D0C01009F5D9C /* HomeViewController.m in Sources */, 34D1F0A91F867BFC0066283D /* ConversationViewCell.m in Sources */, 34A4C62022175C5C0042EF2E /* OnboardingProfileViewController.swift in Sources */, diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 5f11446e6..e6949262a 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -1422,7 +1422,7 @@ static NSTimeInterval launchStartedAt; } } else { rootViewController = [[OnboardingController new] initialViewController]; - navigationBarHidden = YES; + navigationBarHidden = NO; } OWSAssertDebug(rootViewController); OWSNavigationController *navigationController = diff --git a/Signal/src/Loki/Redesign/Components/Button.swift b/Signal/src/Loki/Redesign/Components/Button.swift index 5516c4a90..6f1e7011e 100644 --- a/Signal/src/Loki/Redesign/Components/Button.swift +++ b/Signal/src/Loki/Redesign/Components/Button.swift @@ -4,7 +4,7 @@ final class Button : UIButton { private let size: Size enum Style { - case unimportant, regular, prominent + case unimportant, regular, prominentOutline, prominentFilled } enum Size { @@ -31,19 +31,22 @@ final class Button : UIButton { switch style { case .unimportant: fillColor = Colors.unimportantButtonBackground case .regular: fillColor = UIColor.clear - case .prominent: fillColor = UIColor.clear + case .prominentOutline: fillColor = UIColor.clear + case .prominentFilled: fillColor = Colors.accent } let borderColor: UIColor switch style { case .unimportant: borderColor = Colors.unimportantButtonBackground case .regular: borderColor = Colors.text - case .prominent: borderColor = Colors.accent + case .prominentOutline: borderColor = Colors.accent + case .prominentFilled: borderColor = Colors.accent } let textColor: UIColor switch style { case .unimportant: textColor = Colors.text case .regular: textColor = Colors.text - case .prominent: textColor = Colors.accent + case .prominentOutline: textColor = Colors.accent + case .prominentFilled: textColor = Colors.text } let height: CGFloat switch size { diff --git a/Signal/src/Loki/Redesign/Components/FakeChatView.swift b/Signal/src/Loki/Redesign/Components/FakeChatView.swift new file mode 100644 index 000000000..64fdf6991 --- /dev/null +++ b/Signal/src/Loki/Redesign/Components/FakeChatView.swift @@ -0,0 +1,108 @@ + +final class FakeChatView : UIView { + private let spacing = Values.mediumSpacing + + private lazy var chatBubbles = [ + getChatBubble(withText: NSLocalizedString("What is Loki Messenger? A completely decentralised private messaging application for all platforms.", comment: ""), wasSentByCurrentUser: true), + getChatBubble(withText: NSLocalizedString("So no metadata collection, or personally identifiable information? How does it work?", comment: ""), wasSentByCurrentUser: false), + getChatBubble(withText: NSLocalizedString("Through a combination of advanced blockchain techniques including onion routing through Lokinet's private servers.", comment: ""), wasSentByCurrentUser: true), + getChatBubble(withText: NSLocalizedString("Friends don't let friends use compromised messengers. You're welcome.", comment: ""), wasSentByCurrentUser: true) + ] + + private lazy var scrollView: UIScrollView = { + let result = UIScrollView() + result.showsVerticalScrollIndicator = false + return result + }() + + override init(frame: CGRect) { + super.init(frame: frame) + setUpViewHierarchy() + animate() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + setUpViewHierarchy() + animate() + } + + private func setUpViewHierarchy() { + let stackView = UIStackView(arrangedSubviews: chatBubbles) + stackView.axis = .vertical + stackView.spacing = spacing + stackView.alignment = .fill + stackView.set(.width, to: UIScreen.main.bounds.width) + stackView.layoutMargins = UIEdgeInsets(top: 8, leading: Values.veryLargeSpacing, bottom: 8, trailing: Values.veryLargeSpacing) + stackView.isLayoutMarginsRelativeArrangement = true + scrollView.addSubview(stackView) + stackView.pin(to: scrollView) + addSubview(scrollView) + scrollView.pin(to: self) + } + + private func getChatBubble(withText text: String, wasSentByCurrentUser: Bool) -> UIView { + let result = UIView() + let bubbleView = UIView() + bubbleView.set(.width, to: Values.fakeChatBubbleWidth) + bubbleView.layer.cornerRadius = Values.fakeChatBubbleCornerRadius + let backgroundColor = wasSentByCurrentUser ? Colors.accent : Colors.fakeChatBubbleBackground + bubbleView.backgroundColor = backgroundColor + let label = UILabel() + let textColor = wasSentByCurrentUser ? Colors.fakeChatBubbleText : Colors.text + label.textColor = textColor + label.font = .boldSystemFont(ofSize: Values.mediumFontSize) + label.numberOfLines = 0 + label.lineBreakMode = .byWordWrapping + label.text = text + bubbleView.addSubview(label) + label.pin(to: bubbleView, withInset: Values.smallSpacing) + result.addSubview(bubbleView) + bubbleView.pin(.top, to: .top, of: result) + result.pin(.bottom, to: .bottom, of: bubbleView) + if wasSentByCurrentUser { + bubbleView.pin(.leading, to: .leading, of: result) + } else { + result.pin(.trailing, to: .trailing, of: bubbleView) + } + return result + } + + private func animate() { + let animationDuration = Values.fakeChatAnimationDuration + let delayBetweenMessages = Values.fakeChatDelay + chatBubbles.forEach { $0.alpha = 0 } + Timer.scheduledTimer(withTimeInterval: Values.fakeChatStartDelay, repeats: false) { [weak self] _ in + self?.showChatBubble(at: 0) + Timer.scheduledTimer(withTimeInterval: delayBetweenMessages, repeats: false) { _ in + self?.showChatBubble(at: 1) + Timer.scheduledTimer(withTimeInterval: delayBetweenMessages, repeats: false) { _ in + self?.showChatBubble(at: 2) + UIView.animate(withDuration: animationDuration) { + guard let self = self else { return } + self.scrollView.contentOffset = CGPoint(x: 0, y: self.chatBubbles[0].height() + self.spacing) + } + Timer.scheduledTimer(withTimeInterval: delayBetweenMessages, repeats: false) { _ in + self?.showChatBubble(at: 3) + UIView.animate(withDuration: animationDuration) { + guard let self = self else { return } + self.scrollView.contentOffset = CGPoint(x: 0, y: self.chatBubbles[0].height() + self.spacing + self.chatBubbles[1].height() + self.spacing) + } + } + } + } + } + } + + private func showChatBubble(at index: Int) { + let chatBubble = chatBubbles[index] + UIView.animate(withDuration: Values.fakeChatAnimationDuration) { + chatBubble.alpha = 1 + } + let scale = Values.fakeChatMessagePopAnimationStartScale + chatBubble.transform = CGAffineTransform(scaleX: scale, y: scale) + UIView.animate(withDuration: Values.fakeChatAnimationDuration, delay: 0, usingSpringWithDamping: 0.68, initialSpringVelocity: 4, options: .curveEaseInOut, animations: { + chatBubble.transform = CGAffineTransform(scaleX: 1, y: 1) + }, completion: nil) + } +} diff --git a/Signal/src/Loki/Redesign/Style Guide/Colors.swift b/Signal/src/Loki/Redesign/Style Guide/Colors.swift index 80c26dc30..c1316fd02 100644 --- a/Signal/src/Loki/Redesign/Style Guide/Colors.swift +++ b/Signal/src/Loki/Redesign/Style Guide/Colors.swift @@ -29,4 +29,6 @@ final class Colors : NSObject { @objc static let settingButtonSelected = UIColor(hex: 0x0C0C0C) @objc static let modalBackground = UIColor(hex: 0x101011) @objc static let modalBorder = UIColor(hex: 0x212121) + @objc static let fakeChatBubbleBackground = UIColor(hex: 0x3F4146) + @objc static let fakeChatBubbleText = UIColor(hex: 0x000000) } diff --git a/Signal/src/Loki/Redesign/Style Guide/Values.swift b/Signal/src/Loki/Redesign/Style Guide/Values.swift index a208324a4..0f9516330 100644 --- a/Signal/src/Loki/Redesign/Style Guide/Values.swift +++ b/Signal/src/Loki/Redesign/Style Guide/Values.swift @@ -35,6 +35,9 @@ final class Values : NSObject { @objc static let settingButtonHeight = CGFloat(75) @objc static let modalCornerRadius = CGFloat(10) @objc static let modalButtonCornerRadius = CGFloat(5) + @objc static let fakeChatBubbleWidth = CGFloat(224) + @objc static let fakeChatBubbleCornerRadius = CGFloat(10) + @objc static let fakeChatViewHeight = CGFloat(300) // MARK: - Distances @objc static let verySmallSpacing = CGFloat(4) @@ -44,4 +47,11 @@ final class Values : NSObject { @objc static let veryLargeSpacing = CGFloat(35) @objc static let massiveSpacing = CGFloat(64) @objc static let newConversationButtonBottomOffset = CGFloat(52) + @objc static let restoreButtonBottomOffset = CGFloat(52) + + // MARK: - Animation Values + @objc static let fakeChatStartDelay: TimeInterval = 2 + @objc static let fakeChatAnimationDuration: TimeInterval = 0.4 + @objc static let fakeChatDelay: TimeInterval = 4 + @objc static let fakeChatMessagePopAnimationStartScale: CGFloat = 0.6 } diff --git a/Signal/src/Loki/Redesign/Utilities/UIView+Constraints.swift b/Signal/src/Loki/Redesign/Utilities/UIView+Constraints.swift index aa191c58d..6ae22a929 100644 --- a/Signal/src/Loki/Redesign/Utilities/UIView+Constraints.swift +++ b/Signal/src/Loki/Redesign/Utilities/UIView+Constraints.swift @@ -43,6 +43,13 @@ extension UIView { [ VerticalEdge.top, VerticalEdge.bottom ].forEach { pin($0, to: $0, of: view) } } + func pin(to view: UIView, withInset inset: CGFloat) { + pin(.leading, to: .leading, of: view, withInset: inset) + pin(.top, to: .top, of: view, withInset: inset) + view.pin(.trailing, to: .trailing, of: self, withInset: inset) + view.pin(.bottom, to: .bottom, of: self, withInset: inset) + } + @discardableResult func center(_ direction: Direction, in view: UIView) -> NSLayoutConstraint { translatesAutoresizingMaskIntoConstraints = false diff --git a/Signal/src/Loki/Redesign/View Controllers/DeviceLinksVC.swift b/Signal/src/Loki/Redesign/View Controllers/DeviceLinksVC.swift index 693343cdb..0ac5667fe 100644 --- a/Signal/src/Loki/Redesign/View Controllers/DeviceLinksVC.swift +++ b/Signal/src/Loki/Redesign/View Controllers/DeviceLinksVC.swift @@ -24,7 +24,7 @@ final class DeviceLinksVC : UIViewController, UITableViewDataSource, UITableView explanationLabel.lineBreakMode = .byWordWrapping explanationLabel.textAlignment = .center explanationLabel.text = NSLocalizedString("You don't have any linked devices yet", comment: "") - let linkNewDeviceButton = Button(style: .prominent, size: .medium) + let linkNewDeviceButton = Button(style: .prominentOutline, size: .medium) linkNewDeviceButton.setTitle(NSLocalizedString("Link a Device", comment: ""), for: UIControl.State.normal) linkNewDeviceButton.addTarget(self, action: #selector(linkNewDevice), for: UIControl.Event.touchUpInside) linkNewDeviceButton.set(.width, to: 160) diff --git a/Signal/src/Loki/Redesign/View Controllers/JoinPublicChatVC.swift b/Signal/src/Loki/Redesign/View Controllers/JoinPublicChatVC.swift index 6a5d99c86..199ea8e0c 100644 --- a/Signal/src/Loki/Redesign/View Controllers/JoinPublicChatVC.swift +++ b/Signal/src/Loki/Redesign/View Controllers/JoinPublicChatVC.swift @@ -182,7 +182,7 @@ private final class EnterChatURLVC : UIViewController { explanationLabel.textAlignment = .center explanationLabel.lineBreakMode = .byWordWrapping // Next button - let nextButton = Button(style: .prominent, size: .large) + let nextButton = Button(style: .prominentOutline, size: .large) nextButton.setTitle(NSLocalizedString("Next", comment: ""), for: UIControl.State.normal) nextButton.addTarget(self, action: #selector(joinPublicChatIfPossible), for: UIControl.Event.touchUpInside) let nextButtonContainer = UIView() diff --git a/Signal/src/Loki/Redesign/View Controllers/LandingVC.swift b/Signal/src/Loki/Redesign/View Controllers/LandingVC.swift new file mode 100644 index 000000000..98ab49f2e --- /dev/null +++ b/Signal/src/Loki/Redesign/View Controllers/LandingVC.swift @@ -0,0 +1,74 @@ + +final class LandingVC : UIViewController { + + // MARK: Settings + override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent } + + // MARK: Lifecycle + override func viewDidLoad() { + // Set gradient background + view.backgroundColor = .clear + let gradient = Gradients.defaultLokiBackground + 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: "Loki") + logoImageView.contentMode = .scaleAspectFit + logoImageView.set(.width, to: 32) + logoImageView.set(.height, to: 32) + navigationItem.titleView = logoImageView + // Set up title label + let titleLabel = UILabel() + titleLabel.textColor = Colors.text + titleLabel.font = .boldSystemFont(ofSize: Values.veryLargeFontSize) + titleLabel.text = NSLocalizedString("Your Loki Messenger begins here...", comment: "") + titleLabel.numberOfLines = 0 + titleLabel.lineBreakMode = .byWordWrapping + // Set up title label container + let titleLabelContainer = UIView() + titleLabelContainer.addSubview(titleLabel) + titleLabel.pin(.leading, to: .leading, of: titleLabelContainer, withInset: Values.veryLargeSpacing) + titleLabel.pin(.top, to: .top, of: titleLabelContainer) + titleLabelContainer.pin(.trailing, to: .trailing, of: titleLabel, withInset: Values.veryLargeSpacing) + titleLabelContainer.pin(.bottom, to: .bottom, of: titleLabel) + // Set up fake chat view + let fakeChatView = FakeChatView() + // Set up main stack view + let mainStackView = UIStackView(arrangedSubviews: [ titleLabelContainer, fakeChatView ]) + mainStackView.axis = .vertical + mainStackView.spacing = Values.mediumSpacing // The fake chat view has an internal top margin + mainStackView.alignment = .fill + view.addSubview(mainStackView) + mainStackView.pin(.leading, to: .leading, of: view) + view.pin(.trailing, to: .trailing, of: mainStackView) + mainStackView.set(.height, to: Values.fakeChatViewHeight) + mainStackView.center(.vertical, in: view) + // Set up view + let screen = UIScreen.main.bounds + view.set(.width, to: screen.width) + view.set(.height, to: screen.height) + // Set up register button + let registerButton = Button(style: .prominentFilled, size: .large) + registerButton.setTitle(NSLocalizedString("Create Account", comment: ""), for: UIControl.State.normal) + registerButton.titleLabel!.font = .boldSystemFont(ofSize: Values.mediumFontSize) + // Set up restore button + let restoreButton = Button(style: .prominentOutline, size: .large) + restoreButton.setTitle(NSLocalizedString("Continue your Loki Messenger", comment: ""), for: UIControl.State.normal) + restoreButton.titleLabel!.font = .boldSystemFont(ofSize: Values.mediumFontSize) + // Set up button stack view + let buttonStackView = UIStackView(arrangedSubviews: [ registerButton, restoreButton ]) + buttonStackView.axis = .vertical + buttonStackView.spacing = Values.mediumSpacing + buttonStackView.alignment = .fill + view.addSubview(buttonStackView) + buttonStackView.pin(.leading, to: .leading, of: view, withInset: Values.massiveSpacing) + view.pin(.trailing, to: .trailing, of: buttonStackView, withInset: Values.massiveSpacing) + view.pin(.bottom, to: .bottom, of: buttonStackView, withInset: Values.restoreButtonBottomOffset) + } +} diff --git a/Signal/src/Loki/Redesign/View Controllers/NewPrivateChatVC.swift b/Signal/src/Loki/Redesign/View Controllers/NewPrivateChatVC.swift index 5d5c45816..10d32e377 100644 --- a/Signal/src/Loki/Redesign/View Controllers/NewPrivateChatVC.swift +++ b/Signal/src/Loki/Redesign/View Controllers/NewPrivateChatVC.swift @@ -192,7 +192,7 @@ private final class EnterPublicKeyVC : UIViewController { buttonContainer.spacing = Values.mediumSpacing buttonContainer.distribution = .fillEqually // Next button - let nextButton = Button(style: .prominent, size: .large) + let nextButton = Button(style: .prominentOutline, size: .large) nextButton.setTitle(NSLocalizedString("Next", comment: ""), for: UIControl.State.normal) nextButton.addTarget(self, action: #selector(startNewPrivateChatIfPossible), for: UIControl.Event.touchUpInside) let nextButtonContainer = UIView() diff --git a/Signal/src/Loki/Redesign/View Controllers/SettingsVC.swift b/Signal/src/Loki/Redesign/View Controllers/SettingsVC.swift index b1a14eb25..8cf3097ff 100644 --- a/Signal/src/Loki/Redesign/View Controllers/SettingsVC.swift +++ b/Signal/src/Loki/Redesign/View Controllers/SettingsVC.swift @@ -47,7 +47,7 @@ final class SettingsVC : UIViewController, AvatarViewHelperDelegate { }() private lazy var copyButton: Button = { - let result = Button(style: .prominent, size: .medium) + let result = Button(style: .prominentOutline, size: .medium) result.setTitle(NSLocalizedString("Copy", comment: ""), for: UIControl.State.normal) result.addTarget(self, action: #selector(copyPublicKey), for: UIControl.Event.touchUpInside) return result diff --git a/Signal/src/ViewControllers/AvatarViewHelper.m b/Signal/src/ViewControllers/AvatarViewHelper.m index 649fbbeec..d85483550 100644 --- a/Signal/src/ViewControllers/AvatarViewHelper.m +++ b/Signal/src/ViewControllers/AvatarViewHelper.m @@ -12,6 +12,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN diff --git a/Signal/src/ViewControllers/Registration/OnboardingController.swift b/Signal/src/ViewControllers/Registration/OnboardingController.swift index e23aaddd6..6180c7342 100644 --- a/Signal/src/ViewControllers/Registration/OnboardingController.swift +++ b/Signal/src/ViewControllers/Registration/OnboardingController.swift @@ -90,9 +90,7 @@ public class OnboardingController: NSObject { @objc public func initialViewController() -> UIViewController { AssertIsOnMainThread() - - let view = OnboardingSplashViewController(onboardingController: self) - return view + return LandingVC() } // MARK: - Transitions diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index 186450262..7dbbbf5d7 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -2724,3 +2724,10 @@ "Couldn't Update Profile Picture" = "Couldn't Update Profile Picture"; "Clear" = "Clear"; "Enter a display name" = "Enter a display name"; +"Your Loki Messenger begins here..." = "Your Loki Messenger begins here..."; +"What is Loki Messenger? A completely decentralised private messaging application for all platforms." = "What is Loki Messenger? A completely decentralised private messaging application for all platforms."; +"So no metadata collection, or personally identifiable information? How does it work?" = "So no metadata collection, or personally identifiable information? How does it work?"; +"Through a combination of advanced blockchain techniques including onion routing through Lokinet's private servers." = "Through a combination of advanced blockchain techniques including onion routing through Lokinet's private servers."; +"Friends don't let friends use compromised messengers. You're welcome." = "Friends don't let friends use compromised messengers. You're welcome."; +"Create Account" = "Create Account"; +"Continue your Loki Messenger" = "Continue your Loki Messenger";