From 33f1cfcc77b11073b54585f97f1a3e48da063a9a Mon Sep 17 00:00:00 2001 From: CMK Date: Tue, 2 Mar 2021 12:01:11 +0800 Subject: [PATCH 1/9] fix: server description may display in HTML format issue. resolve: #30 --- .../PickServer/TableViewCell/PickServerCell.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerCell.swift b/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerCell.swift index 0ded9392f..fef09b955 100644 --- a/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerCell.swift +++ b/Mastodon/Scene/Onboarding/PickServer/TableViewCell/PickServerCell.swift @@ -8,6 +8,7 @@ import UIKit import MastodonSDK import Kingfisher +import Kanna protocol PickServerCellDelegate: class { func pickServerCell(modeChange server: Mastodon.Entity.Server, newMode: PickServerCell.Mode, updates: (() -> Void)) @@ -326,7 +327,13 @@ extension PickServerCell { private func updateServerInfo() { guard let serverInfo = server else { return } domainLabel.text = serverInfo.domain - descriptionLabel.text = serverInfo.description + descriptionLabel.text = { + guard let html = try? HTML(html: serverInfo.description, encoding: .utf8) else { + return serverInfo.description + } + + return html.text ?? serverInfo.description + }() let processor = RoundCornerImageProcessor(cornerRadius: 3) thumbImageView.kf.indicatorType = .activity thumbImageView.kf.setImage(with: URL(string: serverInfo.proxiedThumbnail ?? "")!, placeholder: UIImage.placeholder(color: Asset.Colors.lightBackground.color), options: [ From ea511c153fa7fe0ab081dc54ed3f26e7d18fb2e6 Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Tue, 2 Mar 2021 16:19:20 +0800 Subject: [PATCH 2/9] chore: set user avatar use PhotoUI --- Mastodon.xcodeproj/project.pbxproj | 21 +++++++++ .../xcshareddata/swiftpm/Package.resolved | 9 ++++ Mastodon/Generated/Strings.swift | 2 +- .../Resources/en.lproj/Localizable.strings | 2 +- ...astodonRegisterViewController+Avatar.swift | 47 +++++++++++++++++++ .../MastodonRegisterViewController.swift | 5 ++ 6 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 9b5894130..2a7c70420 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -72,6 +72,8 @@ 2D927F0E25C7E9C9004F19B8 /* History.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D927F0D25C7E9C9004F19B8 /* History.swift */; }; 2D927F1425C7EDD9004F19B8 /* Emoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D927F1325C7EDD9004F19B8 /* Emoji.swift */; }; 2D939AB525EDD8A90076FA61 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D939AB425EDD8A90076FA61 /* String.swift */; }; + 2D939AC825EE14620076FA61 /* CropViewController in Frameworks */ = {isa = PBXBuildFile; productRef = 2D939AC725EE14620076FA61 /* CropViewController */; }; + 2D939AE825EE1CF80076FA61 /* MastodonRegisterViewController+Avatar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D939AE725EE1CF80076FA61 /* MastodonRegisterViewController+Avatar.swift */; }; 2DA7D04425CA52B200804E11 /* TimelineLoaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA7D04325CA52B200804E11 /* TimelineLoaderTableViewCell.swift */; }; 2DA7D04A25CA52CB00804E11 /* TimelineBottomLoaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA7D04925CA52CB00804E11 /* TimelineBottomLoaderTableViewCell.swift */; }; 2DA7D05725CA693F00804E11 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA7D05625CA693F00804E11 /* Application.swift */; }; @@ -279,6 +281,7 @@ 2D927F0D25C7E9C9004F19B8 /* History.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = History.swift; sourceTree = ""; }; 2D927F1325C7EDD9004F19B8 /* Emoji.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Emoji.swift; sourceTree = ""; }; 2D939AB425EDD8A90076FA61 /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = ""; }; + 2D939AE725EE1CF80076FA61 /* MastodonRegisterViewController+Avatar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MastodonRegisterViewController+Avatar.swift"; sourceTree = ""; }; 2DA7D04325CA52B200804E11 /* TimelineLoaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineLoaderTableViewCell.swift; sourceTree = ""; }; 2DA7D04925CA52CB00804E11 /* TimelineBottomLoaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineBottomLoaderTableViewCell.swift; sourceTree = ""; }; 2DA7D05025CA545E00804E11 /* LoadMoreConfigurableTableViewContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadMoreConfigurableTableViewContainer.swift; sourceTree = ""; }; @@ -395,6 +398,7 @@ DB0140BD25C40D7500F9F3CF /* CommonOSLog in Frameworks */, DB89BA0325C10FD0008580ED /* CoreDataStack.framework in Frameworks */, 2D42FF6125C8177C004A627A /* ActiveLabel in Frameworks */, + 2D939AC825EE14620076FA61 /* CropViewController in Frameworks */, 5D526FE225BE9AC400460CB9 /* MastodonSDK in Frameworks */, DB5086B825CC0D6400C2C187 /* Kingfisher in Frameworks */, 2D61336925C18A4F00CAE157 /* AlamofireNetworkActivityIndicator in Frameworks */, @@ -1079,6 +1083,7 @@ isa = PBXGroup; children = ( DBE0821425CD382600FD6BBD /* MastodonRegisterViewController.swift */, + 2D939AE725EE1CF80076FA61 /* MastodonRegisterViewController+Avatar.swift */, DBE0822325CD3F1E00FD6BBD /* MastodonRegisterViewModel.swift */, ); path = Register; @@ -1124,6 +1129,7 @@ DB0140BC25C40D7500F9F3CF /* CommonOSLog */, DB5086B725CC0D6400C2C187 /* Kingfisher */, 2D5981B925E4D7F8000FB903 /* ThirdPartyMailer */, + 2D939AC725EE14620076FA61 /* CropViewController */, ); productName = Mastodon; productReference = DB427DD225BAA00100D1B89D /* Mastodon.app */; @@ -1252,6 +1258,7 @@ DB0140BB25C40D7500F9F3CF /* XCRemoteSwiftPackageReference "CommonOSLog" */, DB5086B625CC0D6400C2C187 /* XCRemoteSwiftPackageReference "Kingfisher" */, 2D5981B825E4D7F8000FB903 /* XCRemoteSwiftPackageReference "ThirdPartyMailer" */, + 2D939AC625EE14620076FA61 /* XCRemoteSwiftPackageReference "TOCropViewController" */, ); productRefGroup = DB427DD325BAA00100D1B89D /* Products */; projectDirPath = ""; @@ -1493,6 +1500,7 @@ 2DF75BA125D0E29D00694EC8 /* StatusProvider+TimelinePostTableViewCellDelegate.swift in Sources */, 2D42FF7E25C82218004A627A /* ActionToolBarContainer.swift in Sources */, DB0140A125C40C0600F9F3CF /* MastodonPinBasedAuthenticationViewController.swift in Sources */, + 2D939AE825EE1CF80076FA61 /* MastodonRegisterViewController+Avatar.swift in Sources */, 2D5981A125E4A593000FB903 /* MastodonConfirmEmailViewModel.swift in Sources */, DB8AF55025C13703002E6C99 /* MainTabBarController.swift in Sources */, DB9D6BE925E4F5340051B173 /* SearchViewController.swift in Sources */, @@ -2099,6 +2107,14 @@ minimumVersion = 3.1.0; }; }; + 2D939AC625EE14620076FA61 /* XCRemoteSwiftPackageReference "TOCropViewController" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/TimOliver/TOCropViewController.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 2.6.0; + }; + }; DB0140BB25C40D7500F9F3CF /* XCRemoteSwiftPackageReference "CommonOSLog" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/MainasuK/CommonOSLog"; @@ -2141,6 +2157,11 @@ package = 2D61336725C18A4F00CAE157 /* XCRemoteSwiftPackageReference "AlamofireNetworkActivityIndicator" */; productName = AlamofireNetworkActivityIndicator; }; + 2D939AC725EE14620076FA61 /* CropViewController */ = { + isa = XCSwiftPackageProductDependency; + package = 2D939AC625EE14620076FA61 /* XCRemoteSwiftPackageReference "TOCropViewController" */; + productName = CropViewController; + }; 5D526FE125BE9AC400460CB9 /* MastodonSDK */ = { isa = XCSwiftPackageProductDependency; productName = MastodonSDK; diff --git a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved index 456a6e967..543a09da9 100644 --- a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -90,6 +90,15 @@ "revision": "923c60ee7588da47db8cfc4e0f5b96e5e605ef84", "version": "1.7.1" } + }, + { + "package": "TOCropViewController", + "repositoryURL": "https://github.com/TimOliver/TOCropViewController.git", + "state": { + "branch": null, + "revision": "dad97167bf1be16aeecd109130900995dd01c515", + "version": "2.6.0" + } } ] }, diff --git a/Mastodon/Generated/Strings.swift b/Mastodon/Generated/Strings.swift index 8e93c804e..fedb437ac 100644 --- a/Mastodon/Generated/Strings.swift +++ b/Mastodon/Generated/Strings.swift @@ -124,7 +124,7 @@ internal enum L10n { internal static let passwordTooShrot = L10n.tr("Localizable", "Common.Errors.Itemdetail.PasswordTooShrot") /// Username must only contain alphanumeric characters and underscores internal static let usernameInvalid = L10n.tr("Localizable", "Common.Errors.Itemdetail.UsernameInvalid") - /// username is too long ( can't be longer than 30 characters) + /// username is too long (can't be longer than 30 characters) internal static let usernameTooLong = L10n.tr("Localizable", "Common.Errors.Itemdetail.UsernameTooLong") } } diff --git a/Mastodon/Resources/en.lproj/Localizable.strings b/Mastodon/Resources/en.lproj/Localizable.strings index 191ec0daf..0bb8b8cb0 100644 --- a/Mastodon/Resources/en.lproj/Localizable.strings +++ b/Mastodon/Resources/en.lproj/Localizable.strings @@ -42,7 +42,7 @@ "Common.Errors.Itemdetail.EmailInvalid" = "This is not a valid e-mail address"; "Common.Errors.Itemdetail.PasswordTooShrot" = "password is too short (must be at least 8 characters)"; "Common.Errors.Itemdetail.UsernameInvalid" = "Username must only contain alphanumeric characters and underscores"; -"Common.Errors.Itemdetail.UsernameTooLong" = "username is too long ( can't be longer than 30 characters)"; +"Common.Errors.Itemdetail.UsernameTooLong" = "username is too long (can't be longer than 30 characters)"; "Scene.ConfirmEmail.Button.DontReceiveEmail" = "I never got an email"; "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."; diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift new file mode 100644 index 000000000..b25b402df --- /dev/null +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift @@ -0,0 +1,47 @@ +// +// MastodonRegisterViewController+Avatar.swift +// Mastodon +// +// Created by sxiaojian on 2021/3/2. +// + +import Foundation +import UIKit +import CropViewController +import PhotosUI +extension MastodonRegisterViewController: CropViewControllerDelegate, PHPickerViewControllerDelegate, UINavigationControllerDelegate{ + func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { + if let itemProvider = results.first?.itemProvider, itemProvider.canLoadObject(ofClass: UIImage.self) { + + itemProvider.loadObject(ofClass: UIImage.self) { [weak self] image, error in + guard let self = self, let image = image as? UIImage else { return } + DispatchQueue.main.async { + let cropController = CropViewController(croppingStyle: .default, image: image) + cropController.delegate = self + self.image = image + picker.dismiss(animated: true, completion: { + self.present(cropController, animated: true, completion: nil) + }) + } + } + } else { + picker.dismiss(animated: true, completion: { + }) + } + } + + public func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) { + self.image = image + self.photoButton.setImage(image, for: .normal) + cropViewController.dismiss(animated: true, completion: nil) + } + + @objc func avatarButtonPressed(_ sender: UIButton) { + var configuration = PHPickerConfiguration() + configuration.filter = .images + + let imagePicker = PHPickerViewController(configuration: configuration) + imagePicker.delegate = self + self.present(imagePicker, animated: true, completion: nil) + } +} diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift index 9931a8b19..cc64be1f0 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift @@ -17,6 +17,9 @@ final class MastodonRegisterViewController: UIViewController, NeedsDependency, O weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } + // avater image + var image: UIImage? + var viewModel: MastodonRegisterViewModel! let tapGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer @@ -56,6 +59,8 @@ final class MastodonRegisterViewController: UIViewController, NeedsDependency, O button.backgroundColor = .white button.layer.cornerRadius = 45 button.clipsToBounds = true + + button.addTarget(self, action: #selector(MastodonRegisterViewController.avatarButtonPressed(_:)), for: .touchUpInside) return button }() From 211f5dd0e459a994a5012ea899b2d8c998e314a3 Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Tue, 2 Mar 2021 16:27:58 +0800 Subject: [PATCH 3/9] chore: code format --- ...astodonRegisterViewController+Avatar.swift | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift index b25b402df..67bd2629e 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift @@ -5,31 +5,30 @@ // Created by sxiaojian on 2021/3/2. // -import Foundation -import UIKit import CropViewController +import Foundation import PhotosUI -extension MastodonRegisterViewController: CropViewControllerDelegate, PHPickerViewControllerDelegate, UINavigationControllerDelegate{ +import UIKit + +extension MastodonRegisterViewController: CropViewControllerDelegate, PHPickerViewControllerDelegate { func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { - if let itemProvider = results.first?.itemProvider, itemProvider.canLoadObject(ofClass: UIImage.self) { - - itemProvider.loadObject(ofClass: UIImage.self) { [weak self] image, error in - guard let self = self, let image = image as? UIImage else { return } - DispatchQueue.main.async { - let cropController = CropViewController(croppingStyle: .default, image: image) - cropController.delegate = self - self.image = image - picker.dismiss(animated: true, completion: { - self.present(cropController, animated: true, completion: nil) - }) - } + guard let itemProvider = results.first?.itemProvider, itemProvider.canLoadObject(ofClass: UIImage.self) else { + picker.dismiss(animated: true, completion: {}) + return + } + itemProvider.loadObject(ofClass: UIImage.self) { [weak self] image, _ in + guard let self = self, let image = image as? UIImage else { return } + DispatchQueue.main.async { + let cropController = CropViewController(croppingStyle: .default, image: image) + cropController.delegate = self + self.image = image + picker.dismiss(animated: true, completion: { + self.present(cropController, animated: true, completion: nil) + }) } - } else { - picker.dismiss(animated: true, completion: { - }) } } - + public func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) { self.image = image self.photoButton.setImage(image, for: .normal) @@ -39,7 +38,7 @@ extension MastodonRegisterViewController: CropViewControllerDelegate, PHPickerVi @objc func avatarButtonPressed(_ sender: UIButton) { var configuration = PHPickerConfiguration() configuration.filter = .images - + let imagePicker = PHPickerViewController(configuration: configuration) imagePicker.delegate = self self.present(imagePicker, animated: true, completion: nil) From eb2057d14e840266401f4c3d17f1f8e3c2dc63f4 Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Tue, 2 Mar 2021 16:39:43 +0800 Subject: [PATCH 4/9] chore: make sure to crop the image into a square --- .../Register/MastodonRegisterViewController+Avatar.swift | 5 +++-- .../Onboarding/Register/MastodonRegisterViewController.swift | 3 --- .../Onboarding/Register/MastodonRegisterViewModel.swift | 1 + 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift index 67bd2629e..9b3937122 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift @@ -21,7 +21,8 @@ extension MastodonRegisterViewController: CropViewControllerDelegate, PHPickerVi DispatchQueue.main.async { let cropController = CropViewController(croppingStyle: .default, image: image) cropController.delegate = self - self.image = image + cropController.setAspectRatioPreset(.presetSquare, animated: true) + cropController.aspectRatioLockEnabled = true picker.dismiss(animated: true, completion: { self.present(cropController, animated: true, completion: nil) }) @@ -30,7 +31,7 @@ extension MastodonRegisterViewController: CropViewControllerDelegate, PHPickerVi } public func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) { - self.image = image + self.viewModel.avatarImage.value = image self.photoButton.setImage(image, for: .normal) cropViewController.dismiss(animated: true, completion: nil) } diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift index cc64be1f0..81dc16f75 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift @@ -17,9 +17,6 @@ final class MastodonRegisterViewController: UIViewController, NeedsDependency, O weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } - // avater image - var image: UIImage? - var viewModel: MastodonRegisterViewModel! let tapGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewModel.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewModel.swift index a32e5d040..9e244c2de 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewModel.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewModel.swift @@ -24,6 +24,7 @@ final class MastodonRegisterViewModel { let email = CurrentValueSubject("") let password = CurrentValueSubject("") let reason = CurrentValueSubject("") + let avatarImage = CurrentValueSubject(nil) // output let approvalRequired: Bool From f16b4ed1cbdb682bb11544042c4889882c86c138 Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Tue, 2 Mar 2021 17:24:04 +0800 Subject: [PATCH 5/9] chore: update password hint, handle error when use PhotosUI --- Localization/app.json | 3 +-- Mastodon/Generated/Strings.swift | 6 ++--- .../Resources/en.lproj/Localizable.strings | 3 +-- ...astodonRegisterViewController+Avatar.swift | 24 +++++++++++++------ .../MastodonRegisterViewController.swift | 10 ++++++++ .../Register/MastodonRegisterViewModel.swift | 5 +--- 6 files changed, 32 insertions(+), 19 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index 3a45922a5..43cdf01ad 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -108,8 +108,7 @@ }, "password": { "placeholder": "password", - "prompt": "Your password needs at least:", - "prompt_eight_characters": "Eight characters" + "hint": "Your password needs at least Eight characters" }, "invite": { "registration_user_invite_request": "Why do you want to join?" diff --git a/Mastodon/Generated/Strings.swift b/Mastodon/Generated/Strings.swift index fedb437ac..dfd69f0c6 100644 --- a/Mastodon/Generated/Strings.swift +++ b/Mastodon/Generated/Strings.swift @@ -192,12 +192,10 @@ internal enum L10n { internal static let registrationUserInviteRequest = L10n.tr("Localizable", "Scene.Register.Input.Invite.RegistrationUserInviteRequest") } internal enum Password { + /// Your password needs at least Eight characters + internal static let hint = L10n.tr("Localizable", "Scene.Register.Input.Password.Hint") /// password internal static let placeholder = L10n.tr("Localizable", "Scene.Register.Input.Password.Placeholder") - /// Your password needs at least: - internal static let prompt = L10n.tr("Localizable", "Scene.Register.Input.Password.Prompt") - /// Eight characters - internal static let promptEightCharacters = L10n.tr("Localizable", "Scene.Register.Input.Password.PromptEightCharacters") } internal enum Username { /// This username is taken. diff --git a/Mastodon/Resources/en.lproj/Localizable.strings b/Mastodon/Resources/en.lproj/Localizable.strings index 0bb8b8cb0..d333460e9 100644 --- a/Mastodon/Resources/en.lproj/Localizable.strings +++ b/Mastodon/Resources/en.lproj/Localizable.strings @@ -61,9 +61,8 @@ tap the link to confirm your account."; "Scene.Register.Input.DisplayName.Placeholder" = "display name"; "Scene.Register.Input.Email.Placeholder" = "email"; "Scene.Register.Input.Invite.RegistrationUserInviteRequest" = "Why do you want to join?"; +"Scene.Register.Input.Password.Hint" = "Your password needs at least Eight characters"; "Scene.Register.Input.Password.Placeholder" = "password"; -"Scene.Register.Input.Password.Prompt" = "Your password needs at least:"; -"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"; diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift index 9b3937122..bb4e3f3eb 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController+Avatar.swift @@ -16,12 +16,27 @@ extension MastodonRegisterViewController: CropViewControllerDelegate, PHPickerVi picker.dismiss(animated: true, completion: {}) return } - itemProvider.loadObject(ofClass: UIImage.self) { [weak self] image, _ in - guard let self = self, let image = image as? UIImage else { return } + itemProvider.loadObject(ofClass: UIImage.self) { [weak self] image, error in + guard let self = self else { return } + guard let image = image as? UIImage else { + guard let error = error else { return } + let alertController = UIAlertController(for: error, title: "", preferredStyle: .alert) + let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default, handler: nil) + alertController.addAction(okAction) + DispatchQueue.main.async { + self.coordinator.present( + scene: .alertController(alertController: alertController), + from: nil, + transition: .alertController(animated: true, completion: nil) + ) + } + return + } DispatchQueue.main.async { let cropController = CropViewController(croppingStyle: .default, image: image) cropController.delegate = self cropController.setAspectRatioPreset(.presetSquare, animated: true) + cropController.aspectRatioPickerButtonHidden = true cropController.aspectRatioLockEnabled = true picker.dismiss(animated: true, completion: { self.present(cropController, animated: true, completion: nil) @@ -37,11 +52,6 @@ extension MastodonRegisterViewController: CropViewControllerDelegate, PHPickerVi } @objc func avatarButtonPressed(_ sender: UIButton) { - var configuration = PHPickerConfiguration() - configuration.filter = .images - - let imagePicker = PHPickerViewController(configuration: configuration) - imagePicker.delegate = self self.present(imagePicker, animated: true, completion: nil) } } diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift index 81dc16f75..a5e75e0fa 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift @@ -10,6 +10,7 @@ import MastodonSDK import os.log import UIKit import UITextField_Shake +import PhotosUI final class MastodonRegisterViewController: UIViewController, NeedsDependency, OnboardingViewControllerAppearance { var disposeBag = Set() @@ -19,6 +20,15 @@ final class MastodonRegisterViewController: UIViewController, NeedsDependency, O var viewModel: MastodonRegisterViewModel! + lazy var imagePicker: PHPickerViewController = { + var configuration = PHPickerConfiguration() + configuration.filter = .images + + let imagePicker = PHPickerViewController(configuration: configuration) + imagePicker.delegate = self + return imagePicker + }() + let tapGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer let scrollView: UIScrollView = { diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewModel.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewModel.swift index 9e244c2de..f0c11849a 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewModel.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewModel.swift @@ -161,11 +161,8 @@ extension MastodonRegisterViewModel { let falseColor = UIColor.clear let attributeString = NSMutableAttributedString() - let start = NSAttributedString(string: "Your password needs at least:", attributes: [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: color]) - attributeString.append(start) - attributeString.append(checkmarkImage(color: eightCharacters ? color : falseColor)) - let eightCharactersDescription = NSAttributedString(string: " Eight characters\n", attributes: [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: color]) + let eightCharactersDescription = NSAttributedString(string: L10n.Scene.Register.Input.Password.hint, attributes: [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: color]) attributeString.append(eightCharactersDescription) return attributeString From 384fe6018edb3cdf522b8409b2403cae83542485 Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Tue, 2 Mar 2021 18:21:54 +0800 Subject: [PATCH 6/9] chore: set the photoButton highlight with some value alpha --- .../MastodonRegisterViewController.swift | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift index a5e75e0fa..da6f570db 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift @@ -8,9 +8,9 @@ import Combine import MastodonSDK import os.log +import PhotosUI import UIKit import UITextField_Shake -import PhotosUI final class MastodonRegisterViewController: UIViewController, NeedsDependency, OnboardingViewControllerAppearance { var disposeBag = Set() @@ -36,7 +36,7 @@ final class MastodonRegisterViewController: UIViewController, NeedsDependency, O scrollview.showsVerticalScrollIndicator = false scrollview.keyboardDismissMode = .interactive scrollview.alwaysBounceVertical = true - scrollview.clipsToBounds = false // make content could display over bleeding + scrollview.clipsToBounds = false // make content could display over bleeding scrollview.translatesAutoresizingMaskIntoConstraints = false return scrollview }() @@ -216,19 +216,28 @@ final class MastodonRegisterViewController: UIViewController, NeedsDependency, O }() deinit { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", (#file as NSString).lastPathComponent, #line, #function) } - } extension MastodonRegisterViewController { - override func viewDidLoad() { super.viewDidLoad() setupOnboardingAppearance() defer { setupNavigationBarBackgroundView() } + NSObject.KeyValueObservingPublisher(object: photoButton, keyPath: \.isHighlighted, options: NSKeyValueObservingOptions.new) + .receive(on: DispatchQueue.main) + .sink { [weak self] isHighlighted in + guard let self = self else { return } + let alpha: CGFloat = isHighlighted ? 0.8 : 1 + self.plusIcon.alpha = alpha + self.plusIconBackground.alpha = alpha + self.photoButton.alpha = alpha + } + .store(in: &disposeBag) + domainLabel.text = "@" + viewModel.domain + " " domainLabel.sizeToFit() passwordCheckLabel.attributedText = viewModel.attributeStringForPassword() @@ -415,7 +424,7 @@ extension MastodonRegisterViewController { viewModel.isUsernameTaken .receive(on: DispatchQueue.main) - .sink {[weak self] isUsernameTaken in + .sink { [weak self] isUsernameTaken in guard let self = self else { return } if isUsernameTaken { self.usernameIsTakenLabel.isHidden = false @@ -492,10 +501,9 @@ extension MastodonRegisterViewController { .store(in: &disposeBag) if viewModel.approvalRequired { - inviteTextField.delegate = self NSLayoutConstraint.activate([ - inviteTextField.heightAnchor.constraint(equalToConstant: 50).priority(.defaultHigh) + inviteTextField.heightAnchor.constraint(equalToConstant: 50).priority(.defaultHigh), ]) viewModel.inviteValidateState @@ -503,7 +511,6 @@ extension MastodonRegisterViewController { .sink { [weak self] validateState in guard let self = self else { return } self.setTextFieldValidAppearance(self.inviteTextField, validateState: validateState) - } .store(in: &disposeBag) NotificationCenter.default @@ -518,11 +525,9 @@ extension MastodonRegisterViewController { signUpButton.addTarget(self, action: #selector(MastodonRegisterViewController.signUpButtonPressed(_:)), for: .touchUpInside) } - } extension MastodonRegisterViewController: UITextFieldDelegate { - func textFieldDidBeginEditing(_ textField: UITextField) { let text = textField.text?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "" @@ -564,7 +569,6 @@ extension MastodonRegisterViewController: UITextFieldDelegate { } extension MastodonRegisterViewController { - @objc private func tapGestureRecognizerHandler(_ sender: UITapGestureRecognizer) { view.endEditing(true) } @@ -611,6 +615,5 @@ extension MastodonRegisterViewController { self.coordinator.present(scene: .mastodonConfirmEmail(viewModel: viewModel), from: self, transition: .show) } .store(in: &disposeBag) - } } From a0aa8b9194e5aefc16115028a2fb7368e58ca69f Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Wed, 3 Mar 2021 11:30:25 +0800 Subject: [PATCH 7/9] chore: use instance method to observe highlighted property --- .../Onboarding/Register/MastodonRegisterViewController.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift index da6f570db..d95a03571 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift @@ -227,7 +227,8 @@ extension MastodonRegisterViewController { setupOnboardingAppearance() defer { setupNavigationBarBackgroundView() } - NSObject.KeyValueObservingPublisher(object: photoButton, keyPath: \.isHighlighted, options: NSKeyValueObservingOptions.new) + + photoButton.publisher(for: \.isHighlighted, options: .new) .receive(on: DispatchQueue.main) .sink { [weak self] isHighlighted in guard let self = self else { return } From 492ad98d9bb3f2a483d20699fd4d94959e4dc941 Mon Sep 17 00:00:00 2001 From: sunxiaojian Date: Wed, 3 Mar 2021 12:26:14 +0800 Subject: [PATCH 8/9] chore: change puls.circle.fill --- Mastodon/Generated/Assets.swift | 4 + .../Assets.xcassets/Circles/Contents.json | 9 ++ .../plus.circle.fill.imageset/Contents.json | 21 ++++ .../plus.circle.fill.pdf | 89 +++++++++++++++ .../plus.circle.fill.imageset/Contents.json | 21 ++++ .../plus.circle.fill.pdf | 101 ++++++++++++++++++ .../MastodonRegisterViewController.swift | 29 ++--- 7 files changed, 254 insertions(+), 20 deletions(-) create mode 100644 Mastodon/Resources/Assets.xcassets/Circles/Contents.json create mode 100644 Mastodon/Resources/Assets.xcassets/Circles/plus.circle.fill.imageset/Contents.json create mode 100644 Mastodon/Resources/Assets.xcassets/Circles/plus.circle.fill.imageset/plus.circle.fill.pdf create mode 100644 Mastodon/Resources/Assets.xcassets/Colors/plus.circle.fill.imageset/Contents.json create mode 100644 Mastodon/Resources/Assets.xcassets/Colors/plus.circle.fill.imageset/plus.circle.fill.pdf diff --git a/Mastodon/Generated/Assets.swift b/Mastodon/Generated/Assets.swift index 08507ed9d..d8bdb7063 100644 --- a/Mastodon/Generated/Assets.swift +++ b/Mastodon/Generated/Assets.swift @@ -28,6 +28,9 @@ internal enum Asset { internal enum Asset { internal static let mastodonTextLogo = ImageAsset(name: "Asset/mastodon.text.logo") } + internal enum Circles { + internal static let plusCircleFill = ImageAsset(name: "Circles/plus.circle.fill") + } internal enum Colors { internal enum Background { internal static let onboardingBackground = ColorAsset(name: "Colors/Background/onboarding.background") @@ -66,6 +69,7 @@ internal enum Asset { internal static let lightSecondaryText = ColorAsset(name: "Colors/lightSecondaryText") internal static let lightSuccessGreen = ColorAsset(name: "Colors/lightSuccessGreen") internal static let lightWhite = ColorAsset(name: "Colors/lightWhite") + internal static let plusCircleFill = ImageAsset(name: "Colors/plus.circle.fill") internal static let systemOrange = ColorAsset(name: "Colors/system.orange") } internal enum Welcome { diff --git a/Mastodon/Resources/Assets.xcassets/Circles/Contents.json b/Mastodon/Resources/Assets.xcassets/Circles/Contents.json new file mode 100644 index 000000000..6e965652d --- /dev/null +++ b/Mastodon/Resources/Assets.xcassets/Circles/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/Mastodon/Resources/Assets.xcassets/Circles/plus.circle.fill.imageset/Contents.json b/Mastodon/Resources/Assets.xcassets/Circles/plus.circle.fill.imageset/Contents.json new file mode 100644 index 000000000..580a3f7a0 --- /dev/null +++ b/Mastodon/Resources/Assets.xcassets/Circles/plus.circle.fill.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "plus.circle.fill.pdf", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Mastodon/Resources/Assets.xcassets/Circles/plus.circle.fill.imageset/plus.circle.fill.pdf b/Mastodon/Resources/Assets.xcassets/Circles/plus.circle.fill.imageset/plus.circle.fill.pdf new file mode 100644 index 000000000..efe6b69dc --- /dev/null +++ b/Mastodon/Resources/Assets.xcassets/Circles/plus.circle.fill.imageset/plus.circle.fill.pdf @@ -0,0 +1,89 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm +0.000000 0.000000 0.000000 scn +12.007203 -0.000002 m +18.586674 -0.000002 24.000000 5.413311 24.000000 12.007201 c +24.000000 18.586702 18.586674 24.000000 11.992814 24.000000 c +5.413314 24.000000 0.000000 18.586702 0.000000 12.007201 c +0.000000 5.413311 5.413314 -0.000002 12.007203 -0.000002 c +h +6.478707 12.007201 m +6.478707 12.827837 7.068974 13.432522 7.875220 13.432522 c +10.567494 13.432522 l +10.567494 16.124798 l +10.567494 16.931015 11.172179 17.535698 11.992814 17.535698 c +12.813449 17.535698 13.418134 16.931015 13.418134 16.124798 c +13.418134 13.432522 l +16.110380 13.432522 l +16.931015 13.432522 17.521311 12.827837 17.521311 12.007201 c +17.521311 11.186566 16.931015 10.581882 16.110380 10.581882 c +13.418134 10.581882 l +13.418134 7.889637 l +13.418134 7.083389 12.813449 6.478704 11.992814 6.478704 c +11.172179 6.478704 10.567494 7.083389 10.567494 7.889637 c +10.567494 10.581882 l +7.875220 10.581882 l +7.068974 10.581882 6.478707 11.186566 6.478707 12.007201 c +h +f +n +Q + +endstream +endobj + +3 0 obj + 1071 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 24.000000 24.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Type /Catalog + /Pages 5 0 R + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000001161 00000 n +0000001184 00000 n +0000001357 00000 n +0000001431 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +1490 +%%EOF \ No newline at end of file diff --git a/Mastodon/Resources/Assets.xcassets/Colors/plus.circle.fill.imageset/Contents.json b/Mastodon/Resources/Assets.xcassets/Colors/plus.circle.fill.imageset/Contents.json new file mode 100644 index 000000000..580a3f7a0 --- /dev/null +++ b/Mastodon/Resources/Assets.xcassets/Colors/plus.circle.fill.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "plus.circle.fill.pdf", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Mastodon/Resources/Assets.xcassets/Colors/plus.circle.fill.imageset/plus.circle.fill.pdf b/Mastodon/Resources/Assets.xcassets/Colors/plus.circle.fill.imageset/plus.circle.fill.pdf new file mode 100644 index 000000000..f4a613417 --- /dev/null +++ b/Mastodon/Resources/Assets.xcassets/Colors/plus.circle.fill.imageset/plus.circle.fill.pdf @@ -0,0 +1,101 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm +1.000000 1.000000 1.000000 scn +30.000000 15.000000 m +30.000000 6.715729 23.284271 0.000000 15.000000 0.000000 c +6.715729 0.000000 0.000000 6.715729 0.000000 15.000000 c +0.000000 23.284271 6.715729 30.000000 15.000000 30.000000 c +23.284271 30.000000 30.000000 23.284271 30.000000 15.000000 c +h +f +n +Q +q +1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm +0.000000 0.000000 0.000000 scn +15.009004 0.000000 m +23.233341 0.000000 30.000000 6.766640 30.000000 15.009003 c +30.000000 23.233379 23.233341 30.000000 14.991017 30.000000 c +6.766642 30.000000 0.000000 23.233379 0.000000 15.009003 c +0.000000 6.766640 6.766643 0.000000 15.009004 0.000000 c +h +8.098384 15.009003 m +8.098384 16.034798 8.836217 16.790653 9.844025 16.790653 c +13.209368 16.790653 l +13.209368 20.155996 l +13.209368 21.163769 13.965223 21.919624 14.991017 21.919624 c +16.016811 21.919624 16.772667 21.163769 16.772667 20.155996 c +16.772667 16.790653 l +20.137974 16.790653 l +21.163769 16.790653 21.901638 16.034798 21.901638 15.009003 c +21.901638 13.983208 21.163769 13.227352 20.137974 13.227352 c +16.772667 13.227352 l +16.772667 9.862047 l +16.772667 8.854239 16.016811 8.098381 14.991017 8.098381 c +13.965223 8.098381 13.209368 8.854239 13.209368 9.862047 c +13.209368 13.227352 l +9.844025 13.227352 l +8.836217 13.227352 8.098384 13.983208 8.098384 15.009003 c +h +f +n +Q + +endstream +endobj + +3 0 obj + 1426 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 30.000000 30.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Type /Catalog + /Pages 5 0 R + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000001516 00000 n +0000001539 00000 n +0000001712 00000 n +0000001786 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +1845 +%%EOF \ No newline at end of file diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift index d95a03571..ba515e2da 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewController.swift @@ -71,23 +71,13 @@ final class MastodonRegisterViewController: UIViewController, NeedsDependency, O return button }() - let plusIconBackground: UIImageView = { - let icon = UIImageView() - let boldFont = UIFont.systemFont(ofSize: 24) - let configuration = UIImage.SymbolConfiguration(font: boldFont) - let image = UIImage(systemName: "plus.circle", withConfiguration: configuration) - icon.image = image - icon.tintColor = .white - return icon - }() - let plusIcon: UIImageView = { let icon = UIImageView() - let boldFont = UIFont.systemFont(ofSize: 24) - let configuration = UIImage.SymbolConfiguration(font: boldFont) - let image = UIImage(systemName: "plus.circle.fill", withConfiguration: configuration) + + let image = Asset.Circles.plusCircleFill.image.withRenderingMode(.alwaysTemplate) icon.image = image icon.tintColor = Asset.Colors.Icon.plus.color + icon.backgroundColor = .white return icon }() @@ -234,7 +224,6 @@ extension MastodonRegisterViewController { guard let self = self else { return } let alpha: CGFloat = isHighlighted ? 0.8 : 1 self.plusIcon.alpha = alpha - self.plusIconBackground.alpha = alpha self.photoButton.alpha = alpha } .store(in: &disposeBag) @@ -305,12 +294,7 @@ extension MastodonRegisterViewController { photoButton.centerXAnchor.constraint(equalTo: photoView.centerXAnchor), photoButton.centerYAnchor.constraint(equalTo: photoView.centerYAnchor), ]) - plusIconBackground.translatesAutoresizingMaskIntoConstraints = false - photoView.addSubview(plusIconBackground) - NSLayoutConstraint.activate([ - plusIconBackground.trailingAnchor.constraint(equalTo: photoButton.trailingAnchor), - plusIconBackground.bottomAnchor.constraint(equalTo: photoButton.bottomAnchor), - ]) + plusIcon.translatesAutoresizingMaskIntoConstraints = false photoView.addSubview(plusIcon) NSLayoutConstraint.activate([ @@ -526,6 +510,11 @@ extension MastodonRegisterViewController { signUpButton.addTarget(self, action: #selector(MastodonRegisterViewController.signUpButtonPressed(_:)), for: .touchUpInside) } + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + plusIcon.layer.cornerRadius = plusIcon.frame.width/2 + plusIcon.clipsToBounds = true + } } extension MastodonRegisterViewController: UITextFieldDelegate { From ba283bbdcb40c10508f999682543d4c03d028a10 Mon Sep 17 00:00:00 2001 From: CMK Date: Thu, 4 Mar 2021 10:51:49 +0800 Subject: [PATCH 9/9] fix: appVersion not set issue --- .../mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist | 4 ++-- Mastodon/Supporting Files/AppDelegate.swift | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist index b1a7a744c..bc78dfa4b 100644 --- a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist @@ -17,12 +17,12 @@ Mastodon - Release.xcscheme_^#shared#^_ orderHint - 1 + 2 Mastodon.xcscheme_^#shared#^_ orderHint - 0 + 1 SuppressBuildableAutocreation diff --git a/Mastodon/Supporting Files/AppDelegate.swift b/Mastodon/Supporting Files/AppDelegate.swift index cfac7f1a5..00d839b51 100644 --- a/Mastodon/Supporting Files/AppDelegate.swift +++ b/Mastodon/Supporting Files/AppDelegate.swift @@ -13,11 +13,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate { let appContext = AppContext() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - return true // Update app version info. See: `Settings.bundle` UserDefaults.standard.setValue(UIApplication.appVersion(), forKey: "Mastodon.appVersion") UserDefaults.standard.setValue(UIApplication.appBuild(), forKey: "Mastodon.appBundle") + + return true } // MARK: UISceneSession Lifecycle