krz/hutch

an ios client for sourcehut

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

v3.7.0: Hutch/Views/Repositories/ArtifactsView.swift · raw

 1import SwiftUI
 2
 3struct ArtifactsView: View {
 4    let viewModel: RepositoryDetailViewModel
 5    @Environment(\.openURL) private var openURL
 6
 7    var body: some View {
 8        List {
 9            ForEach(viewModel.referenceArtifacts) { refArtifacts in
10                Section(refArtifacts.name) {
11                    ForEach(refArtifacts.artifacts) { artifact in
12                        ArtifactRow(artifact: artifact) {
13                            openURL(artifact.url)
14                        }
15                    }
16                    .themedRow()
17                }
18            }
19        }
20        .themedList()
21        .listStyle(.insetGrouped)
22        .overlay {
23            if viewModel.isLoadingArtifacts, viewModel.referenceArtifacts.isEmpty {
24                SRHTLoadingStateView(message: "Loading artifacts…")
25            } else if let error = viewModel.error, viewModel.referenceArtifacts.isEmpty {
26                SRHTErrorStateView(
27                    title: "Couldn't Load Artifacts",
28                    message: error,
29                    retryAction: { await viewModel.loadArtifacts() }
30                )
31            } else if viewModel.referenceArtifacts.isEmpty {
32                ContentUnavailableView(
33                    "No Artifacts",
34                    systemImage: "archivebox",
35                    description: Text("This repository has no release artifacts.")
36                )
37            }
38        }
39        .task {
40            if viewModel.referenceArtifacts.isEmpty {
41                await viewModel.loadArtifacts()
42            }
43        }
44        .refreshable {
45            await viewModel.loadArtifacts()
46        }
47    }
48}
49
50private struct ArtifactRow: View {
51    let artifact: ArtifactInfo
52    let onDownload: () -> Void
53
54    var body: some View {
55        HStack {
56            VStack(alignment: .leading, spacing: 4) {
57                Text(artifact.filename)
58                    .font(.subheadline)
59
60                Text(artifact.size.formattedByteCount)
61                    .font(.caption)
62                    .foregroundStyle(.secondary)
63            }
64
65            Spacer()
66
67            Button {
68                onDownload()
69            } label: {
70                Image(systemName: "arrow.down.circle")
71                    .imageScale(.large)
72            }
73        }
74    }
75}