krz/hutch

an ios client for sourcehut

clone: git clone https://gitbay.org/krz/hutch.git

v3.1.7: 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) {
 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}