summaryrefslogtreecommitdiff
path: root/Hutch/Models/Project.swift
blob: 2cd8e00ac5d11743c07d23945f9760e71e55a872 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import Foundation

struct Project: Identifiable, Hashable, Sendable {
    struct MailingList: Identifiable, Hashable, Sendable {
        let id: String
        let name: String
        let description: String?
        let visibility: Visibility
        let owner: Entity

        var ownerUsername: String {
            owner.canonicalName.srhtUsername
        }

        var inboxReference: InboxMailingListReference {
            InboxMailingListReference(
                id: 0,
                rid: id,
                name: name,
                owner: owner
            )
        }
    }

    struct SourceRepo: Identifiable, Hashable, Sendable {
        enum RepoType: String, Decodable, Sendable {
            case git = "GIT"
            case hg = "HG"

            var service: SRHTService {
                switch self {
                case .git: .git
                case .hg: .hg
                }
            }
        }

        let id: String
        let name: String
        let description: String?
        let visibility: Visibility
        let owner: Entity
        let repoType: RepoType

        var ownerUsername: String {
            owner.canonicalName.srhtUsername
        }
    }

    struct Tracker: Identifiable, Hashable, Sendable {
        let id: String
        let name: String
        let description: String?
        let visibility: Visibility
        let owner: Entity

        var ownerUsername: String {
            owner.canonicalName.srhtUsername
        }
    }

    let id: String
    let name: String
    let description: String?
    let website: String?
    let visibility: Visibility
    let tags: [String]
    let updated: Date
    let mailingLists: [MailingList]
    let sources: [SourceRepo]
    let trackers: [Tracker]

    var resourceSummary: String? {
        let parts = [
            Self.resourceCountText(count: sources.count, singular: "repo"),
            Self.resourceCountText(count: trackers.count, singular: "tracker"),
            Self.resourceCountText(count: mailingLists.count, singular: "list")
        ].compactMap { $0 }

        if !parts.isEmpty {
            return parts.joined(separator: " • ")
        }

        if let website, !website.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
            return "Website linked"
        }

        return nil
    }

    private static func resourceCountText(count: Int, singular: String) -> String? {
        guard count > 0 else { return nil }
        let label = count == 1 ? singular : "\(singular)s"
        return "\(count) \(label)"
    }
}

extension String {
    var srhtUsername: String {
        hasPrefix("~") ? String(dropFirst()) : self
    }
}