From 611d65dd302f52fbc96de868592c895e1ed201e3 Mon Sep 17 00:00:00 2001 From: CMK Date: Fri, 21 May 2021 17:18:03 +0800 Subject: [PATCH] feat: add segmented control keyboard shortcut for notification scene --- Localization/app.json | 4 + Mastodon/Generated/Strings.swift | 6 ++ .../Resources/ar.lproj/Localizable.strings | 2 + .../Resources/en.lproj/Localizable.strings | 2 + .../NotificationViewController.swift | 92 +++++++++++++++++-- .../Paging/ProfilePagingViewController.swift | 10 +- 6 files changed, 105 insertions(+), 11 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index 34dd5221b..fb7c943bb 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -453,6 +453,10 @@ "poll": "Your poll has ended", "mention": "mentioned you", "follow_request": "request to follow you" + }, + "keyobard": { + "show_everything": "Show Everything", + "show_mentions": "Show Mentions" } }, "thread": { diff --git a/Mastodon/Generated/Strings.swift b/Mastodon/Generated/Strings.swift index 588f12caa..3dd633372 100644 --- a/Mastodon/Generated/Strings.swift +++ b/Mastodon/Generated/Strings.swift @@ -550,6 +550,12 @@ internal enum L10n { /// rebloged your post internal static let reblog = L10n.tr("Localizable", "Scene.Notification.Action.Reblog") } + internal enum Keyobard { + /// Show Everything + internal static let showEverything = L10n.tr("Localizable", "Scene.Notification.Keyobard.ShowEverything") + /// Show Mentions + internal static let showMentions = L10n.tr("Localizable", "Scene.Notification.Keyobard.ShowMentions") + } internal enum Title { /// Everything internal static let everything = L10n.tr("Localizable", "Scene.Notification.Title.Everything") diff --git a/Mastodon/Resources/ar.lproj/Localizable.strings b/Mastodon/Resources/ar.lproj/Localizable.strings index bd7c9f295..1cb13ea8c 100644 --- a/Mastodon/Resources/ar.lproj/Localizable.strings +++ b/Mastodon/Resources/ar.lproj/Localizable.strings @@ -190,6 +190,8 @@ tap the link to confirm your account."; "Scene.Notification.Action.Mention" = "mentioned you"; "Scene.Notification.Action.Poll" = "Your poll has ended"; "Scene.Notification.Action.Reblog" = "rebloged your post"; +"Scene.Notification.Keyobard.ShowEverything" = "Show Everything"; +"Scene.Notification.Keyobard.ShowMentions" = "Show Mentions"; "Scene.Notification.Title.Everything" = "Everything"; "Scene.Notification.Title.Mentions" = "Mentions"; "Scene.Preview.Keyboard.ClosePreview" = "Close Preview"; diff --git a/Mastodon/Resources/en.lproj/Localizable.strings b/Mastodon/Resources/en.lproj/Localizable.strings index bd7c9f295..1cb13ea8c 100644 --- a/Mastodon/Resources/en.lproj/Localizable.strings +++ b/Mastodon/Resources/en.lproj/Localizable.strings @@ -190,6 +190,8 @@ tap the link to confirm your account."; "Scene.Notification.Action.Mention" = "mentioned you"; "Scene.Notification.Action.Poll" = "Your poll has ended"; "Scene.Notification.Action.Reblog" = "rebloged your post"; +"Scene.Notification.Keyobard.ShowEverything" = "Show Everything"; +"Scene.Notification.Keyobard.ShowMentions" = "Show Mentions"; "Scene.Notification.Title.Everything" = "Everything"; "Scene.Notification.Title.Mentions" = "Mentions"; "Scene.Preview.Keyboard.ClosePreview" = "Close Preview"; diff --git a/Mastodon/Scene/Notification/NotificationViewController.swift b/Mastodon/Scene/Notification/NotificationViewController.swift index 6ef820a8d..47fee4d66 100644 --- a/Mastodon/Scene/Notification/NotificationViewController.swift +++ b/Mastodon/Scene/Notification/NotificationViewController.swift @@ -81,6 +81,25 @@ extension NotificationViewController { } } .store(in: &disposeBag) + + viewModel.selectedIndex + .removeDuplicates() + .receive(on: DispatchQueue.main) + .sink { [weak self] segment in + guard let self = self else { return } + self.segmentControl.selectedSegmentIndex = segment.rawValue + + guard let domain = self.viewModel.activeMastodonAuthenticationBox.value?.domain, let userID = self.viewModel.activeMastodonAuthenticationBox.value?.userID else { + return + } + switch segment { + case .EveryThing: + self.viewModel.notificationPredicate.value = MastodonNotification.predicate(domain: domain, userID: userID) + case .Mentions: + self.viewModel.notificationPredicate.value = MastodonNotification.predicate(domain: domain, userID: userID, typeRaw: Mastodon.Entity.Notification.NotificationType.mention.rawValue) + } + } + .store(in: &disposeBag) } override func viewWillAppear(_ animated: Bool) { @@ -122,14 +141,7 @@ extension NotificationViewController { extension NotificationViewController { @objc private func segmentedControlValueChanged(_ sender: UISegmentedControl) { os_log("%{public}s[%{public}ld], %{public}s: select at index: %ld", (#file as NSString).lastPathComponent, #line, #function, sender.selectedSegmentIndex) - guard let domain = viewModel.activeMastodonAuthenticationBox.value?.domain, let userID = viewModel.activeMastodonAuthenticationBox.value?.userID else { - return - } - if sender.selectedSegmentIndex == NotificationViewModel.NotificationSegment.EveryThing.rawValue { - viewModel.notificationPredicate.value = MastodonNotification.predicate(domain: domain, userID: userID) - } else { - viewModel.notificationPredicate.value = MastodonNotification.predicate(domain: domain, userID: userID, typeRaw: Mastodon.Entity.Notification.NotificationType.mention.rawValue) - } + viewModel.selectedIndex.value = NotificationViewModel.NotificationSegment(rawValue: sender.selectedSegmentIndex)! } @@ -273,8 +285,70 @@ extension NotificationViewController: LoadMoreConfigurableTableViewContainer { } extension NotificationViewController { + + enum CategorySwitch: String, CaseIterable { + case showEverything + case showMentions + + var title: String { + switch self { + case .showEverything: return L10n.Scene.Notification.Keyobard.showEverything + case .showMentions: return L10n.Scene.Notification.Keyobard.showMentions + } + } + + // UIKeyCommand input + var input: String { + switch self { + case .showEverything: return "[" // + shift + command + case .showMentions: return "]" // + shift + command + } + } + + var modifierFlags: UIKeyModifierFlags { + switch self { + case .showEverything: return [.shift, .command] + case .showMentions: return [.shift, .command] + } + } + + var propertyList: Any { + return rawValue + } + } + + var categorySwitchKeyCommands: [UIKeyCommand] { + CategorySwitch.allCases.map { category in + UIKeyCommand( + title: category.title, + image: nil, + action: #selector(NotificationViewController.showCategory(_:)), + input: category.input, + modifierFlags: category.modifierFlags, + propertyList: category.propertyList, + alternates: [], + discoverabilityTitle: nil, + attributes: [], + state: .off + ) + } + } + + @objc private func showCategory(_ sender: UIKeyCommand) { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + guard let rawValue = sender.propertyList as? String, + let category = CategorySwitch(rawValue: rawValue) else { return } + + switch category { + case .showEverything: + viewModel.selectedIndex.value = .EveryThing + case .showMentions: + viewModel.selectedIndex.value = .Mentions + } + } + override var keyCommands: [UIKeyCommand]? { - return navigationKeyCommands + return categorySwitchKeyCommands + navigationKeyCommands } } diff --git a/Mastodon/Scene/Profile/Segmented/Paging/ProfilePagingViewController.swift b/Mastodon/Scene/Profile/Segmented/Paging/ProfilePagingViewController.swift index 0ae2187c3..16dcbbeb6 100644 --- a/Mastodon/Scene/Profile/Segmented/Paging/ProfilePagingViewController.swift +++ b/Mastodon/Scene/Profile/Segmented/Paging/ProfilePagingViewController.swift @@ -58,13 +58,19 @@ extension ProfilePagingViewController { } +// workaround to fix tab man responder chain issue extension ProfilePagingViewController { - + override var keyCommands: [UIKeyCommand]? { return currentViewController?.keyCommands } - @objc func keyCommandHandlerRelay(_ sender: UIKeyCommand) { + @objc func navigateKeyCommandHandlerRelay(_ sender: UIKeyCommand) { + (currentViewController as? StatusTableViewControllerNavigateable)?.navigateKeyCommandHandlerRelay(sender) + + } + + @objc func statusKeyCommandHandlerRelay(_ sender: UIKeyCommand) { (currentViewController as? StatusTableViewControllerNavigateable)?.statusKeyCommandHandlerRelay(sender) }