From c06f8502a8b9b364ca6d6eeb945315e2f4cb83d7 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Thu, 12 Jan 2023 23:34:25 -0500 Subject: [PATCH 1/4] =?UTF-8?q?Disable=20the=20=E2=80=9CUnfollow=E2=80=9D?= =?UTF-8?q?=20button=20when=20you=20weren=E2=80=99t=20previously=20followi?= =?UTF-8?q?ng?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s always been weird to me that this button says “Unfollowed” since I never followed the person I’m reporting --- Localization/StringsConvertor/input/Base.lproj/app.json | 1 + Localization/app.json | 1 + Mastodon/Scene/Report/ReportResult/ReportResultView.swift | 8 +++++++- .../Scene/Report/ReportResult/ReportResultViewModel.swift | 3 +++ .../Sources/MastodonLocalization/Generated/Strings.swift | 2 ++ .../Resources/Base.lproj/Localizable.strings | 1 + 6 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index 23180ac894..ac91f7d734 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -747,6 +747,7 @@ "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", "unfollow": "Unfollow", "unfollowed": "Unfollowed", + "not_following": "Not Following", "unfollow_user": "Unfollow %s", "mute_user": "Mute %s", "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", diff --git a/Localization/app.json b/Localization/app.json index 0f471d9733..bb311463c2 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -764,6 +764,7 @@ "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", "unfollow": "Unfollow", "unfollowed": "Unfollowed", + "not_following": "Not Following", "unfollow_user": "Unfollow %s", "mute_user": "Mute %s", "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", diff --git a/Mastodon/Scene/Report/ReportResult/ReportResultView.swift b/Mastodon/Scene/Report/ReportResult/ReportResultView.swift index 361f5db248..9f1ca6fe73 100644 --- a/Mastodon/Scene/Report/ReportResult/ReportResultView.swift +++ b/Mastodon/Scene/Report/ReportResult/ReportResultView.swift @@ -75,9 +75,15 @@ struct ReportResultView: View { action: { viewModel.followActionPublisher.send() }, - title: viewModel.relationshipViewModel.isFollowing ? L10n.Scene.Report.StepFinal.unfollow : L10n.Scene.Report.StepFinal.unfollowed, + title: viewModel.relationshipViewModel.isFollowing + ? L10n.Scene.Report.StepFinal.unfollow + : (viewModel.wasFollowing + ? L10n.Scene.Report.StepFinal.unfollowed + : L10n.Scene.Report.StepFinal.notFollowing), isBusy: viewModel.isRequestFollow ) + .disabled(!viewModel.wasFollowing) + .opacity(viewModel.wasFollowing ? 1 : 0.5) } // Mute diff --git a/Mastodon/Scene/Report/ReportResult/ReportResultViewModel.swift b/Mastodon/Scene/Report/ReportResult/ReportResultViewModel.swift index 8123a87737..cf364e13d9 100644 --- a/Mastodon/Scene/Report/ReportResult/ReportResultViewModel.swift +++ b/Mastodon/Scene/Report/ReportResult/ReportResultViewModel.swift @@ -37,6 +37,8 @@ class ReportResultViewModel: ObservableObject { @Published var isRequestMute = false @Published var isRequestBlock = false + @Published var wasFollowing = false + // output @Published var avatarURL: URL? @Published var username: String = "" @@ -63,6 +65,7 @@ class ReportResultViewModel: ObservableObject { guard let me = authContext.mastodonAuthenticationBox.authenticationRecord.object(in: context.managedObjectContext)?.user else { return } self.relationshipViewModel.user = user self.relationshipViewModel.me = me + self.wasFollowing = self.relationshipViewModel.isFollowing self.avatarURL = user.avatarImageURL() self.username = user.acctWithDomain diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index fb516496a2..63e8f16988 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -1091,6 +1091,8 @@ public enum L10n { public static func muteUser(_ p1: Any) -> String { return L10n.tr("Localizable", "Scene.Report.StepFinal.MuteUser", String(describing: p1), fallback: "Mute %@") } + /// Not Following + public static let notFollowing = L10n.tr("Localizable", "Scene.Report.StepFinal.NotFollowing", fallback: "Not Following") /// They will no longer be able to follow or see your posts, but they can see if they’ve been blocked. public static let theyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked = L10n.tr("Localizable", "Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked", fallback: "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.") /// Unfollow diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 2c2d295b39..505e5610d6 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -365,6 +365,7 @@ uploaded to Mastodon."; "Scene.Report.StepFinal.BlockUser" = "Block %@"; "Scene.Report.StepFinal.DontWantToSeeThis" = "Don’t want to see this?"; "Scene.Report.StepFinal.MuteUser" = "Mute %@"; +"Scene.Report.StepFinal.NotFollowing" = "Not Following"; "Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; "Scene.Report.StepFinal.Unfollow" = "Unfollow"; "Scene.Report.StepFinal.UnfollowUser" = "Unfollow %@"; From fa377b4ecea425dd8da33a54bb4a7d3bfa788c9f Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 13 Jan 2023 09:23:45 -0500 Subject: [PATCH 2/4] Swap from skip/next to a single submit button on the additional comments screen --- .../input/Base.lproj/app.json | 1 + Localization/app.json | 1 + .../Report/Report/ReportViewController.swift | 10 +------ .../Scene/Report/Report/ReportViewModel.swift | 4 +-- .../ReportResultViewController.swift | 2 +- .../ReportSupplementaryViewController.swift | 30 +++++-------------- .../ReportSupplementaryViewModel.swift | 4 ++- .../Generated/Strings.swift | 2 ++ .../Resources/Base.lproj/Localizable.strings | 1 + 9 files changed, 19 insertions(+), 36 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index ac91f7d734..10a7474ca1 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -87,6 +87,7 @@ "share": "Share", "share_user": "Share %s", "share_post": "Share Post", + "submit": "Submit", "open_in_safari": "Open in Safari", "open_in_browser": "Open in Browser", "find_people": "Find people to follow", diff --git a/Localization/app.json b/Localization/app.json index bb311463c2..1ee8ec0a75 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -87,6 +87,7 @@ "share": "Share", "share_user": "Share %s", "share_post": "Share Post", + "submit": "Submit", "open_in_safari": "Open in Safari", "open_in_browser": "Open in Browser", "find_people": "Find people to follow", diff --git a/Mastodon/Scene/Report/Report/ReportViewController.swift b/Mastodon/Scene/Report/Report/ReportViewController.swift index fb0417a7f4..ce2294cf2b 100644 --- a/Mastodon/Scene/Report/Report/ReportViewController.swift +++ b/Mastodon/Scene/Report/Report/ReportViewController.swift @@ -150,15 +150,7 @@ extension ReportViewController: ReportStatusViewControllerDelegate { // MARK: - ReportSupplementaryViewControllerDelegate extension ReportViewController: ReportSupplementaryViewControllerDelegate { - func reportSupplementaryViewController(_ viewController: ReportSupplementaryViewController, skipButtonDidPressed button: UIButton) { - report() - } - - func reportSupplementaryViewController(_ viewController: ReportSupplementaryViewController, nextButtonDidPressed button: UIButton) { - report() - } - - private func report() { + func reportSupplementaryViewController(_ viewController: ReportSupplementaryViewController, submitButtonDidPressed button: UIButton) { Task { @MainActor in do { let _ = try await viewModel.report() diff --git a/Mastodon/Scene/Report/Report/ReportViewModel.swift b/Mastodon/Scene/Report/Report/ReportViewModel.swift index 05f1cfef8e..0d20b9f79d 100644 --- a/Mastodon/Scene/Report/Report/ReportViewModel.swift +++ b/Mastodon/Scene/Report/Report/ReportViewModel.swift @@ -120,8 +120,8 @@ extension ReportViewModel { // the user comment is essential step in report flow // only check isSkip or not let comment: String? = { - let _comment = self.reportSupplementaryViewModel.isSkip ? nil : self.reportSupplementaryViewModel.commentContext.comment - if let comment = _comment, !comment.isEmpty { + let comment = self.reportSupplementaryViewModel.commentContext.comment + if !comment.isEmpty { return comment } else { return nil diff --git a/Mastodon/Scene/Report/ReportResult/ReportResultViewController.swift b/Mastodon/Scene/Report/ReportResult/ReportResultViewController.swift index 1d67ad6c3e..17a0f09ba8 100644 --- a/Mastodon/Scene/Report/ReportResult/ReportResultViewController.swift +++ b/Mastodon/Scene/Report/ReportResult/ReportResultViewController.swift @@ -82,7 +82,7 @@ extension ReportResultViewController { .store(in: &observations) - navigationActionView.nextButton.addTarget(self, action: #selector(ReportSupplementaryViewController.nextButtonDidPressed(_:)), for: .touchUpInside) + navigationActionView.nextButton.addTarget(self, action: #selector(ReportSupplementaryViewController.submitButtonDidPressed(_:)), for: .touchUpInside) viewModel.followActionPublisher .throttle(for: 0.3, scheduler: DispatchQueue.main, latest: false) diff --git a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift index a84a3a6508..445594a08b 100644 --- a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift +++ b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift @@ -14,8 +14,7 @@ import MastodonUI import MastodonLocalization protocol ReportSupplementaryViewControllerDelegate: AnyObject { - func reportSupplementaryViewController(_ viewController: ReportSupplementaryViewController, skipButtonDidPressed button: UIButton) - func reportSupplementaryViewController(_ viewController: ReportSupplementaryViewController, nextButtonDidPressed button: UIButton) + func reportSupplementaryViewController(_ viewController: ReportSupplementaryViewController, submitButtonDidPressed button: UIButton) } final class ReportSupplementaryViewController: UIViewController, NeedsDependency, ReportViewControllerAppearance { @@ -59,7 +58,8 @@ final class ReportSupplementaryViewController: UIViewController, NeedsDependency let navigationActionView: NavigationActionView = { let navigationActionView = NavigationActionView() navigationActionView.backgroundColor = Asset.Scene.Onboarding.background.color - navigationActionView.backButton.setTitle(L10n.Common.Controls.Actions.skip, for: .normal) + navigationActionView.nextButton.setTitle(L10n.Common.Controls.Actions.submit, for: .normal) + navigationActionView.hidesBackButton = true return navigationActionView }() @@ -83,7 +83,7 @@ extension ReportSupplementaryViewController { guard let self = self else { return } self.navigationItem.rightBarButtonItem = isBusy ? self.activityIndicatorBarButtonItem : self.cancelBarButtonItem self.navigationItem.hidesBackButton = isBusy - self.navigationActionView.backButton.isUserInteractionEnabled = !isBusy + self.navigationActionView.nextButton.isUserInteractionEnabled = !isBusy } .store(in: &disposeBag) @@ -116,13 +116,7 @@ extension ReportSupplementaryViewController { } .store(in: &observations) - viewModel.$isNextButtonEnabled - .receive(on: DispatchQueue.main) - .assign(to: \.isEnabled, on: navigationActionView.nextButton) - .store(in: &disposeBag) - - navigationActionView.backButton.addTarget(self, action: #selector(ReportSupplementaryViewController.skipButtonDidPressed(_:)), for: .touchUpInside) - navigationActionView.nextButton.addTarget(self, action: #selector(ReportSupplementaryViewController.nextButtonDidPressed(_:)), for: .touchUpInside) + navigationActionView.nextButton.addTarget(self, action: #selector(ReportSupplementaryViewController.submitButtonDidPressed(_:)), for: .touchUpInside) } } @@ -133,22 +127,12 @@ extension ReportSupplementaryViewController { dismiss(animated: true, completion: nil) } - @objc func skipButtonDidPressed(_ sender: UIButton) { + @objc func submitButtonDidPressed(_ sender: UIButton) { logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") assert(viewModel.delegate != nil) - viewModel.isSkip = true - viewModel.delegate?.reportSupplementaryViewController(self, skipButtonDidPressed: sender) + viewModel.delegate?.reportSupplementaryViewController(self, submitButtonDidPressed: sender) } - - @objc func nextButtonDidPressed(_ sender: UIButton) { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") - - assert(viewModel.delegate != nil) - viewModel.isSkip = false - viewModel.delegate?.reportSupplementaryViewController(self, nextButtonDidPressed: sender) - } - } // MARK: - UITableViewDelegate diff --git a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel.swift b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel.swift index a4239bbc4d..cf7c7fcc87 100644 --- a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel.swift +++ b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel.swift @@ -21,7 +21,9 @@ class ReportSupplementaryViewModel { let user: ManagedObjectRecord let commentContext = ReportItem.CommentContext() - @Published var isSkip = false + // without this, `.assign(to: &reportSupplementaryViewModel.$isBusy)` in `ReportViewModel` + // hits an EXC_BAD_ACCESS! Fun! + let dummy = false @Published var isBusy = false // output diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 63e8f16988..bea6141f9f 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -180,6 +180,8 @@ public enum L10n { public static let signUp = L10n.tr("Localizable", "Common.Controls.Actions.SignUp", fallback: "Create account") /// Skip public static let skip = L10n.tr("Localizable", "Common.Controls.Actions.Skip", fallback: "Skip") + /// Submit + public static let submit = L10n.tr("Localizable", "Common.Controls.Actions.Submit", fallback: "Submit") /// Take Photo public static let takePhoto = L10n.tr("Localizable", "Common.Controls.Actions.TakePhoto", fallback: "Take Photo") /// Try Again diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 505e5610d6..0b9f7bcf8b 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -62,6 +62,7 @@ Please check your internet connection."; "Common.Controls.Actions.SignIn" = "Log in"; "Common.Controls.Actions.SignUp" = "Create account"; "Common.Controls.Actions.Skip" = "Skip"; +"Common.Controls.Actions.Submit" = "Submit"; "Common.Controls.Actions.TakePhoto" = "Take Photo"; "Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; From 1f972decdd69656bfa5b28ffba3cef3d23ef95ba Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 13 Jan 2023 10:03:28 -0500 Subject: [PATCH 3/4] EXC_BAD_ACCESS is gone now (?) --- .../ReportSupplementary/ReportSupplementaryViewModel.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel.swift b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel.swift index cf7c7fcc87..fd3e99329d 100644 --- a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel.swift +++ b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel.swift @@ -21,9 +21,6 @@ class ReportSupplementaryViewModel { let user: ManagedObjectRecord let commentContext = ReportItem.CommentContext() - // without this, `.assign(to: &reportSupplementaryViewModel.$isBusy)` in `ReportViewModel` - // hits an EXC_BAD_ACCESS! Fun! - let dummy = false @Published var isBusy = false // output From f57d47218c6537dec90ab495cd2fb27116a94899 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 13 Jan 2023 10:09:08 -0500 Subject: [PATCH 4/4] Update language for the report comments placeholder --- Localization/StringsConvertor/input/Base.lproj/app.json | 2 +- Localization/app.json | 2 +- .../Sources/MastodonLocalization/Generated/Strings.swift | 4 ++-- .../Resources/Base.lproj/Localizable.strings | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index 10a7474ca1..dc59fe46c6 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -711,7 +711,7 @@ "report_sent_title": "Thanks for reporting, we’ll look into this.", "send": "Send Report", "skip_to_send": "Send without comment", - "text_placeholder": "Type or paste additional comments", + "text_placeholder": "Type or paste additional comments (optional)", "reported": "REPORTED", "step_one": { "step_1_of_4": "Step 1 of 4", diff --git a/Localization/app.json b/Localization/app.json index 1ee8ec0a75..7f4a7dca8e 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -728,7 +728,7 @@ "report_sent_title": "Thanks for reporting, we’ll look into this.", "send": "Send Report", "skip_to_send": "Send without comment", - "text_placeholder": "Type or paste additional comments", + "text_placeholder": "Type or paste additional comments (optional)", "reported": "REPORTED", "step_one": { "step_1_of_4": "Step 1 of 4", diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index bea6141f9f..c4d1769b0b 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -1074,8 +1074,8 @@ public enum L10n { public static let step1 = L10n.tr("Localizable", "Scene.Report.Step1", fallback: "Step 1 of 2") /// Step 2 of 2 public static let step2 = L10n.tr("Localizable", "Scene.Report.Step2", fallback: "Step 2 of 2") - /// Type or paste additional comments - public static let textPlaceholder = L10n.tr("Localizable", "Scene.Report.TextPlaceholder", fallback: "Type or paste additional comments") + /// Type or paste additional comments (optional) + public static let textPlaceholder = L10n.tr("Localizable", "Scene.Report.TextPlaceholder", fallback: "Type or paste additional comments (optional)") /// Report %@ public static func title(_ p1: Any) -> String { return L10n.tr("Localizable", "Scene.Report.Title", String(describing: p1), fallback: "Report %@") diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 0b9f7bcf8b..99eec0be0e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -396,7 +396,7 @@ uploaded to Mastodon."; "Scene.Report.StepTwo.SelectAllThatApply" = "Select all that apply"; "Scene.Report.StepTwo.Step2Of4" = "Step 2 of 4"; "Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Which rules are being violated?"; -"Scene.Report.TextPlaceholder" = "Type or paste additional comments"; +"Scene.Report.TextPlaceholder" = "Type or paste additional comments (optional)"; "Scene.Report.Title" = "Report %@"; "Scene.Report.TitleReport" = "Report"; "Scene.Search.Recommend.Accounts.Description" = "You may like to follow these accounts";