From f5621991d810a570f0a46ef1cc5e52024229ba42 Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Tue, 23 Feb 2021 15:38:05 +0800 Subject: [PATCH 01/12] feat: confirmEmail Page --- Mastodon.xcodeproj/project.pbxproj | 33 ++++ .../xcshareddata/swiftpm/Package.resolved | 9 ++ Mastodon/Coordinator/SceneCoordinator.swift | 5 + Mastodon/Generated/Strings.swift | 26 ++++ Mastodon/Info.plist | 11 ++ .../Resources/en.lproj/Localizable.strings | 18 +++ .../MastodonConfirmEmailViewController.swift | 144 ++++++++++++++++++ .../MastodonConfirmEmailViewModel.swift | 21 +++ .../MastodonRegisterViewController.swift | 3 +- 9 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift create mode 100644 Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewModel.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index a67b28178..202fe0f96 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -36,6 +36,9 @@ 2D45E5BF25C9549700A6D639 /* PublicTimelineViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D45E5BE25C9549700A6D639 /* PublicTimelineViewModel+State.swift */; }; 2D46975E25C2A54100CF4AA9 /* NSLayoutConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D46975D25C2A54100CF4AA9 /* NSLayoutConstraint.swift */; }; 2D46976425C2A71500CF4AA9 /* UIIamge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D46976325C2A71500CF4AA9 /* UIIamge.swift */; }; + 2D59819B25E4A581000FB903 /* MastodonConfirmEmailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D59819A25E4A581000FB903 /* MastodonConfirmEmailViewController.swift */; }; + 2D5981A125E4A593000FB903 /* MastodonConfirmEmailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5981A025E4A593000FB903 /* MastodonConfirmEmailViewModel.swift */; }; + 2D5981BA25E4D7F8000FB903 /* ThirdPartyMailer in Frameworks */ = {isa = PBXBuildFile; productRef = 2D5981B925E4D7F8000FB903 /* ThirdPartyMailer */; }; 2D5A3D0325CF8742002347D6 /* ControlContainableScrollViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A3D0225CF8742002347D6 /* ControlContainableScrollViews.swift */; }; 2D5A3D1125CF87AA002347D6 /* AvatarBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A3D1025CF87AA002347D6 /* AvatarBarButtonItem.swift */; }; 2D5A3D2825CF8BC9002347D6 /* HomeTimelineViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D5A3D2725CF8BC9002347D6 /* HomeTimelineViewModel+Diffable.swift */; }; @@ -218,6 +221,8 @@ 2D45E5BE25C9549700A6D639 /* PublicTimelineViewModel+State.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PublicTimelineViewModel+State.swift"; sourceTree = ""; }; 2D46975D25C2A54100CF4AA9 /* NSLayoutConstraint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSLayoutConstraint.swift; sourceTree = ""; }; 2D46976325C2A71500CF4AA9 /* UIIamge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIIamge.swift; sourceTree = ""; }; + 2D59819A25E4A581000FB903 /* MastodonConfirmEmailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonConfirmEmailViewController.swift; sourceTree = ""; }; + 2D5981A025E4A593000FB903 /* MastodonConfirmEmailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonConfirmEmailViewModel.swift; sourceTree = ""; }; 2D5A3D0225CF8742002347D6 /* ControlContainableScrollViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControlContainableScrollViews.swift; sourceTree = ""; }; 2D5A3D1025CF87AA002347D6 /* AvatarBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarBarButtonItem.swift; sourceTree = ""; }; 2D5A3D2725CF8BC9002347D6 /* HomeTimelineViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HomeTimelineViewModel+Diffable.swift"; sourceTree = ""; }; @@ -346,6 +351,7 @@ DB5086B825CC0D6400C2C187 /* Kingfisher in Frameworks */, 2D61336925C18A4F00CAE157 /* AlamofireNetworkActivityIndicator in Frameworks */, DB3D0FF325BAA61700EAA174 /* AlamofireImage in Frameworks */, + 2D5981BA25E4D7F8000FB903 /* ThirdPartyMailer in Frameworks */, 45B49097460EDE530AD5AA72 /* Pods_Mastodon.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -466,6 +472,15 @@ path = Button; sourceTree = ""; }; + 2D59819925E4A55C000FB903 /* ConfirmEmail */ = { + isa = PBXGroup; + children = ( + 2D59819A25E4A581000FB903 /* MastodonConfirmEmailViewController.swift */, + 2D5981A025E4A593000FB903 /* MastodonConfirmEmailViewModel.swift */, + ); + path = ConfirmEmail; + sourceTree = ""; + }; 2D5A3D0125CF8640002347D6 /* Vender */ = { isa = PBXGroup; children = ( @@ -596,6 +611,7 @@ DB01409B25C40BB600F9F3CF /* Authentication */ = { isa = PBXGroup; children = ( + 2D59819925E4A55C000FB903 /* ConfirmEmail */, DB0140A625C40C0900F9F3CF /* PinBased */, DBE0821A25CD382900FD6BBD /* Register */, DB72602125E36A2500235243 /* ServerRules */, @@ -947,6 +963,7 @@ 2D42FF6025C8177C004A627A /* ActiveLabel */, DB0140BC25C40D7500F9F3CF /* CommonOSLog */, DB5086B725CC0D6400C2C187 /* Kingfisher */, + 2D5981B925E4D7F8000FB903 /* ThirdPartyMailer */, ); productName = Mastodon; productReference = DB427DD225BAA00100D1B89D /* Mastodon.app */; @@ -1074,6 +1091,7 @@ 2D42FF5F25C8177C004A627A /* XCRemoteSwiftPackageReference "ActiveLabel" */, DB0140BB25C40D7500F9F3CF /* XCRemoteSwiftPackageReference "CommonOSLog" */, DB5086B625CC0D6400C2C187 /* XCRemoteSwiftPackageReference "Kingfisher" */, + 2D5981B825E4D7F8000FB903 /* XCRemoteSwiftPackageReference "ThirdPartyMailer" */, ); productRefGroup = DB427DD325BAA00100D1B89D /* Products */; projectDirPath = ""; @@ -1258,6 +1276,7 @@ files = ( DB98337125C9443200AD9700 /* APIService+Authentication.swift in Sources */, 0FAA0FDF25E0B57E0017CCDE /* WelcomeViewController.swift in Sources */, + 2D59819B25E4A581000FB903 /* MastodonConfirmEmailViewController.swift in Sources */, DB45FB1D25CA9D23005A8AC7 /* APIService+HomeTimeline.swift in Sources */, 2D7631B325C159F700929FB9 /* Item.swift in Sources */, 2D61335E25C1894B00CAE157 /* APIService.swift in Sources */, @@ -1302,6 +1321,7 @@ 2DF75BA125D0E29D00694EC8 /* StatusProvider+TimelinePostTableViewCellDelegate.swift in Sources */, 2D42FF7E25C82218004A627A /* ActionToolBarContainer.swift in Sources */, DB0140A125C40C0600F9F3CF /* MastodonPinBasedAuthenticationViewController.swift in Sources */, + 2D5981A125E4A593000FB903 /* MastodonConfirmEmailViewModel.swift in Sources */, DB8AF55025C13703002E6C99 /* MainTabBarController.swift in Sources */, 2D38F1C625CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift in Sources */, DB8AF54525C13647002E6C99 /* NeedsDependency.swift in Sources */, @@ -1875,6 +1895,14 @@ minimumVersion = 4.0.0; }; }; + 2D5981B825E4D7F8000FB903 /* XCRemoteSwiftPackageReference "ThirdPartyMailer" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/vtourraine/ThirdPartyMailer.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.7.1; + }; + }; 2D61336725C18A4F00CAE157 /* XCRemoteSwiftPackageReference "AlamofireNetworkActivityIndicator" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/Alamofire/AlamofireNetworkActivityIndicator"; @@ -1915,6 +1943,11 @@ package = 2D42FF5F25C8177C004A627A /* XCRemoteSwiftPackageReference "ActiveLabel" */; productName = ActiveLabel; }; + 2D5981B925E4D7F8000FB903 /* ThirdPartyMailer */ = { + isa = XCSwiftPackageProductDependency; + package = 2D5981B825E4D7F8000FB903 /* XCRemoteSwiftPackageReference "ThirdPartyMailer" */; + productName = ThirdPartyMailer; + }; 2D61336825C18A4F00CAE157 /* AlamofireNetworkActivityIndicator */ = { isa = XCSwiftPackageProductDependency; package = 2D61336725C18A4F00CAE157 /* XCRemoteSwiftPackageReference "AlamofireNetworkActivityIndicator" */; diff --git a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved index bbf66235a..456a6e967 100644 --- a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -81,6 +81,15 @@ "revision": "2b6054efa051565954e1d2b9da831680026cd768", "version": "5.0.0" } + }, + { + "package": "ThirdPartyMailer", + "repositoryURL": "https://github.com/vtourraine/ThirdPartyMailer.git", + "state": { + "branch": null, + "revision": "923c60ee7588da47db8cfc4e0f5b96e5e605ef84", + "version": "1.7.1" + } } ] }, diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index 833e2a51a..02689f102 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -43,6 +43,7 @@ extension SceneCoordinator { case mastodonPinBasedAuthentication(viewModel: MastodonPinBasedAuthenticationViewModel) case mastodonRegister(viewModel: MastodonRegisterViewModel) case mastodonServerRules(viewModel: MastodonServerRulesViewModel) + case mastodonConfirmEmail(viewModel: MastodonConfirmEmailViewModel) case alertController(alertController: UIAlertController) } @@ -151,6 +152,10 @@ private extension SceneCoordinator { let _viewController = MastodonServerRulesViewController() _viewController.viewModel = viewModel viewController = _viewController + case .mastodonConfirmEmail(let viewModel): + let _viewController = MastodonConfirmEmailViewController() + _viewController.viewModel = viewModel + viewController = _viewController case .alertController(let alertController): if let popoverPresentationController = alertController.popoverPresentationController { assert( diff --git a/Mastodon/Generated/Strings.swift b/Mastodon/Generated/Strings.swift index 6042012d1..6b5cfb186 100644 --- a/Mastodon/Generated/Strings.swift +++ b/Mastodon/Generated/Strings.swift @@ -68,6 +68,32 @@ internal enum L10n { } internal enum Scene { + internal enum ConfirmEmail { + /// We just sent an email to %@,\ntap the link to confirm your account. + internal static func subtitle(_ p1: Any) -> String { + return L10n.tr("Localizable", "Scene.ConfirmEmail.Subtitle", String(describing: p1)) + } + /// One last thing. + internal static let title = L10n.tr("Localizable", "Scene.ConfirmEmail.Title") + internal enum Button { + /// I never got an email + internal static let dontReceiveEmail = L10n.tr("Localizable", "Scene.ConfirmEmail.Button.DontReceiveEmail") + /// Open email app + internal static let openEmailApp = L10n.tr("Localizable", "Scene.ConfirmEmail.Button.OpenEmailApp") + } + internal enum DontReceiveEmail { + /// Give our servers another n seconds before sending another email.\n\nCheck if your email address is correct as well as your junk folder if you haven’t. + internal static let alertDescription = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.alertDescription") + /// It’s too soon to tell. + internal static let alertTitle = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.alertTitle") + } + internal enum OpenEmailApp { + /// We just sent you another email. Check your junk folder if you haven’t. + internal static let alertDescription = L10n.tr("Localizable", "Scene.ConfirmEmail.OpenEmailApp.alertDescription") + /// Check your inbox. + internal static let alertTitle = L10n.tr("Localizable", "Scene.ConfirmEmail.OpenEmailApp.alertTitle") + } + } internal enum HomeTimeline { /// Home internal static let title = L10n.tr("Localizable", "Scene.HomeTimeline.Title") diff --git a/Mastodon/Info.plist b/Mastodon/Info.plist index 3455e6836..26ce99d70 100644 --- a/Mastodon/Info.plist +++ b/Mastodon/Info.plist @@ -66,5 +66,16 @@ Dark UIViewControllerBasedStatusBarAppearance + LSApplicationQueriesSchemes + + sparrow + googlegmail + x-dispatch + readdle-spark + airmail + ms-outlook + ymail + fastmail + diff --git a/Mastodon/Resources/en.lproj/Localizable.strings b/Mastodon/Resources/en.lproj/Localizable.strings index 9ef824361..47a1cf0bf 100644 --- a/Mastodon/Resources/en.lproj/Localizable.strings +++ b/Mastodon/Resources/en.lproj/Localizable.strings @@ -29,6 +29,7 @@ "Scene.Register.Input.Username.DuplicatePrompt" = "This username is taken."; "Scene.Register.Input.Username.Placeholder" = "username"; "Scene.Register.Title" = "Tell us about you."; + "Scene.ServerPicker.Input.Placeholder" = "Find a server or join your own..."; "Scene.ServerPicker.Title" = "Pick a Server, any server."; @@ -36,5 +37,22 @@ any server."; "Scene.ServerRules.Prompt" = "By continuing, you're subject to the terms of service and privacy policy for %@."; "Scene.ServerRules.Subtitle" = "These rules are set by the admins of %@."; "Scene.ServerRules.Title" = "Some ground rules."; + "Scene.Welcome.Slogan" = "Social networking back in your hands."; + +"Scene.ConfirmEmail.Title" = "One last thing."; +"Scene.ConfirmEmail.Subtitle" = "We just sent an email to %@, +tap the link to confirm your account."; +"Scene.ConfirmEmail.Button.OpenEmailApp" = "Open email app"; + +"Scene.ConfirmEmail.Button.DontReceiveEmail" = "I never got an email"; + +"Scene.ConfirmEmail.DontReceiveEmail.alertTitle" = "It’s too soon to tell."; +"Scene.ConfirmEmail.DontReceiveEmail.alertDescription" = "Give our servers another n seconds before sending another email. + +Check if your email address is correct as well as your junk folder if you haven’t."; +"Scene.ConfirmEmail.OpenEmailApp.alertTitle" = "Check your inbox."; +"Scene.ConfirmEmail.OpenEmailApp.alertDescription" = "We just sent you another email. Check your junk folder if you haven’t."; + + diff --git a/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift new file mode 100644 index 000000000..0c45a0220 --- /dev/null +++ b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift @@ -0,0 +1,144 @@ +// +// MastodonConfirmEmailViewController.swift +// Mastodon +// +// Created by sxiaojian on 2021/2/23. +// + +import Combine +import ThirdPartyMailer +import UIKit + +final class MastodonConfirmEmailViewController: UIViewController, NeedsDependency { + var disposeBag = Set() + + weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } + weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } + + var viewModel: MastodonConfirmEmailViewModel! + + let largeTitleLabel: UILabel = { + let label = UILabel() + label.font = UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: UIFont.boldSystemFont(ofSize: 34)) + label.textColor = .label + label.text = L10n.Scene.ConfirmEmail.title + return label + }() + + private(set) lazy var subtitleLabel: UILabel = { + let label = UILabel() + label.font = UIFontMetrics(forTextStyle: .title1).scaledFont(for: UIFont.systemFont(ofSize: 20)) + label.textColor = .secondaryLabel + label.text = L10n.Scene.ConfirmEmail.subtitle(viewModel.email) + label.numberOfLines = 0 + return label + }() + + let openEmailButton: UIButton = { + let button = UIButton(type: .system) + button.titleLabel?.font = .preferredFont(forTextStyle: .headline) + button.setBackgroundImage(UIImage.placeholder(color: Asset.Colors.lightBrandBlue.color), for: .normal) + button.setTitleColor(.white, for: .normal) + button.setTitle(L10n.Scene.ConfirmEmail.Button.openEmailApp, for: .normal) + button.layer.masksToBounds = true + button.layer.cornerRadius = 8 + button.layer.cornerCurve = .continuous + button.addTarget(self, action: #selector(openEmailButtonPressed(_:)), for: UIControl.Event.touchUpInside) + return button + }() + + let dontReceiveButton: UIButton = { + let button = UIButton(type: .system) + button.titleLabel?.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: UIFont.boldSystemFont(ofSize: 15)) + button.setTitleColor(Asset.Colors.lightBrandBlue.color, for: .normal) + button.setTitle(L10n.Scene.ConfirmEmail.Button.dontReceiveEmail, for: .normal) + button.addTarget(self, action: #selector(dontReceiveButtonPressed(_:)), for: UIControl.Event.touchUpInside) + return button + }() +} + +extension MastodonConfirmEmailViewController { + override func viewDidLoad() { + overrideUserInterfaceStyle = .light + view.backgroundColor = Asset.Colors.Background.onboardingBackground.color + // set navigationBar transparent + self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarPosition.any, barMetrics: .default) + self.navigationController?.navigationBar.shadowImage = UIImage() + self.navigationController?.navigationBar.topItem?.title = "Back" + + // resizedView + let resizedView = UIView() + resizedView.translatesAutoresizingMaskIntoConstraints = false + resizedView.setContentHuggingPriority(UILayoutPriority.defaultLow, for: NSLayoutConstraint.Axis.vertical) + + // stackView + let stackView = UIStackView() + stackView.axis = .vertical + stackView.distribution = .fill + stackView.spacing = 10 + stackView.layoutMargins = UIEdgeInsets(top: 10, left: 0, bottom: 23, right: 0) + stackView.isLayoutMarginsRelativeArrangement = true + stackView.addArrangedSubview(self.largeTitleLabel) + stackView.addArrangedSubview(self.subtitleLabel) + stackView.addArrangedSubview(resizedView) + stackView.addArrangedSubview(self.openEmailButton) + stackView.addArrangedSubview(self.dontReceiveButton) + + view.addSubview(stackView) + stackView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + stackView.topAnchor.constraint(equalTo: view.readableContentGuide.topAnchor), + stackView.leadingAnchor.constraint(equalTo: view.readableContentGuide.leadingAnchor), + stackView.trailingAnchor.constraint(equalTo: view.readableContentGuide.trailingAnchor), + stackView.bottomAnchor.constraint(equalTo: view.readableContentGuide.bottomAnchor), + ]) + NSLayoutConstraint.activate([ + self.openEmailButton.heightAnchor.constraint(equalToConstant: 46), + ]) + } +} + +extension MastodonConfirmEmailViewController { + @objc private func openEmailButtonPressed(_ sender: UIButton) { + let alertController = UIAlertController(title: L10n.Scene.ConfirmEmail.OpenEmailApp.alertTitle, message: L10n.Scene.ConfirmEmail.OpenEmailApp.alertDescription, preferredStyle: .alert) + let openEmailAction = UIAlertAction(title: L10n.Scene.ConfirmEmail.Button.openEmailApp, style: .default) { [weak self] _ in + guard let self = self else { return } + self.showEmailAppAlert() + } + let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel, handler: nil) + alertController.addAction(openEmailAction) + alertController.addAction(cancelAction) + + self.coordinator.present(scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil)) + } + + @objc private func dontReceiveButtonPressed(_ sender: UIButton) { + let alertController = UIAlertController(title: L10n.Scene.ConfirmEmail.DontReceiveEmail.alertTitle, message: L10n.Scene.ConfirmEmail.DontReceiveEmail.alertDescription, preferredStyle: .alert) + let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default) { _ in } + alertController.addAction(okAction) + self.coordinator.present(scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil)) + } + + func showEmailAppAlert() { + let clients = ThirdPartyMailClient.clients() + let application = UIApplication.shared + let avaliableClients = clients.filter { client -> Bool in + ThirdPartyMailer.application(application, isMailClientAvailable: client) + } + let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) + let alertAction = UIAlertAction(title: "Mail", style: .default) { _ in + UIApplication.shared.open(URL(string: "message://")!, options: [:], completionHandler: nil) + } + alertController.addAction(alertAction) + _ = avaliableClients.compactMap { client -> UIAlertAction in + let alertAction = UIAlertAction(title: client.name, style: .default) { _ in + _ = ThirdPartyMailer.application(application, openMailClient: client, recipient: nil, subject: nil, body: nil) + } + alertController.addAction(alertAction) + return alertAction + } + let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel, handler: nil) + alertController.addAction(cancelAction) + self.coordinator.present(scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil)) + } +} diff --git a/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewModel.swift b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewModel.swift new file mode 100644 index 000000000..8da02d8ed --- /dev/null +++ b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewModel.swift @@ -0,0 +1,21 @@ +// +// MastodonConfirmEmailViewModel.swift +// Mastodon +// +// Created by sxiaojian on 2021/2/23. +// + +import Combine + +final class MastodonConfirmEmailViewModel { + var disposeBag = Set() + + let context: AppContext + var email: String + + init(context: AppContext, email: String) { + self.context = context + self.email = email + } +} + diff --git a/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift b/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift index 98f876c3d..dd29d10bf 100644 --- a/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift +++ b/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift @@ -572,7 +572,8 @@ extension MastodonRegisterViewController { let alertController = UIAlertController(title: "Success", message: "Regsiter request sent. Please check your email.\n(Auto sign in not implement yet.)", preferredStyle: .alert) let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default) { [weak self] _ in guard let self = self else { return } - self.navigationController?.popViewController(animated: true) + let viewModel = MastodonConfirmEmailViewModel(context: self.context, email: email) + self.coordinator.present(scene: .mastodonConfirmEmail(viewModel: viewModel), from: self, transition: .show) } alertController.addAction(okAction) self.coordinator.present(scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil)) From 36e5fa3950b1c7abfa017f16fa279c1234285be0 Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Wed, 24 Feb 2021 10:49:50 +0800 Subject: [PATCH 02/12] chore: add cancel action to alert --- Mastodon/Generated/Strings.swift | 10 ++++++---- Mastodon/Resources/en.lproj/Localizable.strings | 9 +++++---- .../MastodonConfirmEmailViewController.swift | 8 +++++--- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Mastodon/Generated/Strings.swift b/Mastodon/Generated/Strings.swift index 6b5cfb186..2f8c34e4f 100644 --- a/Mastodon/Generated/Strings.swift +++ b/Mastodon/Generated/Strings.swift @@ -83,15 +83,17 @@ internal enum L10n { } internal enum DontReceiveEmail { /// Give our servers another n seconds before sending another email.\n\nCheck if your email address is correct as well as your junk folder if you haven’t. - internal static let alertDescription = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.alertDescription") + internal static let alertDescription = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.AlertDescription") /// It’s too soon to tell. - internal static let alertTitle = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.alertTitle") + internal static let alertTitle = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.AlertTitle") } internal enum OpenEmailApp { /// We just sent you another email. Check your junk folder if you haven’t. - internal static let alertDescription = L10n.tr("Localizable", "Scene.ConfirmEmail.OpenEmailApp.alertDescription") + internal static let alertDescription = L10n.tr("Localizable", "Scene.ConfirmEmail.OpenEmailApp.AlertDescription") /// Check your inbox. - internal static let alertTitle = L10n.tr("Localizable", "Scene.ConfirmEmail.OpenEmailApp.alertTitle") + internal static let alertTitle = L10n.tr("Localizable", "Scene.ConfirmEmail.OpenEmailApp.AlertTitle") + /// Mail + internal static let mail = L10n.tr("Localizable", "Scene.ConfirmEmail.OpenEmailApp.Mail") } } internal enum HomeTimeline { diff --git a/Mastodon/Resources/en.lproj/Localizable.strings b/Mastodon/Resources/en.lproj/Localizable.strings index 47a1cf0bf..3efe99032 100644 --- a/Mastodon/Resources/en.lproj/Localizable.strings +++ b/Mastodon/Resources/en.lproj/Localizable.strings @@ -48,11 +48,12 @@ tap the link to confirm your account."; "Scene.ConfirmEmail.Button.DontReceiveEmail" = "I never got an email"; -"Scene.ConfirmEmail.DontReceiveEmail.alertTitle" = "It’s too soon to tell."; -"Scene.ConfirmEmail.DontReceiveEmail.alertDescription" = "Give our servers another n seconds before sending another email. +"Scene.ConfirmEmail.DontReceiveEmail.AlertTitle" = "It’s too soon to tell."; +"Scene.ConfirmEmail.DontReceiveEmail.AlertDescription" = "Give our servers another n seconds before sending another email. Check if your email address is correct as well as your junk folder if you haven’t."; -"Scene.ConfirmEmail.OpenEmailApp.alertTitle" = "Check your inbox."; -"Scene.ConfirmEmail.OpenEmailApp.alertDescription" = "We just sent you another email. Check your junk folder if you haven’t."; +"Scene.ConfirmEmail.OpenEmailApp.AlertTitle" = "Check your inbox."; +"Scene.ConfirmEmail.OpenEmailApp.AlertDescription" = "We just sent you another email. Check your junk folder if you haven’t."; +"Scene.ConfirmEmail.OpenEmailApp.Mail" = "Mail"; diff --git a/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift index 0c45a0220..4a0cec74a 100644 --- a/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift +++ b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift @@ -108,7 +108,7 @@ extension MastodonConfirmEmailViewController { let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel, handler: nil) alertController.addAction(openEmailAction) alertController.addAction(cancelAction) - + alertController.preferredAction = openEmailAction self.coordinator.present(scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil)) } @@ -125,8 +125,9 @@ extension MastodonConfirmEmailViewController { let avaliableClients = clients.filter { client -> Bool in ThirdPartyMailer.application(application, isMailClientAvailable: client) } - let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) - let alertAction = UIAlertAction(title: "Mail", style: .default) { _ in + let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .alert) + + let alertAction = UIAlertAction(title: L10n.Scene.ConfirmEmail.OpenEmailApp.mail, style: .default) { _ in UIApplication.shared.open(URL(string: "message://")!, options: [:], completionHandler: nil) } alertController.addAction(alertAction) @@ -140,5 +141,6 @@ extension MastodonConfirmEmailViewController { let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel, handler: nil) alertController.addAction(cancelAction) self.coordinator.present(scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil)) + } } From 405958768b5cb2e8e67ced4817735527dcd7ff7b Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Wed, 24 Feb 2021 17:08:36 +0800 Subject: [PATCH 03/12] chore: edit app.json --- Localization/app.json | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Localization/app.json b/Localization/app.json index 0c3f16c7c..ca9fd60e3 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -68,6 +68,23 @@ "confirm": "I Agree" } }, + "confirm_email": { + "title": "One last thing.", + "subtitle": "We just sent an email to %@,\ntap the link to confirm your account.", + "button": { + "open_email_app": "Open email app", + "dont_receive_email": "I never got an email" + }, + "dont_receive_email": { + "alert_title": "It’s too soon to tell.", + "alert_description": "Give our servers another n seconds before sending another email.\nCheck if your email address is correct as well as your junk folder if you haven’t." + }, + "open_email_app": { + "alert_title": "Check your inbox.", + "alert_description": "We just sent you another email. Check your junk folder if you haven’t.", + "mail": "Mail" + } + }, "home_timeline": { "title": "Home" }, @@ -75,4 +92,4 @@ "title": "Public" } } -} \ No newline at end of file +} From 35ef867adf6d768ff15dbd992bacb69a460032cd Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Wed, 24 Feb 2021 20:06:28 +0800 Subject: [PATCH 04/12] chore: add account validation and webView email pre-fill --- Localization/app.json | 4 +- Mastodon.xcodeproj/project.pbxproj | 16 ++++ Mastodon/Coordinator/SceneCoordinator.swift | 5 ++ Mastodon/Generated/Strings.swift | 6 +- .../Resources/en.lproj/Localizable.strings | 13 ++++ .../AuthenticationViewController.swift | 2 +- .../MastodonConfirmEmailViewController.swift | 22 ++++-- .../MastodonConfirmEmailViewModel.swift | 40 +++++++++- .../MastodonRegisterViewController.swift | 7 +- .../MastodonResendEmailViewController.swift | 73 +++++++++++++++++++ .../MastodonResendEmailViewModel.swift | 26 +++++++ .../MastodonSDK/API/Mastodon+API.swift | 4 + 12 files changed, 202 insertions(+), 16 deletions(-) create mode 100644 Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewController.swift create mode 100644 Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModel.swift diff --git a/Localization/app.json b/Localization/app.json index bfe2178cb..19bf46537 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -63,7 +63,9 @@ "prompt": "Your password needs at least:", "prompt_eight_characters": "Eight characters" } - } + }, + "success": "Success", + "check_email": "Regsiter request sent. Please check your email." }, "server_rules": { "title": "Some ground rules.", diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 63aacb372..b4eb91e4f 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -18,6 +18,8 @@ 2D32EAAC25CB96DC00C9ED86 /* TimelineMiddleLoaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D32EAAB25CB96DC00C9ED86 /* TimelineMiddleLoaderTableViewCell.swift */; }; 2D32EABA25CB9B0500C9ED86 /* UIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D32EAB925CB9B0500C9ED86 /* UIView.swift */; }; 2D32EADA25CBCC3300C9ED86 /* PublicTimelineViewModel+LoadMiddleState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D32EAD925CBCC3300C9ED86 /* PublicTimelineViewModel+LoadMiddleState.swift */; }; + 2D364F7225E66D7500204FDC /* MastodonResendEmailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */; }; + 2D364F7825E66D8300204FDC /* MastodonResendEmailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */; }; 2D38F1C625CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1C525CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift */; }; 2D38F1D525CD465300561493 /* HomeTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1D425CD465300561493 /* HomeTimelineViewController.swift */; }; 2D38F1DF25CD46A400561493 /* HomeTimelineViewController+StatusProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1DE25CD46A400561493 /* HomeTimelineViewController+StatusProvider.swift */; }; @@ -213,6 +215,8 @@ 2D32EAAB25CB96DC00C9ED86 /* TimelineMiddleLoaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineMiddleLoaderTableViewCell.swift; sourceTree = ""; }; 2D32EAB925CB9B0500C9ED86 /* UIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIView.swift; sourceTree = ""; }; 2D32EAD925CBCC3300C9ED86 /* PublicTimelineViewModel+LoadMiddleState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PublicTimelineViewModel+LoadMiddleState.swift"; sourceTree = ""; }; + 2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewController.swift; sourceTree = ""; }; + 2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewModel.swift; sourceTree = ""; }; 2D38F1C525CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentOffsetAdjustableTimelineViewControllerDelegate.swift; sourceTree = ""; }; 2D38F1D425CD465300561493 /* HomeTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTimelineViewController.swift; sourceTree = ""; }; 2D38F1DE25CD46A400561493 /* HomeTimelineViewController+StatusProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HomeTimelineViewController+StatusProvider.swift"; sourceTree = ""; }; @@ -446,6 +450,15 @@ path = Content; sourceTree = ""; }; + 2D364F7025E66D5B00204FDC /* ResendEmail */ = { + isa = PBXGroup; + children = ( + 2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */, + 2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */, + ); + path = ResendEmail; + sourceTree = ""; + }; 2D38F1D325CD463600561493 /* HomeTimeline */ = { isa = PBXGroup; children = ( @@ -631,6 +644,7 @@ DB01409B25C40BB600F9F3CF /* Authentication */ = { isa = PBXGroup; children = ( + 2D364F7025E66D5B00204FDC /* ResendEmail */, 2D59819925E4A55C000FB903 /* ConfirmEmail */, DB0140A625C40C0900F9F3CF /* PinBased */, DBE0821A25CD382900FD6BBD /* Register */, @@ -1353,6 +1367,7 @@ 0FAA101225E105390017CCDE /* PrimaryActionButton.swift in Sources */, DB8AF53025C13561002E6C99 /* AppContext.swift in Sources */, DB72602725E36A6F00235243 /* MastodonServerRulesViewModel.swift in Sources */, + 2D364F7225E66D7500204FDC /* MastodonResendEmailViewController.swift in Sources */, 2D38F1F125CD477D00561493 /* HomeTimelineViewModel+LoadMiddleState.swift in Sources */, DB45FAD725CA6C76005A8AC7 /* UIBarButtonItem.swift in Sources */, 2D152A8C25C295CC009AA50C /* StatusView.swift in Sources */, @@ -1395,6 +1410,7 @@ DB8AF55025C13703002E6C99 /* MainTabBarController.swift in Sources */, DB9D6BE925E4F5340051B173 /* SearchViewController.swift in Sources */, 2D38F1C625CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift in Sources */, + 2D364F7825E66D8300204FDC /* MastodonResendEmailViewModel.swift in Sources */, DB8AF54525C13647002E6C99 /* NeedsDependency.swift in Sources */, DB9D6BF825E4F5690051B173 /* NotificationViewController.swift in Sources */, DB45FADD25CA6F6B005A8AC7 /* APIService+CoreData+MastodonUser.swift in Sources */, diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index ef04c9572..30b68ce5e 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -44,6 +44,7 @@ extension SceneCoordinator { case mastodonRegister(viewModel: MastodonRegisterViewModel) case mastodonServerRules(viewModel: MastodonServerRulesViewModel) case mastodonConfirmEmail(viewModel: MastodonConfirmEmailViewModel) + case mastodonResendEmail(viewModel: MastodonResendEmailViewModel) case alertController(alertController: UIAlertController) } @@ -157,6 +158,10 @@ private extension SceneCoordinator { let _viewController = MastodonConfirmEmailViewController() _viewController.viewModel = viewModel viewController = _viewController + case .mastodonResendEmail(let viewModel): + let _viewController = MastodonResendEmailViewController() + _viewController.viewModel = viewModel + viewController = _viewController case .alertController(let alertController): if let popoverPresentationController = alertController.popoverPresentationController { assert( diff --git a/Mastodon/Generated/Strings.swift b/Mastodon/Generated/Strings.swift index 975b72037..a5cd7a9d7 100644 --- a/Mastodon/Generated/Strings.swift +++ b/Mastodon/Generated/Strings.swift @@ -85,7 +85,7 @@ internal enum L10n { internal static let openEmailApp = L10n.tr("Localizable", "Scene.ConfirmEmail.Button.OpenEmailApp") } internal enum DontReceiveEmail { - /// Give our servers another n seconds before sending another email.\n\nCheck if your email address is correct as well as your junk folder if you haven’t. + /// Give our servers another n seconds before sending another email.\nCheck if your email address is correct as well as your junk folder if you haven’t. internal static let alertDescription = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.AlertDescription") /// It’s too soon to tell. internal static let alertTitle = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.AlertTitle") @@ -108,6 +108,10 @@ internal enum L10n { internal static let title = L10n.tr("Localizable", "Scene.PublicTimeline.Title") } internal enum Register { + /// Regsiter request sent. Please check your email. + internal static let checkEmail = L10n.tr("Localizable", "Scene.Register.CheckEmail") + /// Success + internal static let success = L10n.tr("Localizable", "Scene.Register.Success") /// Tell us about you. internal static let title = L10n.tr("Localizable", "Scene.Register.Title") internal enum Input { diff --git a/Mastodon/Resources/en.lproj/Localizable.strings b/Mastodon/Resources/en.lproj/Localizable.strings index 75dc3999b..c9c731c6b 100644 --- a/Mastodon/Resources/en.lproj/Localizable.strings +++ b/Mastodon/Resources/en.lproj/Localizable.strings @@ -19,8 +19,20 @@ "Common.Controls.Timeline.LoadMore" = "Load More"; "Common.Countable.Photo.Multiple" = "photos"; "Common.Countable.Photo.Single" = "photo"; +"Scene.ConfirmEmail.Button.DontReceiveEmail" = "I never got an email"; +"Scene.ConfirmEmail.Button.OpenEmailApp" = "Open email app"; +"Scene.ConfirmEmail.DontReceiveEmail.AlertDescription" = "Give our servers another n seconds before sending another email. +Check if your email address is correct as well as your junk folder if you haven’t."; +"Scene.ConfirmEmail.DontReceiveEmail.AlertTitle" = "It’s too soon to tell."; +"Scene.ConfirmEmail.OpenEmailApp.AlertDescription" = "We just sent you another email. Check your junk folder if you haven’t."; +"Scene.ConfirmEmail.OpenEmailApp.AlertTitle" = "Check your inbox."; +"Scene.ConfirmEmail.OpenEmailApp.Mail" = "Mail"; +"Scene.ConfirmEmail.Subtitle" = "We just sent an email to %@, +tap the link to confirm your account."; +"Scene.ConfirmEmail.Title" = "One last thing."; "Scene.HomeTimeline.Title" = "Home"; "Scene.PublicTimeline.Title" = "Public"; +"Scene.Register.CheckEmail" = "Regsiter request sent. Please check your email."; "Scene.Register.Input.DisplayName.Placeholder" = "display name"; "Scene.Register.Input.Email.Placeholder" = "email"; "Scene.Register.Input.Password.Placeholder" = "password"; @@ -28,6 +40,7 @@ "Scene.Register.Input.Password.PromptEightCharacters" = "Eight characters"; "Scene.Register.Input.Username.DuplicatePrompt" = "This username is taken."; "Scene.Register.Input.Username.Placeholder" = "username"; +"Scene.Register.Success" = "Success"; "Scene.Register.Title" = "Tell us about you."; "Scene.ServerPicker.Input.Placeholder" = "Find a server or join your own..."; "Scene.ServerPicker.Title" = "Pick a Server, diff --git a/Mastodon/Scene/Authentication/AuthenticationViewController.swift b/Mastodon/Scene/Authentication/AuthenticationViewController.swift index 5ab500bc2..d93651ba5 100644 --- a/Mastodon/Scene/Authentication/AuthenticationViewController.swift +++ b/Mastodon/Scene/Authentication/AuthenticationViewController.swift @@ -78,7 +78,7 @@ extension AuthenticationViewController { super.viewDidLoad() overrideUserInterfaceStyle = .dark // FIXME: - title = "Authentication" + view.backgroundColor = Asset.Colors.Background.systemBackground.color domainLabel.translatesAutoresizingMaskIntoConstraints = false diff --git a/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift index 4a0cec74a..ff41740b2 100644 --- a/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift +++ b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift @@ -8,6 +8,7 @@ import Combine import ThirdPartyMailer import UIKit +import MastodonSDK final class MastodonConfirmEmailViewController: UIViewController, NeedsDependency { var disposeBag = Set() @@ -58,18 +59,25 @@ final class MastodonConfirmEmailViewController: UIViewController, NeedsDependenc } extension MastodonConfirmEmailViewController { + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + navigationController?.setNavigationBarHidden(false, animated: false) + } override func viewDidLoad() { overrideUserInterfaceStyle = .light view.backgroundColor = Asset.Colors.Background.onboardingBackground.color + // set navigationBar transparent - self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarPosition.any, barMetrics: .default) - self.navigationController?.navigationBar.shadowImage = UIImage() - self.navigationController?.navigationBar.topItem?.title = "Back" + let barAppearance = UINavigationBarAppearance() + barAppearance.configureWithTransparentBackground() + navigationController?.navigationBar.standardAppearance = barAppearance + navigationController?.navigationBar.compactAppearance = barAppearance + navigationController?.navigationBar.scrollEdgeAppearance = barAppearance // resizedView let resizedView = UIView() resizedView.translatesAutoresizingMaskIntoConstraints = false - resizedView.setContentHuggingPriority(UILayoutPriority.defaultLow, for: NSLayoutConstraint.Axis.vertical) + resizedView.setContentHuggingPriority(.defaultLow, for: .vertical) // stackView let stackView = UIStackView() @@ -114,7 +122,11 @@ extension MastodonConfirmEmailViewController { @objc private func dontReceiveButtonPressed(_ sender: UIButton) { let alertController = UIAlertController(title: L10n.Scene.ConfirmEmail.DontReceiveEmail.alertTitle, message: L10n.Scene.ConfirmEmail.DontReceiveEmail.alertDescription, preferredStyle: .alert) - let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default) { _ in } + let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default) { _ in + let url = Mastodon.API.resendEmailURL(domain:self.viewModel.authenticateInfo.domain) + let viewModel = MastodonResendEmailViewModel(resendEmailURL: url, email: self.viewModel.email) + self.coordinator.present(scene: .mastodonResendEmail(viewModel: viewModel), from: self, transition: .show) + } alertController.addAction(okAction) self.coordinator.present(scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil)) } diff --git a/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewModel.swift b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewModel.swift index 8da02d8ed..d1e3936a2 100644 --- a/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewModel.swift +++ b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewModel.swift @@ -6,16 +6,48 @@ // import Combine +import Foundation +import MastodonSDK +import os.log final class MastodonConfirmEmailViewModel { var disposeBag = Set() - + let context: AppContext + let coordinator: SceneCoordinator var email: String - - init(context: AppContext, email: String) { + let authenticateInfo: AuthenticationViewModel.AuthenticateInfo + let userToken: Mastodon.Entity.Token + + let timestampUpdatePublisher = Timer.publish(every: 4.0, on: .main, in: .common) + .autoconnect() + .share() + .eraseToAnyPublisher() + + init(context: AppContext,coordinator: SceneCoordinator, email: String, authenticateInfo: AuthenticationViewModel.AuthenticateInfo, userToken: Mastodon.Entity.Token) { self.context = context + self.coordinator = coordinator self.email = email + self.authenticateInfo = authenticateInfo + self.userToken = userToken + timestampUpdatePublisher + .sink { [weak self] _ in + guard let self = self else { return } + AuthenticationViewModel.verifyAndSaveAuthentication(context: self.context, info: authenticateInfo, userToken: userToken) + .receive(on: DispatchQueue.main) + .sink { completion in + switch completion { + case .failure(let error): + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: swap user access token swap fail: %s", ((#file as NSString).lastPathComponent), #line, #function, error.localizedDescription) + case .finished: + break + } + } receiveValue: { _ in + self.coordinator.setup() + } + .store(in: &self.disposeBag) + + } + .store(in: &disposeBag) } } - diff --git a/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift b/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift index afdf815ae..1ee306cf1 100644 --- a/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift +++ b/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift @@ -567,12 +567,12 @@ extension MastodonRegisterViewController { } } receiveValue: { [weak self] response in guard let self = self else { return } - _ = response.value + let userToken = response.value // TODO: - let alertController = UIAlertController(title: "Success", message: "Regsiter request sent. Please check your email.\n(Auto sign in not implement yet.)", preferredStyle: .alert) + let alertController = UIAlertController(title: L10n.Scene.Register.success, message: L10n.Scene.Register.checkEmail, preferredStyle: .alert) let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default) { [weak self] _ in guard let self = self else { return } - let viewModel = MastodonConfirmEmailViewModel(context: self.context, email: email) + let viewModel = MastodonConfirmEmailViewModel(context: self.context, coordinator: self.coordinator, email: email, authenticateInfo: self.viewModel.authenticateInfo, userToken: userToken) self.coordinator.present(scene: .mastodonConfirmEmail(viewModel: viewModel), from: self, transition: .show) } alertController.addAction(okAction) @@ -580,5 +580,4 @@ extension MastodonRegisterViewController { } .store(in: &disposeBag) } - } diff --git a/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewController.swift b/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewController.swift new file mode 100644 index 000000000..e54baa137 --- /dev/null +++ b/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewController.swift @@ -0,0 +1,73 @@ +// +// MastodonResendEmailViewController.swift +// Mastodon +// +// Created by sxiaojian on 2021/2/24. +// + +import Combine +import os.log +import UIKit +import WebKit + +final class MastodonResendEmailViewController: UIViewController, NeedsDependency, WKNavigationDelegate { + weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } + weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } + + var disposeBag = Set() + var viewModel: MastodonResendEmailViewModel! + + let webView: WKWebView = { + let configuration = WKWebViewConfiguration() + configuration.processPool = WKProcessPool() + let webView = WKWebView(frame: .zero, configuration: configuration) + return webView + }() + + deinit { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", (#file as NSString).lastPathComponent, #line, #function) + + // cleanup cookie + let httpCookieStore = webView.configuration.websiteDataStore.httpCookieStore + httpCookieStore.getAllCookies { cookies in + for cookie in cookies { + httpCookieStore.delete(cookie, completionHandler: nil) + } + } + } +} + +extension MastodonResendEmailViewController { + override func viewDidLoad() { + super.viewDidLoad() + + navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(MastodonResendEmailViewController.cancelBarButtonItemPressed(_:))) + + webView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(webView) + NSLayoutConstraint.activate([ + webView.topAnchor.constraint(equalTo: view.topAnchor), + webView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + webView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + webView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + ]) + + let request = URLRequest(url: viewModel.resendEmailURL) + webView.navigationDelegate = self + webView.load(request) + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: resendEmail via: %s", (#file as NSString).lastPathComponent, #line, #function, viewModel.resendEmailURL.debugDescription) + } +} + +extension MastodonResendEmailViewController { + func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { + let scriptString = "document.getElementById('user_email').value = '\(self.viewModel.email)';" + webView.evaluateJavaScript(scriptString) + } +} + +extension MastodonResendEmailViewController { + @objc private func cancelBarButtonItemPressed(_ sender: UIBarButtonItem) { + dismiss(animated: true, completion: nil) + } +} diff --git a/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModel.swift b/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModel.swift new file mode 100644 index 000000000..861d7d7f7 --- /dev/null +++ b/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModel.swift @@ -0,0 +1,26 @@ +// +// MastodonResendEmailViewModel.swift +// Mastodon +// +// Created by sxiaojian on 2021/2/24. +// + +import Combine +import Foundation +import os.log +import WebKit + +final class MastodonResendEmailViewModel { + // input + let resendEmailURL: URL + let email: String + + init(resendEmailURL: URL, email: String) { + self.resendEmailURL = resendEmailURL + self.email = email + } + + deinit { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", (#file as NSString).lastPathComponent, #line, #function) + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift index 24b7ec3ad..92897090c 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift @@ -81,6 +81,10 @@ extension Mastodon.API { static let joinMastodonEndpointURL = URL(string: "https://api.joinmastodon.org/")! + public static func resendEmailURL(domain: String) -> URL { + return URL(string: "https://" + domain + "/auth/confirmation/new")! + } + } extension Mastodon.API { From 5dbd015b1685c0e2cbfb16912ab1e3935af87753 Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Thu, 25 Feb 2021 15:39:48 +0800 Subject: [PATCH 05/12] chore: add OnboardingAppearance --- Localization/app.json | 14 +++-- Mastodon.xcodeproj/project.pbxproj | 8 +++ Mastodon/Generated/Strings.swift | 14 +++-- .../OnboardingViewControllerAppearance.swift | 30 ++++++++++ .../Resources/en.lproj/Localizable.strings | 10 ++-- .../AuthenticationViewController.swift | 6 +- .../MastodonConfirmEmailViewController.swift | 56 ++++++++++++------- .../MastodonConfirmEmailViewModel.swift | 24 +------- .../MastodonRegisterViewController.swift | 12 ++-- .../MastodonResendEmailViewController.swift | 2 +- .../MastodonResendEmailViewModel.swift | 11 ++++ ...EmailViewModelNavigationDelegateShim.swift | 33 +++++++++++ .../MastodonServerRulesViewController.swift | 7 +-- 13 files changed, 154 insertions(+), 73 deletions(-) create mode 100644 Mastodon/Protocol/OnboardingViewControllerAppearance.swift create mode 100644 Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModelNavigationDelegateShim.swift diff --git a/Localization/app.json b/Localization/app.json index 19bf46537..cb74deb8c 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -79,17 +79,19 @@ "title": "One last thing.", "subtitle": "We just sent an email to %@,\ntap the link to confirm your account.", "button": { - "open_email_app": "Open email app", + "open_email_app": "Open Email App", "dont_receive_email": "I never got an email" }, "dont_receive_email": { - "alert_title": "It’s too soon to tell.", - "alert_description": "Give our servers another n seconds before sending another email.\nCheck if your email address is correct as well as your junk folder if you haven’t." + "title": "Check your email", + "description": "Check if your email address is correct as well as your junk folder if you haven’t.", + "resend_email": "Resend email" }, "open_email_app": { - "alert_title": "Check your inbox.", - "alert_description": "We just sent you another email. Check your junk folder if you haven’t.", - "mail": "Mail" + "title": "Check your inbox.", + "description": "We just sent you an email. Check your junk folder if you haven’t.", + "mail": "Mail", + "open_email_client": "Open Email Client" } }, "home_timeline": { diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index b4eb91e4f..27e648a55 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -57,6 +57,8 @@ 2D76319F25C1521200929FB9 /* StatusSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76319E25C1521200929FB9 /* StatusSection.swift */; }; 2D7631A825C1535600929FB9 /* StatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D7631A725C1535600929FB9 /* StatusTableViewCell.swift */; }; 2D7631B325C159F700929FB9 /* Item.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D7631B225C159F700929FB9 /* Item.swift */; }; + 2D82B9FF25E7863200E36F0F /* OnboardingViewControllerAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D82B9FE25E7863200E36F0F /* OnboardingViewControllerAppearance.swift */; }; + 2D82BA0525E7897700E36F0F /* MastodonResendEmailViewModelNavigationDelegateShim.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D82BA0425E7897700E36F0F /* MastodonResendEmailViewModelNavigationDelegateShim.swift */; }; 2D927F0225C7E4F2004F19B8 /* Mention.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D927F0125C7E4F2004F19B8 /* Mention.swift */; }; 2D927F0825C7E9A8004F19B8 /* Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D927F0725C7E9A8004F19B8 /* Tag.swift */; }; 2D927F0E25C7E9C9004F19B8 /* History.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D927F0D25C7E9C9004F19B8 /* History.swift */; }; @@ -251,6 +253,8 @@ 2D76319E25C1521200929FB9 /* StatusSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusSection.swift; sourceTree = ""; }; 2D7631A725C1535600929FB9 /* StatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusTableViewCell.swift; sourceTree = ""; }; 2D7631B225C159F700929FB9 /* Item.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Item.swift; sourceTree = ""; }; + 2D82B9FE25E7863200E36F0F /* OnboardingViewControllerAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewControllerAppearance.swift; sourceTree = ""; }; + 2D82BA0425E7897700E36F0F /* MastodonResendEmailViewModelNavigationDelegateShim.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewModelNavigationDelegateShim.swift; sourceTree = ""; }; 2D927F0125C7E4F2004F19B8 /* Mention.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mention.swift; sourceTree = ""; }; 2D927F0725C7E9A8004F19B8 /* Tag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tag.swift; sourceTree = ""; }; 2D927F0D25C7E9C9004F19B8 /* History.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = History.swift; sourceTree = ""; }; @@ -455,6 +459,7 @@ children = ( 2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */, 2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */, + 2D82BA0425E7897700E36F0F /* MastodonResendEmailViewModelNavigationDelegateShim.swift */, ); path = ResendEmail; sourceTree = ""; @@ -548,6 +553,7 @@ 2D38F1C525CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift */, 2D38F20725CD491300561493 /* DisposeBagCollectable.swift */, 2D5A3D3725CF8D9F002347D6 /* ScrollViewContainer.swift */, + 2D82B9FE25E7863200E36F0F /* OnboardingViewControllerAppearance.swift */, ); path = Protocol; sourceTree = ""; @@ -1386,6 +1392,7 @@ 2DA7D04425CA52B200804E11 /* TimelineLoaderTableViewCell.swift in Sources */, DB8AF52F25C13561002E6C99 /* DocumentStore.swift in Sources */, DB9D6C2425E502C60051B173 /* MosaicImageViewModel.swift in Sources */, + 2D82BA0525E7897700E36F0F /* MastodonResendEmailViewModelNavigationDelegateShim.swift in Sources */, 2D38F1EB25CD477000561493 /* HomeTimelineViewModel+LoadLatestState.swift in Sources */, DBD9149025DF6D8D00903DFD /* APIService+Onboarding.swift in Sources */, DB98337F25C9452D00AD9700 /* APIService+APIError.swift in Sources */, @@ -1393,6 +1400,7 @@ DBE0822425CD3F1E00FD6BBD /* MastodonRegisterViewModel.swift in Sources */, 2DF75B9B25D0E27500694EC8 /* StatusProviderFacade.swift in Sources */, DB5086A525CC0B7000C2C187 /* AvatarBarButtonItem.swift in Sources */, + 2D82B9FF25E7863200E36F0F /* OnboardingViewControllerAppearance.swift in Sources */, 2D38F1E525CD46C100561493 /* HomeTimelineViewModel.swift in Sources */, 2D76316B25C14D4C00929FB9 /* PublicTimelineViewModel.swift in Sources */, 2D38F1DF25CD46A400561493 /* HomeTimelineViewController+StatusProvider.swift in Sources */, diff --git a/Mastodon/Generated/Strings.swift b/Mastodon/Generated/Strings.swift index a5cd7a9d7..bfb8db80e 100644 --- a/Mastodon/Generated/Strings.swift +++ b/Mastodon/Generated/Strings.swift @@ -86,17 +86,21 @@ internal enum L10n { } internal enum DontReceiveEmail { /// Give our servers another n seconds before sending another email.\nCheck if your email address is correct as well as your junk folder if you haven’t. - internal static let alertDescription = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.AlertDescription") + internal static let description = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.Description") + /// Resend Email + internal static let resendEmail = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.ResendEmail") /// It’s too soon to tell. - internal static let alertTitle = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.AlertTitle") + internal static let title = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.Title") } internal enum OpenEmailApp { /// We just sent you another email. Check your junk folder if you haven’t. - internal static let alertDescription = L10n.tr("Localizable", "Scene.ConfirmEmail.OpenEmailApp.AlertDescription") - /// Check your inbox. - internal static let alertTitle = L10n.tr("Localizable", "Scene.ConfirmEmail.OpenEmailApp.AlertTitle") + internal static let description = L10n.tr("Localizable", "Scene.ConfirmEmail.OpenEmailApp.Description") /// Mail internal static let mail = L10n.tr("Localizable", "Scene.ConfirmEmail.OpenEmailApp.Mail") + /// Open Email Client + internal static let openEmailClient = L10n.tr("Localizable", "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient") + /// Check your inbox. + internal static let title = L10n.tr("Localizable", "Scene.ConfirmEmail.OpenEmailApp.Title") } } internal enum HomeTimeline { diff --git a/Mastodon/Protocol/OnboardingViewControllerAppearance.swift b/Mastodon/Protocol/OnboardingViewControllerAppearance.swift new file mode 100644 index 000000000..8e1a5a122 --- /dev/null +++ b/Mastodon/Protocol/OnboardingViewControllerAppearance.swift @@ -0,0 +1,30 @@ +// +// OnboardingViewControllerAppearance.swift +// Mastodon +// +// Created by sxiaojian on 2021/2/25. +// + +import UIKit + +protocol OnboardingViewControllerAppearance: UIViewController { + func setupOnboardingAppearance() +} + +extension OnboardingViewControllerAppearance { + func setupOnboardingAppearance() { + overrideUserInterfaceStyle = .light + view.backgroundColor = Asset.Colors.Background.onboardingBackground.color + + // set navigationBar transparent + let barAppearance = UINavigationBarAppearance() + barAppearance.configureWithTransparentBackground() + navigationController?.navigationBar.standardAppearance = barAppearance + navigationController?.navigationBar.compactAppearance = barAppearance + navigationController?.navigationBar.scrollEdgeAppearance = barAppearance + + let backItem = UIBarButtonItem() + backItem.title = "back" + navigationController?.navigationBar.topItem?.backBarButtonItem = backItem + } +} diff --git a/Mastodon/Resources/en.lproj/Localizable.strings b/Mastodon/Resources/en.lproj/Localizable.strings index c9c731c6b..1311dcc60 100644 --- a/Mastodon/Resources/en.lproj/Localizable.strings +++ b/Mastodon/Resources/en.lproj/Localizable.strings @@ -21,12 +21,14 @@ "Common.Countable.Photo.Single" = "photo"; "Scene.ConfirmEmail.Button.DontReceiveEmail" = "I never got an email"; "Scene.ConfirmEmail.Button.OpenEmailApp" = "Open email app"; -"Scene.ConfirmEmail.DontReceiveEmail.AlertDescription" = "Give our servers another n seconds before sending another email. +"Scene.ConfirmEmail.DontReceiveEmail.Description" = "Give our servers another n seconds before sending another email. Check if your email address is correct as well as your junk folder if you haven’t."; -"Scene.ConfirmEmail.DontReceiveEmail.AlertTitle" = "It’s too soon to tell."; -"Scene.ConfirmEmail.OpenEmailApp.AlertDescription" = "We just sent you another email. Check your junk folder if you haven’t."; -"Scene.ConfirmEmail.OpenEmailApp.AlertTitle" = "Check your inbox."; +"Scene.ConfirmEmail.DontReceiveEmail.ResendEmail" = "Resend Email"; +"Scene.ConfirmEmail.DontReceiveEmail.Title" = "It’s too soon to tell."; +"Scene.ConfirmEmail.OpenEmailApp.Description" = "We just sent you another email. Check your junk folder if you haven’t."; "Scene.ConfirmEmail.OpenEmailApp.Mail" = "Mail"; +"Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Open Email Client"; +"Scene.ConfirmEmail.OpenEmailApp.Title" = "Check your inbox."; "Scene.ConfirmEmail.Subtitle" = "We just sent an email to %@, tap the link to confirm your account."; "Scene.ConfirmEmail.Title" = "One last thing."; diff --git a/Mastodon/Scene/Authentication/AuthenticationViewController.swift b/Mastodon/Scene/Authentication/AuthenticationViewController.swift index d93651ba5..5236bb927 100644 --- a/Mastodon/Scene/Authentication/AuthenticationViewController.swift +++ b/Mastodon/Scene/Authentication/AuthenticationViewController.swift @@ -11,7 +11,7 @@ import Combine import MastodonSDK import UITextField_Shake -final class AuthenticationViewController: UIViewController, NeedsDependency { +final class AuthenticationViewController: UIViewController, NeedsDependency, OnboardingViewControllerAppearance{ var disposeBag = Set() @@ -77,9 +77,7 @@ extension AuthenticationViewController { override func viewDidLoad() { super.viewDidLoad() - overrideUserInterfaceStyle = .dark // FIXME: - - view.backgroundColor = Asset.Colors.Background.systemBackground.color + self.setupOnboardingAppearance() domainLabel.translatesAutoresizingMaskIntoConstraints = false view.addSubview(domainLabel) diff --git a/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift index ff41740b2..b83cb80d1 100644 --- a/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift +++ b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift @@ -6,11 +6,12 @@ // import Combine +import MastodonSDK +import os.log import ThirdPartyMailer import UIKit -import MastodonSDK -final class MastodonConfirmEmailViewController: UIViewController, NeedsDependency { +final class MastodonConfirmEmailViewController: UIViewController, NeedsDependency, OnboardingViewControllerAppearance { var disposeBag = Set() weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } @@ -39,7 +40,7 @@ final class MastodonConfirmEmailViewController: UIViewController, NeedsDependenc let button = UIButton(type: .system) button.titleLabel?.font = .preferredFont(forTextStyle: .headline) button.setBackgroundImage(UIImage.placeholder(color: Asset.Colors.lightBrandBlue.color), for: .normal) - button.setTitleColor(.white, for: .normal) + button.setTitleColor(Asset.Colors.Label.primary.color, for: .normal) button.setTitle(L10n.Scene.ConfirmEmail.Button.openEmailApp, for: .normal) button.layer.masksToBounds = true button.layer.cornerRadius = 8 @@ -63,17 +64,11 @@ extension MastodonConfirmEmailViewController { super.viewWillAppear(animated) navigationController?.setNavigationBarHidden(false, animated: false) } - override func viewDidLoad() { - overrideUserInterfaceStyle = .light - view.backgroundColor = Asset.Colors.Background.onboardingBackground.color - - // set navigationBar transparent - let barAppearance = UINavigationBarAppearance() - barAppearance.configureWithTransparentBackground() - navigationController?.navigationBar.standardAppearance = barAppearance - navigationController?.navigationBar.compactAppearance = barAppearance - navigationController?.navigationBar.scrollEdgeAppearance = barAppearance + override func viewDidLoad() { + + self.setupOnboardingAppearance() + // resizedView let resizedView = UIView() resizedView.translatesAutoresizingMaskIntoConstraints = false @@ -103,12 +98,31 @@ extension MastodonConfirmEmailViewController { NSLayoutConstraint.activate([ self.openEmailButton.heightAnchor.constraint(equalToConstant: 46), ]) + + self.viewModel.timestampUpdatePublisher + .sink { [weak self] _ in + guard let self = self else { return } + AuthenticationViewModel.verifyAndSaveAuthentication(context: self.context, info: self.viewModel.authenticateInfo, userToken: self.viewModel.userToken) + .receive(on: DispatchQueue.main) + .sink { completion in + switch completion { + case .failure(let error): + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: swap user access token swap fail: %s", (#file as NSString).lastPathComponent, #line, #function, error.localizedDescription) + case .finished: + break + } + } receiveValue: { _ in + self.coordinator.setup() + } + .store(in: &self.disposeBag) + } + .store(in: &self.disposeBag) } } extension MastodonConfirmEmailViewController { @objc private func openEmailButtonPressed(_ sender: UIButton) { - let alertController = UIAlertController(title: L10n.Scene.ConfirmEmail.OpenEmailApp.alertTitle, message: L10n.Scene.ConfirmEmail.OpenEmailApp.alertDescription, preferredStyle: .alert) + let alertController = UIAlertController(title: L10n.Scene.ConfirmEmail.OpenEmailApp.title, message: L10n.Scene.ConfirmEmail.OpenEmailApp.description, preferredStyle: .alert) let openEmailAction = UIAlertAction(title: L10n.Scene.ConfirmEmail.Button.openEmailApp, style: .default) { [weak self] _ in guard let self = self else { return } self.showEmailAppAlert() @@ -121,12 +135,15 @@ extension MastodonConfirmEmailViewController { } @objc private func dontReceiveButtonPressed(_ sender: UIButton) { - let alertController = UIAlertController(title: L10n.Scene.ConfirmEmail.DontReceiveEmail.alertTitle, message: L10n.Scene.ConfirmEmail.DontReceiveEmail.alertDescription, preferredStyle: .alert) - let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default) { _ in - let url = Mastodon.API.resendEmailURL(domain:self.viewModel.authenticateInfo.domain) + let alertController = UIAlertController(title: L10n.Scene.ConfirmEmail.DontReceiveEmail.title, message: L10n.Scene.ConfirmEmail.DontReceiveEmail.description, preferredStyle: .alert) + let resendAction = UIAlertAction(title: L10n.Scene.ConfirmEmail.DontReceiveEmail.resendEmail, style: .default) { _ in + let url = Mastodon.API.resendEmailURL(domain: self.viewModel.authenticateInfo.domain) let viewModel = MastodonResendEmailViewModel(resendEmailURL: url, email: self.viewModel.email) - self.coordinator.present(scene: .mastodonResendEmail(viewModel: viewModel), from: self, transition: .show) + self.coordinator.present(scene: .mastodonResendEmail(viewModel: viewModel), from: self, transition: .modal(animated: true, completion: nil)) } + let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default) { _ in + } + alertController.addAction(resendAction) alertController.addAction(okAction) self.coordinator.present(scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil)) } @@ -137,7 +154,7 @@ extension MastodonConfirmEmailViewController { let avaliableClients = clients.filter { client -> Bool in ThirdPartyMailer.application(application, isMailClientAvailable: client) } - let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .alert) + let alertController = UIAlertController(title: L10n.Scene.ConfirmEmail.OpenEmailApp.openEmailClient, message: nil, preferredStyle: .alert) let alertAction = UIAlertAction(title: L10n.Scene.ConfirmEmail.OpenEmailApp.mail, style: .default) { _ in UIApplication.shared.open(URL(string: "message://")!, options: [:], completionHandler: nil) @@ -153,6 +170,5 @@ extension MastodonConfirmEmailViewController { let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel, handler: nil) alertController.addAction(cancelAction) self.coordinator.present(scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil)) - } } diff --git a/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewModel.swift b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewModel.swift index d1e3936a2..aff254741 100644 --- a/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewModel.swift +++ b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewModel.swift @@ -8,13 +8,11 @@ import Combine import Foundation import MastodonSDK -import os.log final class MastodonConfirmEmailViewModel { var disposeBag = Set() let context: AppContext - let coordinator: SceneCoordinator var email: String let authenticateInfo: AuthenticationViewModel.AuthenticateInfo let userToken: Mastodon.Entity.Token @@ -24,30 +22,10 @@ final class MastodonConfirmEmailViewModel { .share() .eraseToAnyPublisher() - init(context: AppContext,coordinator: SceneCoordinator, email: String, authenticateInfo: AuthenticationViewModel.AuthenticateInfo, userToken: Mastodon.Entity.Token) { + init(context: AppContext, email: String, authenticateInfo: AuthenticationViewModel.AuthenticateInfo, userToken: Mastodon.Entity.Token) { self.context = context - self.coordinator = coordinator self.email = email self.authenticateInfo = authenticateInfo self.userToken = userToken - timestampUpdatePublisher - .sink { [weak self] _ in - guard let self = self else { return } - AuthenticationViewModel.verifyAndSaveAuthentication(context: self.context, info: authenticateInfo, userToken: userToken) - .receive(on: DispatchQueue.main) - .sink { completion in - switch completion { - case .failure(let error): - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: swap user access token swap fail: %s", ((#file as NSString).lastPathComponent), #line, #function, error.localizedDescription) - case .finished: - break - } - } receiveValue: { _ in - self.coordinator.setup() - } - .store(in: &self.disposeBag) - - } - .store(in: &disposeBag) } } diff --git a/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift b/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift index 1ee306cf1..aaded394c 100644 --- a/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift +++ b/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift @@ -11,7 +11,7 @@ import os.log import UIKit import UITextField_Shake -final class MastodonRegisterViewController: UIViewController, NeedsDependency { +final class MastodonRegisterViewController: UIViewController, NeedsDependency, OnboardingViewControllerAppearance { var disposeBag = Set() weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } @@ -196,8 +196,8 @@ extension MastodonRegisterViewController { override func viewDidLoad() { super.viewDidLoad() - overrideUserInterfaceStyle = .light - view.backgroundColor = Asset.Colors.Background.onboardingBackground.color + self.setupOnboardingAppearance() + domainLabel.text = "@" + viewModel.domain + " " domainLabel.sizeToFit() passwordCheckLabel.attributedText = viewModel.attributeStringForPassword() @@ -451,7 +451,7 @@ extension MastodonRegisterViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - navigationController?.setNavigationBarHidden(true, animated: false) + navigationController?.setNavigationBarHidden(false, animated: false) } } @@ -568,11 +568,11 @@ extension MastodonRegisterViewController { } receiveValue: { [weak self] response in guard let self = self else { return } let userToken = response.value - // TODO: + let alertController = UIAlertController(title: L10n.Scene.Register.success, message: L10n.Scene.Register.checkEmail, preferredStyle: .alert) let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default) { [weak self] _ in guard let self = self else { return } - let viewModel = MastodonConfirmEmailViewModel(context: self.context, coordinator: self.coordinator, email: email, authenticateInfo: self.viewModel.authenticateInfo, userToken: userToken) + let viewModel = MastodonConfirmEmailViewModel(context: self.context, email: email, authenticateInfo: self.viewModel.authenticateInfo, userToken: userToken) self.coordinator.present(scene: .mastodonConfirmEmail(viewModel: viewModel), from: self, transition: .show) } alertController.addAction(okAction) diff --git a/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewController.swift b/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewController.swift index e54baa137..1a16067cf 100644 --- a/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewController.swift +++ b/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewController.swift @@ -53,7 +53,7 @@ extension MastodonResendEmailViewController { ]) let request = URLRequest(url: viewModel.resendEmailURL) - webView.navigationDelegate = self + webView.navigationDelegate = self.viewModel.navigationDelegate webView.load(request) os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: resendEmail via: %s", (#file as NSString).lastPathComponent, #line, #function, viewModel.resendEmailURL.debugDescription) } diff --git a/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModel.swift b/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModel.swift index 861d7d7f7..e8e16e6e5 100644 --- a/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModel.swift +++ b/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModel.swift @@ -15,6 +15,8 @@ final class MastodonResendEmailViewModel { let resendEmailURL: URL let email: String + private var navigationDelegateShim: MastodonResendEmailViewModelNavigationDelegateShim? + init(resendEmailURL: URL, email: String) { self.resendEmailURL = resendEmailURL self.email = email @@ -24,3 +26,12 @@ final class MastodonResendEmailViewModel { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", (#file as NSString).lastPathComponent, #line, #function) } } +extension MastodonResendEmailViewModel { + + var navigationDelegate: WKNavigationDelegate { + let navigationDelegateShim = MastodonResendEmailViewModelNavigationDelegateShim(viewModel: self) + self.navigationDelegateShim = navigationDelegateShim + return navigationDelegateShim + } + +} diff --git a/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModelNavigationDelegateShim.swift b/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModelNavigationDelegateShim.swift new file mode 100644 index 000000000..ae7047f45 --- /dev/null +++ b/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModelNavigationDelegateShim.swift @@ -0,0 +1,33 @@ +// +// MastodonResendEmailViewModelNavigationDelegateShim.swift +// Mastodon +// +// Created by sxiaojian on 2021/2/25. +// + +import os.log +import Foundation +import WebKit + +final class MastodonResendEmailViewModelNavigationDelegateShim: NSObject { + + weak var viewModel: MastodonResendEmailViewModel? + + init(viewModel: MastodonResendEmailViewModel) { + self.viewModel = viewModel + } + + deinit { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + } +} + + +// MARK: - WKNavigationDelegate +extension MastodonResendEmailViewModelNavigationDelegateShim: WKNavigationDelegate { + + func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { + + } + +} diff --git a/Mastodon/Scene/Authentication/ServerRules/MastodonServerRulesViewController.swift b/Mastodon/Scene/Authentication/ServerRules/MastodonServerRulesViewController.swift index 826a8731a..4f23a6134 100644 --- a/Mastodon/Scene/Authentication/ServerRules/MastodonServerRulesViewController.swift +++ b/Mastodon/Scene/Authentication/ServerRules/MastodonServerRulesViewController.swift @@ -8,7 +8,7 @@ import os.log import UIKit -final class MastodonServerRulesViewController: UIViewController, NeedsDependency { +final class MastodonServerRulesViewController: UIViewController, NeedsDependency ,OnboardingViewControllerAppearance{ weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } @@ -78,8 +78,7 @@ extension MastodonServerRulesViewController { override func viewDidLoad() { super.viewDidLoad() - overrideUserInterfaceStyle = .light - view.backgroundColor = Asset.Colors.Background.onboardingBackground.color + self.setupOnboardingAppearance() bottonContainerView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(bottonContainerView) @@ -144,7 +143,7 @@ extension MastodonServerRulesViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - navigationController?.setNavigationBarHidden(true, animated: false) + navigationController?.setNavigationBarHidden(false, animated: false) } } From 5fbb47470c97e367060452b2a9887cc7f89c88b6 Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Thu, 25 Feb 2021 15:44:14 +0800 Subject: [PATCH 06/12] chore: update generated Strings --- Mastodon/Generated/Strings.swift | 10 +++++----- Mastodon/Resources/en.lproj/Localizable.strings | 11 +++++------ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Mastodon/Generated/Strings.swift b/Mastodon/Generated/Strings.swift index fee851c20..60edbeef5 100644 --- a/Mastodon/Generated/Strings.swift +++ b/Mastodon/Generated/Strings.swift @@ -93,19 +93,19 @@ internal enum L10n { internal enum Button { /// I never got an email internal static let dontReceiveEmail = L10n.tr("Localizable", "Scene.ConfirmEmail.Button.DontReceiveEmail") - /// Open email app + /// Open Email App internal static let openEmailApp = L10n.tr("Localizable", "Scene.ConfirmEmail.Button.OpenEmailApp") } internal enum DontReceiveEmail { - /// Give our servers another n seconds before sending another email.\nCheck if your email address is correct as well as your junk folder if you haven’t. + /// Check if your email address is correct as well as your junk folder if you haven’t. internal static let description = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.Description") - /// Resend Email + /// Resend email internal static let resendEmail = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.ResendEmail") - /// It’s too soon to tell. + /// Check your email internal static let title = L10n.tr("Localizable", "Scene.ConfirmEmail.DontReceiveEmail.Title") } internal enum OpenEmailApp { - /// We just sent you another email. Check your junk folder if you haven’t. + /// We just sent you an email. Check your junk folder if you haven’t. internal static let description = L10n.tr("Localizable", "Scene.ConfirmEmail.OpenEmailApp.Description") /// Mail internal static let mail = L10n.tr("Localizable", "Scene.ConfirmEmail.OpenEmailApp.Mail") diff --git a/Mastodon/Resources/en.lproj/Localizable.strings b/Mastodon/Resources/en.lproj/Localizable.strings index 08f872c8d..3c91e924e 100644 --- a/Mastodon/Resources/en.lproj/Localizable.strings +++ b/Mastodon/Resources/en.lproj/Localizable.strings @@ -23,12 +23,11 @@ "Common.Countable.Photo.Multiple" = "photos"; "Common.Countable.Photo.Single" = "photo"; "Scene.ConfirmEmail.Button.DontReceiveEmail" = "I never got an email"; -"Scene.ConfirmEmail.Button.OpenEmailApp" = "Open email app"; -"Scene.ConfirmEmail.DontReceiveEmail.Description" = "Give our servers another n seconds before sending another email. -Check if your email address is correct as well as your junk folder if you haven’t."; -"Scene.ConfirmEmail.DontReceiveEmail.ResendEmail" = "Resend Email"; -"Scene.ConfirmEmail.DontReceiveEmail.Title" = "It’s too soon to tell."; -"Scene.ConfirmEmail.OpenEmailApp.Description" = "We just sent you another email. Check your junk folder if you haven’t."; +"Scene.ConfirmEmail.Button.OpenEmailApp" = "Open Email App"; +"Scene.ConfirmEmail.DontReceiveEmail.Description" = "Check if your email address is correct as well as your junk folder if you haven’t."; +"Scene.ConfirmEmail.DontReceiveEmail.ResendEmail" = "Resend email"; +"Scene.ConfirmEmail.DontReceiveEmail.Title" = "Check your email"; +"Scene.ConfirmEmail.OpenEmailApp.Description" = "We just sent you an email. Check your junk folder if you haven’t."; "Scene.ConfirmEmail.OpenEmailApp.Mail" = "Mail"; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Open Email Client"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Check your inbox."; From d5dcfca1c331650310e8f8ea64385496747e044f Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Thu, 25 Feb 2021 15:46:32 +0800 Subject: [PATCH 07/12] chore: add script to generate Strings file --- convertAppJson.sh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100755 convertAppJson.sh diff --git a/convertAppJson.sh b/convertAppJson.sh new file mode 100755 index 000000000..ef3a05387 --- /dev/null +++ b/convertAppJson.sh @@ -0,0 +1,24 @@ +#!/bin/zsh + +SRCROOT=`pwd` +echo ${SRCROOT} +# task1 generate strings file +cd ${SRCROOT}/Localization/StringsConvertor +sh ./scripts/build.sh + +# task2 copy strings file /Localization/StringsConvertor/output to /Mastodon/Resources + +cp -r ${SRCROOT}/Localization/StringsConvertor/output/ ${SRCROOT}/Mastodon/Resources/ + +# task3 swiftgen +cd ${SRCROOT} + +if command -v swiftgen >/dev/null 2>&1; then + swiftgen +else + echo "please install swiftgen by run brew install swiftgen" +fi + +#task4 clean temp file +rm -rf ${SRCROOT}/Localization/StringsConvertor/output +rm -rf ${SRCROOT}/Localization/StringsConvertor/intput From fa4b349e06a0070ff517dfb4ced690176904a42a Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Thu, 25 Feb 2021 16:04:14 +0800 Subject: [PATCH 08/12] chore: update generated Strings --- Localization/app.json | 1 + Mastodon/Generated/Strings.swift | 2 ++ Mastodon/Protocol/OnboardingViewControllerAppearance.swift | 2 +- Mastodon/Resources/en.lproj/Localizable.strings | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Localization/app.json b/Localization/app.json index f79d9945a..6ab65832f 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -11,6 +11,7 @@ }, "controls": { "actions": { + "back": "Back", "add": "Add", "remove": "Remove", "edit": "Edit", diff --git a/Mastodon/Generated/Strings.swift b/Mastodon/Generated/Strings.swift index 60edbeef5..c032874d9 100644 --- a/Mastodon/Generated/Strings.swift +++ b/Mastodon/Generated/Strings.swift @@ -26,6 +26,8 @@ internal enum L10n { internal enum Actions { /// Add internal static let add = L10n.tr("Localizable", "Common.Controls.Actions.Add") + /// Back + internal static let back = L10n.tr("Localizable", "Common.Controls.Actions.Back") /// Cancel internal static let cancel = L10n.tr("Localizable", "Common.Controls.Actions.Cancel") /// Confirm diff --git a/Mastodon/Protocol/OnboardingViewControllerAppearance.swift b/Mastodon/Protocol/OnboardingViewControllerAppearance.swift index 8e1a5a122..ea723e3cc 100644 --- a/Mastodon/Protocol/OnboardingViewControllerAppearance.swift +++ b/Mastodon/Protocol/OnboardingViewControllerAppearance.swift @@ -24,7 +24,7 @@ extension OnboardingViewControllerAppearance { navigationController?.navigationBar.scrollEdgeAppearance = barAppearance let backItem = UIBarButtonItem() - backItem.title = "back" + backItem.title = L10n.Common.Controls.Actions.back navigationController?.navigationBar.topItem?.backBarButtonItem = backItem } } diff --git a/Mastodon/Resources/en.lproj/Localizable.strings b/Mastodon/Resources/en.lproj/Localizable.strings index 3c91e924e..de05b7ffb 100644 --- a/Mastodon/Resources/en.lproj/Localizable.strings +++ b/Mastodon/Resources/en.lproj/Localizable.strings @@ -1,6 +1,7 @@ "Common.Alerts.ServerError.Title" = "Server Error"; "Common.Alerts.SignUpFailure.Title" = "Sign Up Failure"; "Common.Controls.Actions.Add" = "Add"; +"Common.Controls.Actions.Back" = "Back"; "Common.Controls.Actions.Cancel" = "Cancel"; "Common.Controls.Actions.Confirm" = "Confirm"; "Common.Controls.Actions.Continue" = "Continue"; From 74c19c9746357578d78a4bba078da11d35ac6e0a Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Thu, 25 Feb 2021 16:20:42 +0800 Subject: [PATCH 09/12] chore: fill email in MastodonResendEmailViewModelNavigationDelegateShim --- .../ResendEmail/MastodonResendEmailViewController.swift | 7 ------- ...astodonResendEmailViewModelNavigationDelegateShim.swift | 6 +++++- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewController.swift b/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewController.swift index 1a16067cf..a10755fe3 100644 --- a/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewController.swift +++ b/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewController.swift @@ -59,13 +59,6 @@ extension MastodonResendEmailViewController { } } -extension MastodonResendEmailViewController { - func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { - let scriptString = "document.getElementById('user_email').value = '\(self.viewModel.email)';" - webView.evaluateJavaScript(scriptString) - } -} - extension MastodonResendEmailViewController { @objc private func cancelBarButtonItemPressed(_ sender: UIBarButtonItem) { dismiss(animated: true, completion: nil) diff --git a/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModelNavigationDelegateShim.swift b/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModelNavigationDelegateShim.swift index ae7047f45..4a27de96d 100644 --- a/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModelNavigationDelegateShim.swift +++ b/Mastodon/Scene/Authentication/ResendEmail/MastodonResendEmailViewModelNavigationDelegateShim.swift @@ -27,7 +27,11 @@ final class MastodonResendEmailViewModelNavigationDelegateShim: NSObject { extension MastodonResendEmailViewModelNavigationDelegateShim: WKNavigationDelegate { func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { - + guard let email = self.viewModel?.email else { + return + } + let scriptString = "document.getElementById('user_email').value = '\(email)';" + webView.evaluateJavaScript(scriptString) } } From 9489fbfa1aa17f44e5f1b1451352639ac4b22c0b Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Thu, 25 Feb 2021 16:37:25 +0800 Subject: [PATCH 10/12] chore: change button color to .white --- .../ConfirmEmail/MastodonConfirmEmailViewController.swift | 2 +- .../Register/MastodonRegisterViewController.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift index b83cb80d1..3bf7f78c4 100644 --- a/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift +++ b/Mastodon/Scene/Authentication/ConfirmEmail/MastodonConfirmEmailViewController.swift @@ -40,7 +40,7 @@ final class MastodonConfirmEmailViewController: UIViewController, NeedsDependenc let button = UIButton(type: .system) button.titleLabel?.font = .preferredFont(forTextStyle: .headline) button.setBackgroundImage(UIImage.placeholder(color: Asset.Colors.lightBrandBlue.color), for: .normal) - button.setTitleColor(Asset.Colors.Label.primary.color, for: .normal) + button.setTitleColor(.white, for: .normal) button.setTitle(L10n.Scene.ConfirmEmail.Button.openEmailApp, for: .normal) button.layer.masksToBounds = true button.layer.cornerRadius = 8 diff --git a/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift b/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift index ad2c1976d..074d5c762 100644 --- a/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift +++ b/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift @@ -176,7 +176,7 @@ final class MastodonRegisterViewController: UIViewController, NeedsDependency, O button.setBackgroundImage(UIImage.placeholder(color: Asset.Colors.lightBrandBlue.color), for: .normal) button.setBackgroundImage(UIImage.placeholder(color: Asset.Colors.lightDisabled.color), for: .disabled) button.isEnabled = false - button.setTitleColor(Asset.Colors.Label.primary.color, for: .normal) + button.setTitleColor(.white, for: .normal) button.setTitle(L10n.Common.Controls.Actions.continue, for: .normal) button.layer.masksToBounds = true button.layer.cornerRadius = 8 From ed99ca034665cf9dc01ac0acb8c8562bc7729cbf Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Thu, 25 Feb 2021 16:50:37 +0800 Subject: [PATCH 11/12] chore: rename script and use swiftgen from CococaPods --- convertAppJson.sh => update_localization.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename convertAppJson.sh => update_localization.sh (100%) diff --git a/convertAppJson.sh b/update_localization.sh similarity index 100% rename from convertAppJson.sh rename to update_localization.sh From a32cf8c18e5034ccda966bb099ce7bb99fd2c6cf Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Thu, 25 Feb 2021 16:50:37 +0800 Subject: [PATCH 12/12] chore: use swiftgen from CococaPods --- update_localization.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/update_localization.sh b/update_localization.sh index ef3a05387..b1c16c025 100755 --- a/update_localization.sh +++ b/update_localization.sh @@ -1,6 +1,8 @@ #!/bin/zsh SRCROOT=`pwd` +PODS_ROOT='Pods' + echo ${SRCROOT} # task1 generate strings file cd ${SRCROOT}/Localization/StringsConvertor @@ -12,11 +14,11 @@ cp -r ${SRCROOT}/Localization/StringsConvertor/output/ ${SRCROOT}/Mastodon/Reso # task3 swiftgen cd ${SRCROOT} - -if command -v swiftgen >/dev/null 2>&1; then - swiftgen +echo "${PODS_ROOT}/SwiftGen/bin/swiftgen" +if [[ -f "${PODS_ROOT}/SwiftGen/bin/swiftgen" ]] then + "${PODS_ROOT}/SwiftGen/bin/swiftgen" else - echo "please install swiftgen by run brew install swiftgen" + echo "Run 'pod install' or update your CocoaPods installation." fi #task4 clean temp file