feat: add segmented control keyboard shortcut for notification scene

This commit is contained in:
CMK 2021-05-21 17:18:03 +08:00
parent aec7a1f5ea
commit 611d65dd30
6 changed files with 105 additions and 11 deletions

View File

@ -453,6 +453,10 @@
"poll": "Your poll has ended", "poll": "Your poll has ended",
"mention": "mentioned you", "mention": "mentioned you",
"follow_request": "request to follow you" "follow_request": "request to follow you"
},
"keyobard": {
"show_everything": "Show Everything",
"show_mentions": "Show Mentions"
} }
}, },
"thread": { "thread": {

View File

@ -550,6 +550,12 @@ internal enum L10n {
/// rebloged your post /// rebloged your post
internal static let reblog = L10n.tr("Localizable", "Scene.Notification.Action.Reblog") 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 { internal enum Title {
/// Everything /// Everything
internal static let everything = L10n.tr("Localizable", "Scene.Notification.Title.Everything") internal static let everything = L10n.tr("Localizable", "Scene.Notification.Title.Everything")

View File

@ -190,6 +190,8 @@ tap the link to confirm your account.";
"Scene.Notification.Action.Mention" = "mentioned you"; "Scene.Notification.Action.Mention" = "mentioned you";
"Scene.Notification.Action.Poll" = "Your poll has ended"; "Scene.Notification.Action.Poll" = "Your poll has ended";
"Scene.Notification.Action.Reblog" = "rebloged your post"; "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.Everything" = "Everything";
"Scene.Notification.Title.Mentions" = "Mentions"; "Scene.Notification.Title.Mentions" = "Mentions";
"Scene.Preview.Keyboard.ClosePreview" = "Close Preview"; "Scene.Preview.Keyboard.ClosePreview" = "Close Preview";

View File

@ -190,6 +190,8 @@ tap the link to confirm your account.";
"Scene.Notification.Action.Mention" = "mentioned you"; "Scene.Notification.Action.Mention" = "mentioned you";
"Scene.Notification.Action.Poll" = "Your poll has ended"; "Scene.Notification.Action.Poll" = "Your poll has ended";
"Scene.Notification.Action.Reblog" = "rebloged your post"; "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.Everything" = "Everything";
"Scene.Notification.Title.Mentions" = "Mentions"; "Scene.Notification.Title.Mentions" = "Mentions";
"Scene.Preview.Keyboard.ClosePreview" = "Close Preview"; "Scene.Preview.Keyboard.ClosePreview" = "Close Preview";

View File

@ -81,6 +81,25 @@ extension NotificationViewController {
} }
} }
.store(in: &disposeBag) .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) { override func viewWillAppear(_ animated: Bool) {
@ -122,14 +141,7 @@ extension NotificationViewController {
extension NotificationViewController { extension NotificationViewController {
@objc private func segmentedControlValueChanged(_ sender: UISegmentedControl) { @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) 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)! viewModel.selectedIndex.value = NotificationViewModel.NotificationSegment(rawValue: sender.selectedSegmentIndex)!
} }
@ -273,8 +285,70 @@ extension NotificationViewController: LoadMoreConfigurableTableViewContainer {
} }
extension NotificationViewController { 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]? { override var keyCommands: [UIKeyCommand]? {
return navigationKeyCommands return categorySwitchKeyCommands + navigationKeyCommands
} }
} }

View File

@ -58,13 +58,19 @@ extension ProfilePagingViewController {
} }
// workaround to fix tab man responder chain issue
extension ProfilePagingViewController { extension ProfilePagingViewController {
override var keyCommands: [UIKeyCommand]? { override var keyCommands: [UIKeyCommand]? {
return currentViewController?.keyCommands 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) (currentViewController as? StatusTableViewControllerNavigateable)?.statusKeyCommandHandlerRelay(sender)
} }