From 443c863465524d07228ece93ad958e65360dded4 Mon Sep 17 00:00:00 2001 From: CMK Date: Fri, 21 May 2021 17:42:14 +0800 Subject: [PATCH] feat: add segment control shortcut for profile scene --- Localization/app.json | 4 +- Mastodon.xcodeproj/project.pbxproj | 4 + Mastodon/Generated/Strings.swift | 4 + .../SegmentedControlNavigateable.swift | 95 +++++++++++++++++++ .../Resources/ar.lproj/Localizable.strings | 2 + .../Resources/en.lproj/Localizable.strings | 2 + .../Scene/Profile/ProfileViewController.swift | 23 ++++- 7 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 Mastodon/Protocol/SegmentedControlNavigateable.swift diff --git a/Localization/app.json b/Localization/app.json index fb7c943bb..ee2f763e2 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -88,7 +88,9 @@ "common": { "switch_to_tab": "Switch to %s", "show_favorites": "Show Favorites", - "open_settings": "Open Settings" + "open_settings": "Open Settings", + "previous_section": "Previous Section", + "next_section": "Next Section" }, "timeline": { "previous_status": "Previous Status", diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index b838d6c5c..6df7a15af 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -202,6 +202,7 @@ DB1D843026566512000346B3 /* KeyboardPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1D842F26566512000346B3 /* KeyboardPreference.swift */; }; DB1D843426579931000346B3 /* TableViewControllerNavigateable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1D843326579931000346B3 /* TableViewControllerNavigateable.swift */; }; DB1D843626579DB5000346B3 /* StatusProvider+TableViewControllerNavigateable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1D843526579DB5000346B3 /* StatusProvider+TableViewControllerNavigateable.swift */; }; + DB1D84382657B275000346B3 /* SegmentedControlNavigateable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1D84372657B275000346B3 /* SegmentedControlNavigateable.swift */; }; DB1E346825F518E20079D7DF /* CategoryPickerSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1E346725F518E20079D7DF /* CategoryPickerSection.swift */; }; DB1E347825F519300079D7DF /* PickServerItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1E347725F519300079D7DF /* PickServerItem.swift */; }; DB1FD43625F26899004CFCFC /* MastodonPickServerViewModel+LoadIndexedServerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1FD43525F26899004CFCFC /* MastodonPickServerViewModel+LoadIndexedServerState.swift */; }; @@ -762,6 +763,7 @@ DB1D842F26566512000346B3 /* KeyboardPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardPreference.swift; sourceTree = ""; }; DB1D843326579931000346B3 /* TableViewControllerNavigateable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewControllerNavigateable.swift; sourceTree = ""; }; DB1D843526579DB5000346B3 /* StatusProvider+TableViewControllerNavigateable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StatusProvider+TableViewControllerNavigateable.swift"; sourceTree = ""; }; + DB1D84372657B275000346B3 /* SegmentedControlNavigateable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentedControlNavigateable.swift; sourceTree = ""; }; DB1E346725F518E20079D7DF /* CategoryPickerSection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CategoryPickerSection.swift; sourceTree = ""; }; DB1E347725F519300079D7DF /* PickServerItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PickServerItem.swift; sourceTree = ""; }; DB1FD43525F26899004CFCFC /* MastodonPickServerViewModel+LoadIndexedServerState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MastodonPickServerViewModel+LoadIndexedServerState.swift"; sourceTree = ""; }; @@ -1353,6 +1355,7 @@ 2D38F20725CD491300561493 /* DisposeBagCollectable.swift */, 5DF1058425F88AE500D6C0D4 /* NeedsDependency+AVPlayerViewControllerDelegate.swift */, DBE3CE12261D7D4200430CC6 /* StatusTableViewControllerAspect.swift */, + DB1D84372657B275000346B3 /* SegmentedControlNavigateable.swift */, DB1D843326579931000346B3 /* TableViewControllerNavigateable.swift */, DB1D842D26552C4D000346B3 /* StatusTableViewControllerNavigateable.swift */, ); @@ -3197,6 +3200,7 @@ 5B90C460262599800002E742 /* SettingsAppearanceTableViewCell.swift in Sources */, DB8AF54425C13647002E6C99 /* SceneCoordinator.swift in Sources */, 5DF1058525F88AE500D6C0D4 /* NeedsDependency+AVPlayerViewControllerDelegate.swift in Sources */, + DB1D84382657B275000346B3 /* SegmentedControlNavigateable.swift in Sources */, DB447697260B439000B66B82 /* CustomEmojiPickerHeaderCollectionReusableView.swift in Sources */, DB45FAF925CA80A2005A8AC7 /* APIService+CoreData+MastodonAuthentication.swift in Sources */, 2D04F42525C255B9003F936F /* APIService+PublicTimeline.swift in Sources */, diff --git a/Mastodon/Generated/Strings.swift b/Mastodon/Generated/Strings.swift index 3dd633372..0b2ecfbfb 100644 --- a/Mastodon/Generated/Strings.swift +++ b/Mastodon/Generated/Strings.swift @@ -199,8 +199,12 @@ internal enum L10n { } internal enum Keyboard { internal enum Common { + /// Next Section + internal static let nextSection = L10n.tr("Localizable", "Common.Controls.Keyboard.Common.NextSection") /// Open Settings internal static let openSettings = L10n.tr("Localizable", "Common.Controls.Keyboard.Common.OpenSettings") + /// Previous Section + internal static let previousSection = L10n.tr("Localizable", "Common.Controls.Keyboard.Common.PreviousSection") /// Show Favorites internal static let showFavorites = L10n.tr("Localizable", "Common.Controls.Keyboard.Common.ShowFavorites") /// Switch to %@ diff --git a/Mastodon/Protocol/SegmentedControlNavigateable.swift b/Mastodon/Protocol/SegmentedControlNavigateable.swift new file mode 100644 index 000000000..16ff25460 --- /dev/null +++ b/Mastodon/Protocol/SegmentedControlNavigateable.swift @@ -0,0 +1,95 @@ +// +// SegmentedControlNavigateable.swift +// Mastodon +// +// Created by MainasuK Cirno on 2021-5-21. +// + +import UIKit + +typealias SegmentedControlNavigateable = SegmentedControlNavigateableCore & SegmentedControlNavigateableRelay + +protocol SegmentedControlNavigateableCore: AnyObject { + var navigateableSegmentedControl: UISegmentedControl { get } + var segmentedControlNavigateKeyCommands: [UIKeyCommand] { get } + + func segmentedControlNavigateKeyCommandHandler(_ sender: UIKeyCommand) + func navigate(direction: SegmentedControlNavigationDirection) +} + +@objc protocol SegmentedControlNavigateableRelay: AnyObject { + func segmentedControlNavigateKeyCommandHandlerRelay(_ sender: UIKeyCommand) +} + +enum SegmentedControlNavigationDirection: String, CaseIterable { + case previous + case next + + var title: String { + switch self { + case .previous: return L10n.Common.Controls.Keyboard.Common.previousSection + case .next: return L10n.Common.Controls.Keyboard.Common.nextSection + } + } + + // UIKeyCommand input + var input: String { + switch self { + case .previous: return "[" + case .next: return "]" + } + } + + var modifierFlags: UIKeyModifierFlags { + switch self { + case .previous: return [.shift, .command] + case .next: return [.shift, .command] + } + } + + var propertyList: Any { + return rawValue + } +} + +extension SegmentedControlNavigateableCore where Self: SegmentedControlNavigateableRelay { + var segmentedControlNavigateKeyCommands: [UIKeyCommand] { + SegmentedControlNavigationDirection.allCases.map { direction in + UIKeyCommand( + title: direction.title, + image: nil, + action: #selector(Self.segmentedControlNavigateKeyCommandHandlerRelay(_:)), + input: direction.input, + modifierFlags: direction.modifierFlags, + propertyList: direction.propertyList, + alternates: [], + discoverabilityTitle: nil, + attributes: [], + state: .off + ) + } + } + + func segmentedControlNavigateKeyCommandHandler(_ sender: UIKeyCommand) { + guard let rawValue = sender.propertyList as? String, + let direction = SegmentedControlNavigationDirection(rawValue: rawValue) else { return } + navigate(direction: direction) + } + +} + +extension SegmentedControlNavigateableCore { + func navigate(direction: SegmentedControlNavigationDirection) { + let index: Int = { + let selectedIndex = navigateableSegmentedControl.selectedSegmentIndex + switch direction { + case .previous: return selectedIndex - 1 + case .next: return selectedIndex + 1 + } + }() + + guard 0..