2022-12-27 09:25:26 +01:00
|
|
|
import Account
|
2023-03-13 13:38:28 +01:00
|
|
|
import DesignSystem
|
2022-12-27 09:25:26 +01:00
|
|
|
import Explore
|
2023-01-17 11:36:01 +01:00
|
|
|
import Foundation
|
2024-01-06 19:27:26 +01:00
|
|
|
import StatusKit
|
2022-12-27 09:25:26 +01:00
|
|
|
import SwiftUI
|
|
|
|
|
2023-09-14 11:04:14 +02:00
|
|
|
@MainActor
|
2024-01-10 13:26:55 +01:00
|
|
|
enum Tab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
2023-01-19 07:24:24 +01:00
|
|
|
case timeline, notifications, mentions, explore, messages, settings, other
|
2023-01-16 14:40:23 +01:00
|
|
|
case trending, federated, local
|
|
|
|
case profile
|
2023-12-28 09:37:02 +01:00
|
|
|
case bookmarks
|
|
|
|
case favorites
|
2024-01-05 08:36:06 +01:00
|
|
|
case post
|
2024-01-10 13:26:55 +01:00
|
|
|
case followedTags
|
|
|
|
case lists
|
2023-01-17 11:36:01 +01:00
|
|
|
|
2023-09-14 11:04:14 +02:00
|
|
|
nonisolated var id: Int {
|
2022-12-27 09:25:26 +01:00
|
|
|
rawValue
|
|
|
|
}
|
2023-01-17 11:36:01 +01:00
|
|
|
|
2022-12-27 09:25:26 +01:00
|
|
|
static func loggedOutTab() -> [Tab] {
|
|
|
|
[.timeline, .settings]
|
|
|
|
}
|
2024-01-10 13:26:55 +01:00
|
|
|
|
|
|
|
static func visionOSTab() -> [Tab] {
|
|
|
|
[.profile, .timeline, .notifications, .mentions, .explore, .messages, .settings]
|
2022-12-27 09:25:26 +01:00
|
|
|
}
|
2023-01-17 11:36:01 +01:00
|
|
|
|
2022-12-27 09:25:26 +01:00
|
|
|
@ViewBuilder
|
2023-12-26 16:01:02 +01:00
|
|
|
func makeContentView(selectedTab: Binding<Tab>, popToRootTab: Binding<Tab>) -> some View {
|
2022-12-27 09:25:26 +01:00
|
|
|
switch self {
|
|
|
|
case .timeline:
|
|
|
|
TimelineTab(popToRootTab: popToRootTab)
|
2023-01-16 14:40:23 +01:00
|
|
|
case .trending:
|
|
|
|
TimelineTab(popToRootTab: popToRootTab, timeline: .trending)
|
|
|
|
case .local:
|
|
|
|
TimelineTab(popToRootTab: popToRootTab, timeline: .local)
|
|
|
|
case .federated:
|
|
|
|
TimelineTab(popToRootTab: popToRootTab, timeline: .federated)
|
2022-12-27 09:25:26 +01:00
|
|
|
case .notifications:
|
2023-12-26 16:01:02 +01:00
|
|
|
NotificationsTab(selectedTab: selectedTab, popToRootTab: popToRootTab, lockedType: nil)
|
2023-01-19 07:24:24 +01:00
|
|
|
case .mentions:
|
2023-12-26 16:01:02 +01:00
|
|
|
NotificationsTab(selectedTab: selectedTab, popToRootTab: popToRootTab, lockedType: .mention)
|
2022-12-27 09:25:26 +01:00
|
|
|
case .explore:
|
|
|
|
ExploreTab(popToRootTab: popToRootTab)
|
2023-01-05 12:21:54 +01:00
|
|
|
case .messages:
|
|
|
|
MessagesTab(popToRootTab: popToRootTab)
|
2022-12-27 09:25:26 +01:00
|
|
|
case .settings:
|
2023-11-18 11:58:04 +01:00
|
|
|
SettingsTabs(popToRootTab: popToRootTab, isModal: false)
|
2023-01-26 07:34:29 +01:00
|
|
|
case .profile:
|
|
|
|
ProfileTab(popToRootTab: popToRootTab)
|
2023-12-28 09:37:02 +01:00
|
|
|
case .bookmarks:
|
|
|
|
NavigationTab {
|
|
|
|
AccountStatusesListView(mode: .bookmarks)
|
|
|
|
}
|
|
|
|
case .favorites:
|
|
|
|
NavigationTab {
|
|
|
|
AccountStatusesListView(mode: .favorites)
|
|
|
|
}
|
2024-01-10 13:26:55 +01:00
|
|
|
case .followedTags:
|
|
|
|
NavigationTab {
|
|
|
|
FollowedTagsListView()
|
|
|
|
}
|
|
|
|
case .lists:
|
|
|
|
NavigationTab {
|
|
|
|
ListsListView()
|
|
|
|
}
|
2024-01-05 08:36:06 +01:00
|
|
|
case .post:
|
|
|
|
VStack { }
|
2023-01-26 07:34:29 +01:00
|
|
|
case .other:
|
2022-12-27 09:25:26 +01:00
|
|
|
EmptyView()
|
|
|
|
}
|
|
|
|
}
|
2023-01-17 11:36:01 +01:00
|
|
|
|
2022-12-27 09:25:26 +01:00
|
|
|
@ViewBuilder
|
|
|
|
var label: some View {
|
|
|
|
switch self {
|
|
|
|
case .timeline:
|
2023-01-19 18:14:08 +01:00
|
|
|
Label("tab.timeline", systemImage: iconName)
|
2023-01-16 14:40:23 +01:00
|
|
|
case .trending:
|
2023-01-19 18:14:08 +01:00
|
|
|
Label("tab.trending", systemImage: iconName)
|
2023-01-16 14:40:23 +01:00
|
|
|
case .local:
|
2023-01-19 18:14:08 +01:00
|
|
|
Label("tab.local", systemImage: iconName)
|
2023-01-16 14:40:23 +01:00
|
|
|
case .federated:
|
2023-01-19 18:14:08 +01:00
|
|
|
Label("tab.federated", systemImage: iconName)
|
2022-12-27 09:25:26 +01:00
|
|
|
case .notifications:
|
2023-01-19 18:14:08 +01:00
|
|
|
Label("tab.notifications", systemImage: iconName)
|
2023-01-19 07:24:24 +01:00
|
|
|
case .mentions:
|
2023-12-28 11:26:00 +01:00
|
|
|
Label("tab.mentions", systemImage: iconName)
|
2022-12-27 09:25:26 +01:00
|
|
|
case .explore:
|
2023-01-19 18:14:08 +01:00
|
|
|
Label("tab.explore", systemImage: iconName)
|
2023-01-05 12:21:54 +01:00
|
|
|
case .messages:
|
2023-01-19 18:14:08 +01:00
|
|
|
Label("tab.messages", systemImage: iconName)
|
2022-12-27 09:25:26 +01:00
|
|
|
case .settings:
|
2023-01-19 18:14:08 +01:00
|
|
|
Label("tab.settings", systemImage: iconName)
|
2023-01-26 07:34:29 +01:00
|
|
|
case .profile:
|
|
|
|
Label("tab.profile", systemImage: iconName)
|
2023-12-28 09:37:02 +01:00
|
|
|
case .bookmarks:
|
|
|
|
Label("accessibility.tabs.profile.picker.bookmarks", systemImage: iconName)
|
|
|
|
case .favorites:
|
|
|
|
Label("accessibility.tabs.profile.picker.favorites", systemImage: iconName)
|
2024-01-05 08:36:06 +01:00
|
|
|
case .post:
|
|
|
|
Label("menu.new-post", systemImage: iconName)
|
2024-01-10 13:26:55 +01:00
|
|
|
case .followedTags:
|
|
|
|
Label("timeline.filter.tags", systemImage: iconName)
|
|
|
|
case .lists:
|
|
|
|
Label("timeline.filter.lists", systemImage: iconName)
|
2023-01-26 07:34:29 +01:00
|
|
|
case .other:
|
2022-12-27 09:25:26 +01:00
|
|
|
EmptyView()
|
2024-01-05 08:36:06 +01:00
|
|
|
|
2022-12-27 09:25:26 +01:00
|
|
|
}
|
|
|
|
}
|
2023-01-17 11:36:01 +01:00
|
|
|
|
2023-01-16 14:40:23 +01:00
|
|
|
var iconName: String {
|
|
|
|
switch self {
|
|
|
|
case .timeline:
|
2023-09-16 14:15:03 +02:00
|
|
|
"rectangle.stack"
|
2023-01-16 14:40:23 +01:00
|
|
|
case .trending:
|
2023-09-16 14:15:03 +02:00
|
|
|
"chart.line.uptrend.xyaxis"
|
2023-01-16 14:40:23 +01:00
|
|
|
case .local:
|
2023-09-16 14:15:03 +02:00
|
|
|
"person.2"
|
2023-01-16 14:40:23 +01:00
|
|
|
case .federated:
|
2023-09-16 14:15:03 +02:00
|
|
|
"globe.americas"
|
2023-01-16 14:40:23 +01:00
|
|
|
case .notifications:
|
2023-09-16 14:15:03 +02:00
|
|
|
"bell"
|
2023-01-19 07:24:24 +01:00
|
|
|
case .mentions:
|
2023-09-16 14:15:03 +02:00
|
|
|
"at"
|
2023-01-16 14:40:23 +01:00
|
|
|
case .explore:
|
2023-09-16 14:15:03 +02:00
|
|
|
"magnifyingglass"
|
2023-01-16 14:40:23 +01:00
|
|
|
case .messages:
|
2023-09-16 14:15:03 +02:00
|
|
|
"tray"
|
2023-01-16 14:40:23 +01:00
|
|
|
case .settings:
|
2023-09-16 14:15:03 +02:00
|
|
|
"gear"
|
2023-01-26 07:34:29 +01:00
|
|
|
case .profile:
|
2023-09-16 14:15:03 +02:00
|
|
|
"person.crop.circle"
|
2023-12-28 09:37:02 +01:00
|
|
|
case .bookmarks:
|
|
|
|
"bookmark"
|
|
|
|
case .favorites:
|
|
|
|
"star"
|
2024-01-05 08:36:06 +01:00
|
|
|
case .post:
|
|
|
|
"square.and.pencil"
|
2024-01-10 13:26:55 +01:00
|
|
|
case .followedTags:
|
|
|
|
"tag"
|
|
|
|
case .lists:
|
|
|
|
"list.bullet"
|
2023-01-26 07:34:29 +01:00
|
|
|
case .other:
|
2023-09-16 14:15:03 +02:00
|
|
|
""
|
2023-01-16 14:40:23 +01:00
|
|
|
}
|
|
|
|
}
|
2022-12-27 09:25:26 +01:00
|
|
|
}
|
2023-12-28 11:26:00 +01:00
|
|
|
|
2024-01-10 13:26:55 +01:00
|
|
|
@Observable
|
|
|
|
class SidebarTabs {
|
|
|
|
struct SidedebarTab: Hashable, Codable {
|
|
|
|
let tab: Tab
|
|
|
|
var enabled: Bool
|
|
|
|
}
|
|
|
|
|
|
|
|
class Storage {
|
|
|
|
@AppStorage("sidebar_tabs") var tabs: [SidedebarTab] = [
|
|
|
|
.init(tab: .timeline, enabled: true),
|
|
|
|
.init(tab: .trending, enabled: true),
|
|
|
|
.init(tab: .federated, enabled: true),
|
|
|
|
.init(tab: .local, enabled: true),
|
|
|
|
.init(tab: .notifications, enabled: true),
|
|
|
|
.init(tab: .mentions, enabled: true),
|
|
|
|
.init(tab: .messages, enabled: true),
|
|
|
|
.init(tab: .explore, enabled: true),
|
|
|
|
.init(tab: .bookmarks, enabled: true),
|
|
|
|
.init(tab: .favorites, enabled: true),
|
|
|
|
.init(tab: .followedTags, enabled: true),
|
|
|
|
.init(tab: .lists, enabled: true),
|
|
|
|
|
|
|
|
.init(tab: .settings, enabled: true),
|
|
|
|
.init(tab: .profile, enabled: true),
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
private let storage = Storage()
|
|
|
|
public static let shared = SidebarTabs()
|
|
|
|
|
|
|
|
var tabs: [SidedebarTab] {
|
|
|
|
didSet {
|
|
|
|
storage.tabs = tabs
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func isEnabled(_ tab: Tab) -> Bool {
|
|
|
|
tabs.first(where: { $0.tab.id == tab.id })?.enabled == true
|
|
|
|
}
|
|
|
|
|
|
|
|
private init() {
|
|
|
|
tabs = storage.tabs
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-28 11:26:00 +01:00
|
|
|
@Observable
|
|
|
|
class iOSTabs {
|
|
|
|
enum TabEntries: String {
|
|
|
|
case first, second, third, fourth, fifth
|
|
|
|
}
|
|
|
|
|
|
|
|
class Storage {
|
|
|
|
@AppStorage(TabEntries.first.rawValue) var firstTab = Tab.timeline
|
|
|
|
@AppStorage(TabEntries.second.rawValue) var secondTab = Tab.notifications
|
|
|
|
@AppStorage(TabEntries.third.rawValue) var thirdTab = Tab.explore
|
|
|
|
@AppStorage(TabEntries.fourth.rawValue) var fourthTab = Tab.messages
|
|
|
|
@AppStorage(TabEntries.fifth.rawValue) var fifthTab = Tab.profile
|
|
|
|
}
|
|
|
|
|
|
|
|
private let storage = Storage()
|
|
|
|
public static let shared = iOSTabs()
|
|
|
|
|
|
|
|
var tabs: [Tab] {
|
|
|
|
[firstTab, secondTab, thirdTab, fourthTab, fifthTab]
|
|
|
|
}
|
|
|
|
|
|
|
|
var firstTab: Tab {
|
|
|
|
didSet {
|
|
|
|
storage.firstTab = firstTab
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var secondTab: Tab {
|
|
|
|
didSet {
|
|
|
|
storage.secondTab = secondTab
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var thirdTab: Tab {
|
|
|
|
didSet {
|
|
|
|
storage.thirdTab = thirdTab
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var fourthTab: Tab {
|
|
|
|
didSet {
|
|
|
|
storage.fourthTab = fourthTab
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var fifthTab: Tab {
|
|
|
|
didSet {
|
|
|
|
storage.fifthTab = fifthTab
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private init() {
|
|
|
|
firstTab = storage.firstTab
|
|
|
|
secondTab = storage.secondTab
|
|
|
|
thirdTab = storage.thirdTab
|
|
|
|
fourthTab = storage.fourthTab
|
|
|
|
fifthTab = storage.fifthTab
|
|
|
|
}
|
|
|
|
}
|