krz/hutch

an ios client for sourcehut

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

v2.7.0: Hutch/Views/Repositories/RepositoryDetailView.swift · raw

  1import SwiftUI
  2
  3struct RepositoryDetailView: View {
  4    var repository: RepositorySummary
  5    var onDeleted: (() -> Void)?
  6
  7    @Environment(AppState.self) private var appState
  8    @Environment(\.dismiss) private var dismiss
  9    @State private var viewModel: RepositoryDetailViewModel?
 10    @State private var selectedTab: RepositoryDetailViewModel.Tab = .summary
 11    @State private var showSettings = false
 12    @State private var displayName: String
 13
 14    init(repository: RepositorySummary, onDeleted: (() -> Void)? = nil) {
 15        self.repository = repository
 16        self.onDeleted = onDeleted
 17        self._displayName = State(initialValue: repository.name)
 18    }
 19
 20    var body: some View {
 21        if repository.service == .hg {
 22            HgRepositoryDetailView(repository: repository, onDeleted: onDeleted)
 23        } else {
 24            Group {
 25                if let viewModel {
 26                    detailContent(viewModel)
 27                } else {
 28                    SRHTLoadingStateView(message: "Loading repository…")
 29                }
 30            }
 31            .navigationTitle(displayName)
 32            .navigationBarTitleDisplayMode(.inline)
 33            .toolbar {
 34                ToolbarItemGroup(placement: .topBarTrailing) {
 35                    SRHTShareButton(url: SRHTWebURL.repository(repository), target: .repository) {
 36                        Image(systemName: "square.and.arrow.up")
 37                    }
 38
 39                    Button {
 40                        showSettings = true
 41                    } label: {
 42                        Image(systemName: "gear")
 43                    }
 44                }
 45            }
 46            .sheet(isPresented: $showSettings) {
 47                RepositorySettingsView(
 48                    repository: repository,
 49                    branches: viewModel?.branches ?? [],
 50                    client: appState.client,
 51                    onRenamed: { newName in
 52                        displayName = newName
 53                    },
 54                    onDeleted: {
 55                        dismiss()
 56                        onDeleted?()
 57                    }
 58                )
 59            }
 60            .task {
 61                if viewModel == nil {
 62                    viewModel = RepositoryDetailViewModel(
 63                        repository: repository,
 64                        client: appState.client
 65                    )
 66                }
 67            }
 68        }
 69    }
 70
 71    @ViewBuilder
 72    private func detailContent(_ viewModel: RepositoryDetailViewModel) -> some View {
 73        VStack(spacing: 0) {
 74            Picker("Tab", selection: $selectedTab) {
 75                ForEach(RepositoryDetailViewModel.Tab.allCases, id: \.self) { tab in
 76                    Text(tab.rawValue).tag(tab)
 77                }
 78            }
 79            .pickerStyle(.segmented)
 80            .padding(.horizontal)
 81            .padding(.vertical, 8)
 82
 83            Divider()
 84
 85            switch selectedTab {
 86            case .summary:
 87                ReadmeView(viewModel: viewModel)
 88            case .tree:
 89                FileTreeView(
 90                    repository: repository,
 91                    client: appState.client
 92                )
 93            case .log:
 94                CommitLogView(viewModel: viewModel)
 95            case .refs:
 96                ReferencesListView(viewModel: viewModel)
 97            case .artifacts:
 98                ArtifactsView(viewModel: viewModel)
 99            }
100        }
101        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
102        .srhtErrorBanner(error: Binding(
103            get: { viewModel.error },
104            set: { viewModel.error = $0 }
105        ))
106    }
107}