gitbay/Discovery/ProfileEdit.swift

v1.9.0
gitbay-ios/gitbay/Discovery/ProfileEdit.swift history · blame · raw

64 lines · 2430 bytes

 1import Foundation
 2
 3/// `profile set` — unlike every other filter or edit in the app, `--link`
 4/// replaces the whole set rather than appending, so every link the form
 5/// wants to keep is sent on every save. The form is always seeded from
 6/// the current profile, so every other field is also sent every time,
 7/// including empty ones: `--description ""` clears, omitting the flag
 8/// would leave the old value alone.
 9///
10/// The about text is not here. It is a file in `<owner>/.gitbay`, written
11/// through the file editor like any other file.
12nonisolated struct ProfileEdit: Equatable, Sendable {
13
14    nonisolated struct Link: Equatable, Sendable, Identifiable {
15        var id = UUID()
16        var label: String
17        var url: String
18    }
19
20    var description: String
21    var website: String
22    var links: [Link]
23
24    init(description: String = "", website: String = "", links: [Link] = []) {
25        self.description = description
26        self.website = website
27        self.links = links
28    }
29
30    init(from profile: ProfileViewModel.Profile) {
31        description = profile.description ?? ""
32        website = profile.website ?? ""
33        links = (profile.links ?? []).map { Link(label: $0.label ?? "", url: $0.url) }
34    }
35
36    /// At most 5 links and every link needs a URL — the server enforces
37    /// both, but the form should not let a save reach it that way. A
38    /// label may not contain `|` either: the server splits a link on its
39    /// first pipe, so a label carrying one would silently corrupt the URL
40    /// rather than be rejected.
41    var validationError: String? {
42        if links.count > 5 { return "At most 5 links." }
43        if links.contains(where: { $0.url.trimmingCharacters(in: .whitespaces).isEmpty }) {
44            return "A link needs a URL."
45        }
46        if links.contains(where: { $0.label.contains("|") }) {
47            return "A link label can't contain \"|\" — that's what separates it from the URL."
48        }
49        return nil
50    }
51
52    func flags() -> [String] {
53        var flags = ["--description", description, "--website", website]
54        if links.isEmpty {
55            flags += ["--link", ""]
56        } else {
57            for link in links {
58                let label = link.label.trimmingCharacters(in: .whitespaces)
59                flags += ["--link", label.isEmpty ? link.url : "\(label)|\(link.url)"]
60            }
61        }
62        return flags
63    }
64}