summaryrefslogtreecommitdiff
path: root/Hutch/Models/Project.swift
blob: 54c031828e8a932ae60d5373bcef92a0c8505782 (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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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]
    let isFullyLoaded: Bool

    init(
        id: String,
        name: String,
        description: String?,
        website: String?,
        visibility: Visibility,
        tags: [String],
        updated: Date,
        mailingLists: [MailingList],
        sources: [SourceRepo],
        trackers: [Tracker],
        isFullyLoaded: Bool = true
    ) {
        self.id = id
        self.name = name
        self.description = description
        self.website = website
        self.visibility = visibility
        self.tags = tags
        self.updated = updated
        self.mailingLists = mailingLists
        self.sources = sources
        self.trackers = trackers
        self.isFullyLoaded = isFullyLoaded
    }

    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
    }
}