diff --git a/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift b/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift index f33672a8..08ec40bb 100644 --- a/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift +++ b/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift @@ -82,6 +82,7 @@ struct TimelineTab: View { } label: { Label(TimelineFilter.latest.localizedTitle(), systemImage: TimelineFilter.latest.iconName() ?? "") } + .keyboardShortcut("r", modifiers: .command) Divider() } ForEach(TimelineFilter.availableTimeline(client: client), id: \.self) { timeline in @@ -120,9 +121,11 @@ struct TimelineTab: View { Menu("timeline.filter.local") { ForEach(preferences.remoteLocalTimelines, id: \.self) { server in Button { - timeline = .remoteLocal(server: server) + timeline = .remoteLocal(server: server, filter: .local) } label: { - Label(server, systemImage: "dot.radiowaves.right") + VStack { + Label(server, systemImage: "dot.radiowaves.right") + } } } Button { @@ -171,13 +174,18 @@ struct TimelineTab: View { Image(systemName: "list.bullet") } } - case let .remoteLocal(server): + case let .remoteLocal(server, _): ToolbarItem { - Button { - preferences.remoteLocalTimelines.removeAll(where: { $0 == server }) - timeline = client.isAuth ? .home : .federated + Menu { + ForEach(RemoteTimelineFilter.allCases, id: \.self) { filter in + Button { + timeline = .remoteLocal(server: server, filter: filter) + } label: { + Label(filter.localizedTitle(), systemImage: filter.iconName()) + } + } } label: { - Image(systemName: "pin.slash") + Image(systemName: "line.3.horizontal.decrease.circle") } } default: diff --git a/Packages/Timeline/Sources/Timeline/TimelineFilter.swift b/Packages/Timeline/Sources/Timeline/TimelineFilter.swift index ce37ac4c..0b6d0758 100644 --- a/Packages/Timeline/Sources/Timeline/TimelineFilter.swift +++ b/Packages/Timeline/Sources/Timeline/TimelineFilter.swift @@ -3,11 +3,37 @@ import Models import Network import SwiftUI +public enum RemoteTimelineFilter: String, CaseIterable, Hashable, Equatable { + case local, federated, trending + + public func localizedTitle() -> LocalizedStringKey { + switch self { + case .federated: + return "timeline.federated" + case .local: + return "timeline.local" + case .trending: + return "timeline.trending" + } + } + + public func iconName() -> String { + switch self { + case .federated: + return "globe.americas" + case .local: + return "person.2" + case .trending: + return "chart.line.uptrend.xyaxis" + } + } +} + public enum TimelineFilter: Hashable, Equatable { case home, local, federated, trending case hashtag(tag: String, accountId: String?) case list(list: Models.List) - case remoteLocal(server: String) + case remoteLocal(server: String, filter: RemoteTimelineFilter) case latest public func hash(into hasher: inout Hasher) { @@ -37,7 +63,7 @@ public enum TimelineFilter: Hashable, Equatable { return "#\(tag)" case let .list(list): return list.title - case let .remoteLocal(server): + case let .remoteLocal(server, _): return server } } @@ -58,7 +84,7 @@ public enum TimelineFilter: Hashable, Equatable { return "#\(tag)" case let .list(list): return LocalizedStringKey(list.title) - case let .remoteLocal(server): + case let .remoteLocal(server, _): return LocalizedStringKey(server) } } @@ -88,7 +114,15 @@ public enum TimelineFilter: Hashable, Equatable { switch self { case .federated: return Timelines.pub(sinceId: sinceId, maxId: maxId, minId: minId, local: false) case .local: return Timelines.pub(sinceId: sinceId, maxId: maxId, minId: minId, local: true) - case .remoteLocal: return Timelines.pub(sinceId: sinceId, maxId: maxId, minId: minId, local: true) + case let .remoteLocal(_, filter): + switch filter { + case .local: + return Timelines.pub(sinceId: sinceId, maxId: maxId, minId: minId, local: true) + case .federated: + return Timelines.pub(sinceId: sinceId, maxId: maxId, minId: minId, local: false) + case .trending: + return Trends.statuses(offset: offset) + } case .latest: return Timelines.home(sinceId: nil, maxId: nil, minId: nil) case .home: return Timelines.home(sinceId: sinceId, maxId: maxId, minId: minId) case .trending: return Trends.statuses(offset: offset) diff --git a/Packages/Timeline/Sources/Timeline/TimelineView.swift b/Packages/Timeline/Sources/Timeline/TimelineView.swift index c40f9832..03beeba6 100644 --- a/Packages/Timeline/Sources/Timeline/TimelineView.swift +++ b/Packages/Timeline/Sources/Timeline/TimelineView.swift @@ -79,7 +79,23 @@ public struct TimelineView: View { } }) } - .navigationTitle(timeline.localizedTitle()) + .toolbar { + ToolbarItem(placement: .principal) { + VStack(alignment: .center) { + switch timeline { + case let .remoteLocal(_, filter): + Text(filter.localizedTitle()) + .font(.headline) + Text(timeline.localizedTitle()) + .font(.caption) + .foregroundColor(.gray) + default: + Text(timeline.localizedTitle()) + .font(.headline) + } + } + } + } .navigationBarTitleDisplayMode(.inline) .onAppear { viewModel.isTimelineVisible = true @@ -111,7 +127,7 @@ public struct TimelineView: View { } .onChange(of: timeline) { newTimeline in switch newTimeline { - case let .remoteLocal(server): + case let .remoteLocal(server, _): viewModel.client = Client(server: server) default: viewModel.client = client