summaryrefslogtreecommitdiff
path: root/Hutch/Views/Lookup/UserProfileView.swift
blob: 4c91244a82ec01759f4e511770f0077c5b196921 (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 SwiftUI

struct UserProfileView: View {
    let user: User

    private static let iso8601Formatter: ISO8601DateFormatter = {
        let formatter = ISO8601DateFormatter()
        formatter.formatOptions = [.withInternetDateTime]
        formatter.timeZone = TimeZone(secondsFromGMT: 0)
        return formatter
    }()

    var body: some View {
        List {
            if let avatarURL = user.avatar.flatMap(URL.init(string:)) {
                Section {
                    HStack {
                        Spacer()
                        AsyncImage(url: avatarURL) { phase in
                            switch phase {
                            case .success(let image):
                                image
                                    .resizable()
                                    .scaledToFill()
                            case .failure, .empty:
                                Image(systemName: "person.crop.circle.fill")
                                    .resizable()
                                    .scaledToFit()
                                    .foregroundStyle(.secondary)
                                    .padding(20)
                            @unknown default:
                                EmptyView()
                            }
                        }
                        .frame(width: 96, height: 96)
                        .clipShape(Circle())
                        .overlay {
                            Circle()
                                .stroke(Color.secondary.opacity(0.2), lineWidth: 1)
                        }
                        Spacer()
                    }
                    .listRowBackground(Color.clear)
                }
            }

            Section {
                LabeledContent("Username", value: user.username)
                LabeledContent("Canonical Name", value: user.canonicalName)
                if let userType = user.userType {
                    LabeledContent("User Type", value: userType)
                }
                if let pronouns = user.pronouns {
                    LabeledContent("Pronouns", value: pronouns)
                }
                if let suspensionNotice = user.suspensionNotice {
                    LabeledContent("Suspension Notice", value: suspensionNotice)
                }
            }

            Section {
                LabeledContent("Email", value: user.email)
                if let urlString = user.url, let url = URL(string: urlString) {
                    LabeledContent("URL") {
                        Link(urlString, destination: url)
                    }
                }
                if let location = user.location {
                    LabeledContent("Location", value: location)
                }
            }

            if let bio = user.bio {
                Section("Bio") {
                    Text(bio)
                }
            }

            if user.created != nil || user.updated != nil {
                Section {
                    if let created = user.created {
                        LabeledContent("Joined", value: formattedTimestamp(created))
                    }
                    if let updated = user.updated {
                        LabeledContent("Updated", value: formattedTimestamp(updated))
                    }
                }
            }
        }
        .listStyle(.insetGrouped)
        .navigationTitle(user.canonicalName)
        .navigationBarTitleDisplayMode(.inline)
    }

    private func formattedTimestamp(_ value: String) -> String {
        guard let date = Self.iso8601Formatter.date(from: value) else {
            return value
        }

        return date.formatted(date: .abbreviated, time: .shortened)
    }
}