diff --git a/.github/workflows/publishing.yml b/.github/workflows/publishing.yml index b4390a6..962bc9b 100644 --- a/.github/workflows/publishing.yml +++ b/.github/workflows/publishing.yml @@ -38,6 +38,7 @@ jobs: path: | ~/Library/Caches/org.swift.swiftpm ~/Library/Developer/Xcode/DerivedData/**/SourcePackages/checkouts + ~/Library/Developer/Xcode/DerivedData/**/SourcePackages/repositories key: ${{ runner.os }}-${{ matrix.platform }}-spm-${{ hashFiles('**/Package.resolved') }} restore-keys: | ${{ runner.os }}-${{ matrix.platform }}-spm- diff --git a/Fyreplace.xcodeproj/project.pbxproj b/Fyreplace.xcodeproj/project.pbxproj index a92c385..51f3678 100644 --- a/Fyreplace.xcodeproj/project.pbxproj +++ b/Fyreplace.xcodeproj/project.pbxproj @@ -51,6 +51,7 @@ 4DB2E3792C43E304007F958D /* RegisterScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DB2E3782C43E304007F958D /* RegisterScreenTests.swift */; }; 4DCE062B2C08E5E200F69AF1 /* CompactNavigation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCE062A2C08E5E200F69AF1 /* CompactNavigation.swift */; }; 4DCE062D2C08E65300F69AF1 /* RegularNavigation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DCE062C2C08E65300F69AF1 /* RegularNavigation.swift */; }; + 4DE140CD2C52688000A699AE /* DestinationCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DE140CC2C52687F00A699AE /* DestinationCommands.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -132,6 +133,7 @@ 4DCEF8652C452EBA00F53085 /* .env-example */ = {isa = PBXFileReference; lastKnownFileType = text; path = ".env-example"; sourceTree = ""; }; 4DCEF8662C452ECC00F53085 /* .env */ = {isa = PBXFileReference; lastKnownFileType = text; path = .env; sourceTree = ""; }; 4DD826FD2BF9FDC500799CEB /* Config.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = Config.sh; sourceTree = ""; }; + 4DE140CC2C52687F00A699AE /* DestinationCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DestinationCommands.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -345,6 +347,7 @@ 4DB10B4E2C4FEBCE00634BF6 /* Commands */ = { isa = PBXGroup; children = ( + 4DE140CC2C52687F00A699AE /* DestinationCommands.swift */, 4DB10B4F2C4FEBFC00634BF6 /* HelpCommands.swift */, ); path = Commands; @@ -561,6 +564,7 @@ 4D5251EC2C1097A600018CD2 /* Destination.swift in Sources */, 4D54C92E2BF2608A001DE071 /* MainView.swift in Sources */, 4D5251F12C109D0D00018CD2 /* Screen.swift in Sources */, + 4DE140CD2C52688000A699AE /* DestinationCommands.swift in Sources */, 4D54C96B2BF4E97E001DE071 /* NotificationsScreen.swift in Sources */, 4D9B3B472C36F50300A8F7AD /* UITextContentType.swift in Sources */, 4D9B3B382C334B3A00A8F7AD /* LoginScreen.swift in Sources */, diff --git a/Fyreplace/Commands/DestinationCommands.swift b/Fyreplace/Commands/DestinationCommands.swift new file mode 100644 index 0000000..4c9cdbe --- /dev/null +++ b/Fyreplace/Commands/DestinationCommands.swift @@ -0,0 +1,31 @@ +import Combine +import SwiftUI + +struct DestinationCommands: Commands { + var body: some Commands { + CommandGroup(after: .sidebar) { + Divider() + + ForEach(Destination.all) { destination in + Button(destination.titleKey) { + DestinationCommandKey.subject.send(destination) + } + .keyboardShortcut(destination.keyboardShortcut) + } + + Divider() + } + } +} + +private struct DestinationCommandKey: EnvironmentKey { + static let subject = PassthroughSubject() + static let defaultValue = subject.eraseToAnyPublisher() +} + +extension EnvironmentValues { + var destinationCommands: AnyPublisher { + get { self[DestinationCommandKey.self] } + set { self[DestinationCommandKey.self] = newValue } + } +} diff --git a/Fyreplace/FyreplaceApp.swift b/Fyreplace/FyreplaceApp.swift index b91a4f7..1c4aa7e 100644 --- a/Fyreplace/FyreplaceApp.swift +++ b/Fyreplace/FyreplaceApp.swift @@ -22,8 +22,9 @@ struct FyreplaceApp: App { MainView() } .commands { - SidebarCommands() ToolbarCommands() + SidebarCommands() + DestinationCommands() HelpCommands() } } diff --git a/Fyreplace/Views/Navigation/Destination.swift b/Fyreplace/Views/Navigation/Destination.swift index 9ac9685..3ffd5d8 100644 --- a/Fyreplace/Views/Navigation/Destination.swift +++ b/Fyreplace/Views/Navigation/Destination.swift @@ -72,5 +72,24 @@ public enum Destination: String, CaseIterable, Identifiable, Codable { } } + var keyboardShortcut: KeyboardShortcut? { + switch self { + case .feed: + .init("1") + case .notifications: + .init("2") + case .archive: + .init("3") + case .drafts: + .init("4") + case .published: + .init("5") + case .settings: + .init("6") + case .login, .register: + nil + } + } + static let all = allCases.filter(\.topLevel) } diff --git a/Fyreplace/Views/Navigation/RegularNavigation.swift b/Fyreplace/Views/Navigation/RegularNavigation.swift index e335c8d..847cd85 100644 --- a/Fyreplace/Views/Navigation/RegularNavigation.swift +++ b/Fyreplace/Views/Navigation/RegularNavigation.swift @@ -1,6 +1,9 @@ import SwiftUI struct RegularNavigation: View { + @Environment(\.destinationCommands) + private var destinationCommands + #if os(macOS) @SceneStorage("RegularNavigation.selectedDestination") private var selectedDestination = Destination.feed @@ -32,6 +35,9 @@ struct RegularNavigation: View { Screen(destination: finalDestination) } } + .onReceive(destinationCommands) { + selectedDestination = $0 + } } }