summaryrefslogtreecommitdiff
path: root/Hutch/Views/Repositories/RepositorySummarySupport.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-03-17 23:19:22 -0500
committerChristian Cleberg <[email protected]>2026-03-17 23:19:22 -0500
commit8f2057c53e9009c2529c9c4849c914666c0e4b40 (patch)
tree77b5a93625fe9ea98baf4ab0d137055524705dad /Hutch/Views/Repositories/RepositorySummarySupport.swift
parentd27726d8755a5631fbd2105f735811a95379c4ab (diff)
downloadhutch-8f2057c53e9009c2529c9c4849c914666c0e4b40.tar.gz
hutch-8f2057c53e9009c2529c9c4849c914666c0e4b40.tar.bz2
hutch-8f2057c53e9009c2529c9c4849c914666c0e4b40.zip
create privacy policy
Diffstat (limited to 'Hutch/Views/Repositories/RepositorySummarySupport.swift')
-rw-r--r--Hutch/Views/Repositories/RepositorySummarySupport.swift101
1 files changed, 101 insertions, 0 deletions
diff --git a/Hutch/Views/Repositories/RepositorySummarySupport.swift b/Hutch/Views/Repositories/RepositorySummarySupport.swift
new file mode 100644
index 0000000..8ad3659
--- /dev/null
+++ b/Hutch/Views/Repositories/RepositorySummarySupport.swift
@@ -0,0 +1,101 @@
+import SwiftUI
+
+struct RepositoryCloneURLs {
+ let readOnly: String
+ let readWrite: String
+}
+
+func repositoryCloneURLs(for repository: RepositorySummary) -> RepositoryCloneURLs {
+ let owner = repository.owner.canonicalName
+ let name = repository.name
+
+ switch repository.service {
+ case .git:
+ return RepositoryCloneURLs(
+ readOnly: "https://git.sr.ht/\(owner)/\(name)",
+ readWrite: "[email protected]:\(owner)/\(name)"
+ )
+ case .hg:
+ return RepositoryCloneURLs(
+ readOnly: "https://hg.sr.ht/\(owner)/\(name)",
+ readWrite: "ssh://[email protected]/\(owner)/\(name)"
+ )
+ default:
+ return RepositoryCloneURLs(
+ readOnly: "https://\(repository.service.rawValue).sr.ht/\(owner)/\(name)",
+ readWrite: ""
+ )
+ }
+}
+
+func repositoryVisibilityLabel(_ visibility: Visibility) -> String {
+ switch visibility {
+ case .public:
+ return "Public"
+ case .unlisted:
+ return "Unlisted"
+ case .private:
+ return "Private"
+ }
+}
+
+struct RepositorySummaryCard<Content: View>: View {
+ let title: String
+ @ViewBuilder let content: Content
+
+ init(_ title: String, @ViewBuilder content: () -> Content) {
+ self.title = title
+ self.content = content()
+ }
+
+ var body: some View {
+ VStack(alignment: .leading, spacing: 12) {
+ Text(title)
+ .font(.caption.weight(.semibold))
+ .foregroundStyle(.secondary)
+ .textCase(.uppercase)
+
+ content
+ }
+ .frame(maxWidth: .infinity, alignment: .leading)
+ .padding()
+ .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 16, style: .continuous))
+ }
+}
+
+struct RepositorySummaryField: View {
+ let label: String
+ let value: String
+ var monospace: Bool = false
+
+ var body: some View {
+ VStack(alignment: .leading, spacing: 4) {
+ Text(label)
+ .font(.caption)
+ .foregroundStyle(.secondary)
+ Text(value)
+ .font(monospace ? .system(.body, design: .monospaced) : .body)
+ .textSelection(.enabled)
+ }
+ }
+}
+
+struct RepositorySummaryListRow: View {
+ let label: String
+ let values: [String]
+
+ var body: some View {
+ VStack(alignment: .leading, spacing: 4) {
+ Text(label)
+ .font(.caption)
+ .foregroundStyle(.secondary)
+
+ if values.isEmpty {
+ Text("None")
+ .foregroundStyle(.tertiary)
+ } else {
+ Text(values.joined(separator: ", "))
+ }
+ }
+ }
+}