krz/hutch
an ios client for sourcehut
clone: git clone https://gitbay.org/krz/hutch.git
v3.9.0: Hutch/Views/More/MoreView.swift · raw
1import SwiftUI
2
3struct MoreView: View {
4 @Environment(AppState.self) private var appState
5
6 private let unsupportedLinks: [(title: String, url: URL)] = [
7 ("chat.sr.ht", SRHTWebURL.chat)
8 ]
9
10 @State private var viewModel: MoreViewModel?
11 @State private var showAccountSwitcher = false
12
13 var body: some View {
14 List {
15 Section("Search") {
16 NavigationLink(value: MoreRoute.lookup(query: nil, type: nil)) {
17 Label("Look Up", systemImage: "magnifyingglass")
18 }
19 .themedRow()
20 }
21
22 Section("Other Services") {
23 NavigationLink(value: MoreRoute.projects) {
24 Label("Projects", systemImage: "square.stack.3d.up")
25 }
26 .themedRow()
27
28 NavigationLink(value: MoreRoute.lists) {
29 Label("Mailing Lists", systemImage: "list.bullet.rectangle")
30 }
31 .themedRow()
32
33 NavigationLink(value: MoreRoute.manPageBrowser) {
34 Label("Man Pages", systemImage: "book")
35 }
36 .themedRow()
37
38 NavigationLink(value: MoreRoute.pastes) {
39 Label("Pastes", systemImage: "doc.on.clipboard")
40 }
41 .themedRow()
42
43 NavigationLink(value: MoreRoute.systemStatus) {
44 SystemStatusSummaryRow(
45 snapshot: viewModel?.systemStatusSnapshot,
46 isLoading: viewModel?.isLoadingSystemStatus ?? true,
47 errorMessage: viewModel?.systemStatusErrorMessage,
48 isShowingStaleData: viewModel?.isShowingStaleSystemStatus ?? false
49 )
50 }
51 .themedRow()
52 }
53
54 Section("Meta") {
55 NavigationLink(value: MoreRoute.profile) {
56 Label("Profile", systemImage: "person.text.rectangle")
57 }
58 .themedRow()
59
60 NavigationLink(value: MoreRoute.settings) {
61 Label("Settings", systemImage: "gear")
62 }
63 .themedRow()
64
65 NavigationLink(value: MoreRoute.about) {
66 Label("About Hutch", systemImage: "info.circle")
67 }
68 .themedRow()
69 }
70
71 Section {
72 ForEach(unsupportedLinks, id: \.title) { item in
73 Link(destination: item.url) {
74 Label(item.title, systemImage: "safari")
75 }
76 }
77 .themedRow()
78 } header: {
79 Text("External Links")
80 } footer: {
81 Text("These SourceHut services are not supported in-app, as the SourceHut API does not support them, and will open in your browser.")
82 }
83 }
84 .themedList()
85 .navigationTitle("More")
86 .refreshable {
87 await ensureViewModel().loadSystemStatus(forceRefresh: true)
88 }
89 .task {
90 await ensureViewModel().loadIfNeeded()
91 }
92 .toolbar {
93 ToolbarItem(placement: .topBarTrailing) {
94 Button {
95 showAccountSwitcher = true
96 } label: {
97 Image(systemName: "person.crop.circle.badge.plus")
98 }
99 }
100 }
101 .sheet(isPresented: $showAccountSwitcher) {
102 AccountSwitcherView()
103 }
104 }
105
106 @MainActor
107 private func ensureViewModel() -> MoreViewModel {
108 if let viewModel {
109 return viewModel
110 }
111
112 let newViewModel = MoreViewModel(repository: appState.systemStatusRepository)
113 viewModel = newViewModel
114 return newViewModel
115 }
116}