gitbay/Issues/Reaction.swift

v1.12.0
gitbay-ios/gitbay/Issues/Reaction.swift history · blame · raw

56 lines · 2266 bytes

 1import Foundation
 2
 3/// One reaction on an issue, a merge request, or one of their comments,
 4/// as `issue show` and `mr show` carry it.
 5nonisolated struct ReactionCount: Decodable, Sendable, Hashable, Identifiable {
 6    let reaction: String
 7    let count: Int
 8    /// The signed-in account gave this one.
 9    let me: Bool
10
11    var id: String { reaction }
12}
13
14/// The reaction vocabulary, named as the server stores it. The order is
15/// the server's display order, so the picker reads the way the web's does.
16nonisolated struct Reaction: Sendable, Hashable, Identifiable {
17    let name: String
18    let emoji: String
19
20    var id: String { name }
21
22    /// What VoiceOver says; "+1" would be read as "plus one".
23    let spoken: String
24
25    static let all: [Reaction] = [
26        .init(name: "+1", emoji: "👍", spoken: "thumbs up"), .init(name: "-1", emoji: "👎", spoken: "thumbs down"),
27        .init(name: "laugh", emoji: "😄", spoken: "laugh"), .init(name: "hooray", emoji: "🎉", spoken: "hooray"),
28        .init(name: "confused", emoji: "😕", spoken: "confused"), .init(name: "heart", emoji: "❤️", spoken: "heart"),
29        .init(name: "rocket", emoji: "🚀", spoken: "rocket"), .init(name: "eyes", emoji: "👀", spoken: "eyes"),
30    ]
31
32    /// A name a newer server added draws as its name rather than vanishing.
33    static func emoji(for name: String) -> String {
34        all.first { $0.name == name }?.emoji ?? name
35    }
36
37    static func spoken(for name: String) -> String {
38        all.first { $0.name == name }?.spoken ?? name
39    }
40
41    /// Picking a reaction the account already gave takes it back, the way
42    /// the web's toggle does.
43    static func remove(_ name: String, given: [ReactionCount]?) -> Bool {
44        given?.contains { $0.reaction == name && $0.me } ?? false
45    }
46
47    /// `issue react` / `mr react <owner/name> <n> [--comment <id>] <reaction> [--remove]`.
48    static func argv(noun: String, repo: String, number: Int64, comment: Int64?,
49                     name: String, remove: Bool) -> [String] {
50        var argv = [noun, "react", repo, String(number)]
51        if let comment { argv += ["--comment", String(comment)] }
52        argv.append(name)
53        if remove { argv.append("--remove") }
54        return argv
55    }
56}