diff --git a/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift b/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift index 0c03d54e..f33672a8 100644 --- a/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift +++ b/IceCubesApp/App/Tabs/Timeline/TimelineTab.swift @@ -76,6 +76,14 @@ struct TimelineTab: View { @ViewBuilder private var timelineFilterButton: some View { + if timeline == .home { + Button { + self.timeline = .latest + } label: { + Label(TimelineFilter.latest.localizedTitle(), systemImage: TimelineFilter.latest.iconName() ?? "") + } + Divider() + } ForEach(TimelineFilter.availableTimeline(client: client), id: \.self) { timeline in Button { self.timeline = timeline diff --git a/IceCubesApp/Resources/Localization/ca.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/ca.lproj/Localizable.strings index 45b253ea..7d77c82a 100644 --- a/IceCubesApp/Resources/Localization/ca.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/ca.lproj/Localizable.strings @@ -298,6 +298,7 @@ // MARK: Package: Timeline "timeline.federated" = "Federada"; +"timeline.latest" = "Jump to Latest"; "timeline.home" = "Inici"; "timeline.local" = "Local"; "timeline.n-recent-from-n-participants %lld %lld" = "%lld publicació recents de %lld participants"; diff --git a/IceCubesApp/Resources/Localization/de.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/de.lproj/Localizable.strings index e324fb00..5a1f897f 100644 --- a/IceCubesApp/Resources/Localization/de.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/de.lproj/Localizable.strings @@ -300,6 +300,7 @@ // MARK: Package: Timeline "timeline.federated" = "Föderiert"; +"timeline.latest" = "Jump to Latest"; "timeline.home" = "Startseite"; "timeline.local" = "Lokal"; "timeline.n-recent-from-n-participants %lld %lld" = "%lld aktuelle Beiträge von %lld Teilnehmenden"; diff --git a/IceCubesApp/Resources/Localization/en-GB.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/en-GB.lproj/Localizable.strings index abc4ef62..257cd849 100644 --- a/IceCubesApp/Resources/Localization/en-GB.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/en-GB.lproj/Localizable.strings @@ -300,6 +300,7 @@ // MARK: Package: Timeline "timeline.federated" = "Federated"; +"timeline.latest" = "Jump to Latest"; "timeline.home" = "Home"; "timeline.local" = "Local"; "timeline.n-recent-from-n-participants %lld %lld" = "%lld recent posts from %lld participants"; diff --git a/IceCubesApp/Resources/Localization/en.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/en.lproj/Localizable.strings index ec11ef8d..cbe6b380 100644 --- a/IceCubesApp/Resources/Localization/en.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/en.lproj/Localizable.strings @@ -300,6 +300,7 @@ // MARK: Package: Timeline "timeline.federated" = "Federated"; +"timeline.latest" = "Jump to Latest"; "timeline.home" = "Home"; "timeline.local" = "Local"; "timeline.n-recent-from-n-participants %lld %lld" = "%lld recent posts from %lld participants"; diff --git a/IceCubesApp/Resources/Localization/es.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/es.lproj/Localizable.strings index 2f69a05c..2aa6488d 100644 --- a/IceCubesApp/Resources/Localization/es.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/es.lproj/Localizable.strings @@ -300,6 +300,7 @@ // MARK: Package: Timeline "timeline.federated" = "Federado"; +"timeline.latest" = "Jump to Latest"; "timeline.home" = "Inicio"; "timeline.local" = "Local"; "timeline.n-recent-from-n-participants %lld %lld" = "%lld publicaciones recientes de %lld participantes"; diff --git a/IceCubesApp/Resources/Localization/fr.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/fr.lproj/Localizable.strings index dbdd0708..a70a4e6f 100644 --- a/IceCubesApp/Resources/Localization/fr.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/fr.lproj/Localizable.strings @@ -295,6 +295,7 @@ // MARK: Package: Timeline "timeline.federated" = "Fédéré"; +"timeline.latest" = "Jump to Latest"; "timeline.home" = "Accueil"; "timeline.local" = "Local"; "timeline.n-recent-from-n-participants %lld %lld" = "%lld publications récentes de %lld participants"; diff --git a/IceCubesApp/Resources/Localization/it.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/it.lproj/Localizable.strings index e331dc6d..abd28cdc 100644 --- a/IceCubesApp/Resources/Localization/it.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/it.lproj/Localizable.strings @@ -300,6 +300,7 @@ // MARK: Package: Timeline "timeline.federated" = "Federazione"; +"timeline.latest" = "Jump to Latest"; "timeline.home" = "Home"; "timeline.local" = "Locale"; "timeline.n-recent-from-n-participants %lld %lld" = "%lld post recenti da %lld partecipanti"; diff --git a/IceCubesApp/Resources/Localization/ja.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/ja.lproj/Localizable.strings index 2bc0b192..640e34e9 100644 --- a/IceCubesApp/Resources/Localization/ja.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/ja.lproj/Localizable.strings @@ -299,6 +299,7 @@ // MARK: Package: Timeline "timeline.federated" = "連合"; +"timeline.latest" = "Jump to Latest"; "timeline.home" = "ホーム"; "timeline.local" = "ローカル"; "timeline.n-recent-from-n-participants %lld %lld" = "%lld トゥートの投稿 %lld 人が投稿している"; diff --git a/IceCubesApp/Resources/Localization/ko.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/ko.lproj/Localizable.strings index c7b0a387..c96ce3a5 100644 --- a/IceCubesApp/Resources/Localization/ko.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/ko.lproj/Localizable.strings @@ -301,6 +301,7 @@ // MARK: Package: Timeline "timeline.federated" = "연합"; +"timeline.latest" = "Jump to Latest"; "timeline.home" = "홈"; "timeline.local" = "로컬"; "timeline.n-recent-from-n-participants %lld %lld" = "%lld개의 최근 글 (%lld명의 사용자가 이야기 중)"; diff --git a/IceCubesApp/Resources/Localization/nb.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/nb.lproj/Localizable.strings index 6c689042..3ff86dc0 100644 --- a/IceCubesApp/Resources/Localization/nb.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/nb.lproj/Localizable.strings @@ -299,6 +299,7 @@ // MARK: Package: Timeline "timeline.federated" = "Federert"; +"timeline.latest" = "Jump to Latest"; "timeline.home" = "Hjem"; "timeline.local" = "Lokal"; "timeline.n-recent-from-n-participants %lld %lld" = "%lld nylige innlegg fra %lld deltakere"; diff --git a/IceCubesApp/Resources/Localization/nl.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/nl.lproj/Localizable.strings index c86cb76b..7391f9d7 100644 --- a/IceCubesApp/Resources/Localization/nl.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/nl.lproj/Localizable.strings @@ -293,6 +293,7 @@ // MARK: Package: Timeline "timeline.federated" = "Gefedereerd"; +"timeline.latest" = "Jump to Latest"; "timeline.home" = "Start"; "timeline.local" = "Lokaal"; "timeline.n-recent-from-n-participants %lld %lld" = "%lld recente posts van %lld deelnemers"; diff --git a/IceCubesApp/Resources/Localization/pl.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/pl.lproj/Localizable.strings index c8b61cce..2bbb053f 100644 --- a/IceCubesApp/Resources/Localization/pl.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/pl.lproj/Localizable.strings @@ -296,6 +296,7 @@ // MARK: Package: Timeline "timeline.federated" = "Strumień globalny"; +"timeline.latest" = "Jump to Latest"; "timeline.home" = "Strona domowa"; "timeline.local" = "Strumień lokalny"; "timeline.trending" = "Teraz popularne"; diff --git a/IceCubesApp/Resources/Localization/pt-BR.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/pt-BR.lproj/Localizable.strings index 11d78e45..a646122b 100644 --- a/IceCubesApp/Resources/Localization/pt-BR.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/pt-BR.lproj/Localizable.strings @@ -299,6 +299,7 @@ // MARK: Package: Timeline "timeline.federated" = "Linha global"; +"timeline.latest" = "Jump to Latest"; "timeline.home" = "Início"; "timeline.local" = "Linha local"; "timeline.n-recent-from-n-participants %lld %lld" = "%lld postagens recentes de %lld participantes"; diff --git a/IceCubesApp/Resources/Localization/tr.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/tr.lproj/Localizable.strings index f6f10021..28ccfd67 100644 --- a/IceCubesApp/Resources/Localization/tr.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/tr.lproj/Localizable.strings @@ -295,6 +295,7 @@ // MARK: Package: Timeline "timeline.federated" = "Birleştirilmiş"; +"timeline.latest" = "Jump to Latest"; "timeline.home" = "Ana Ekran"; "timeline.local" = "Yerel"; "timeline.n-recent-from-n-participants %lld %lld" = "%lld katılımcılar tarafından %lld yeni gönderiler"; diff --git a/IceCubesApp/Resources/Localization/zh-Hans.lproj/Localizable.strings b/IceCubesApp/Resources/Localization/zh-Hans.lproj/Localizable.strings index b400d608..91ae9c63 100644 --- a/IceCubesApp/Resources/Localization/zh-Hans.lproj/Localizable.strings +++ b/IceCubesApp/Resources/Localization/zh-Hans.lproj/Localizable.strings @@ -300,6 +300,7 @@ // MARK: Package: Timeline "timeline.federated" = "跨站"; +"timeline.latest" = "Jump to Latest"; "timeline.home" = "主页"; "timeline.local" = "本地"; "timeline.n-recent-from-n-participants %lld %lld" = "最近 %lld 条嘟文来自 %lld 个参与者"; diff --git a/Packages/Timeline/Sources/Timeline/TimelineFilter.swift b/Packages/Timeline/Sources/Timeline/TimelineFilter.swift index ddfe3331..ce37ac4c 100644 --- a/Packages/Timeline/Sources/Timeline/TimelineFilter.swift +++ b/Packages/Timeline/Sources/Timeline/TimelineFilter.swift @@ -8,6 +8,7 @@ public enum TimelineFilter: Hashable, Equatable { case hashtag(tag: String, accountId: String?) case list(list: Models.List) case remoteLocal(server: String) + case latest public func hash(into hasher: inout Hasher) { hasher.combine(title) @@ -22,6 +23,8 @@ public enum TimelineFilter: Hashable, Equatable { public var title: String { switch self { + case .latest: + return "Latest" case .federated: return "Federated" case .local: @@ -41,6 +44,8 @@ public enum TimelineFilter: Hashable, Equatable { public func localizedTitle() -> LocalizedStringKey { switch self { + case .latest: + return "timeline.latest" case .federated: return "timeline.federated" case .local: @@ -60,6 +65,8 @@ public enum TimelineFilter: Hashable, Equatable { public func iconName() -> String? { switch self { + case .latest: + return "arrow.counterclockwise" case .federated: return "globe.americas" case .local: @@ -82,6 +89,7 @@ public enum TimelineFilter: Hashable, Equatable { 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 .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) case let .list(list): return Timelines.list(listId: list.id, sinceId: sinceId, maxId: maxId, minId: minId) diff --git a/Packages/Timeline/Sources/Timeline/TimelineView.swift b/Packages/Timeline/Sources/Timeline/TimelineView.swift index 0973cffc..3d575d06 100644 --- a/Packages/Timeline/Sources/Timeline/TimelineView.swift +++ b/Packages/Timeline/Sources/Timeline/TimelineView.swift @@ -115,6 +115,9 @@ public struct TimelineView: View { } viewModel.timeline = newTimeline } + .onChange(of: viewModel.timeline, perform: { newValue in + timeline = newValue + }) .onChange(of: scenePhase, perform: { scenePhase in switch scenePhase { case .active: diff --git a/Packages/Timeline/Sources/Timeline/TimelineViewModel.swift b/Packages/Timeline/Sources/Timeline/TimelineViewModel.swift index 5f0a4be9..ae84fa12 100644 --- a/Packages/Timeline/Sources/Timeline/TimelineViewModel.swift +++ b/Packages/Timeline/Sources/Timeline/TimelineViewModel.swift @@ -11,6 +11,10 @@ class TimelineViewModel: ObservableObject { @Published var timeline: TimelineFilter = .federated { didSet { Task { + if timeline == .latest, let client { + await cache.clearCache(for: client) + timeline = .home + } if oldValue != timeline { statuses = [] pendingStatusesObserver.pendingStatuses = []