aboutsummaryrefslogtreecommitdiff
path: root/HoloBar/ContentView.swift
blob: 784f45e0971901acbb11a80132ecf76a06b25bbc (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
import SwiftUI

struct ContentView: View {
    @EnvironmentObject var fetcher: CharacterFetcher
    @State private var searchText: String = ""

    private var filteredCharacters: [Character] {
        if searchText.isEmpty { return fetcher.characters }

        return fetcher.characters.filter {
            $0.name.localizedCaseInsensitiveContains(searchText)
        }
    }

    var body: some View {
        NavigationView {
            List(filteredCharacters) { character in
                Button {
                    NSWorkspace.shared.open(character.profileURL)
                } label: {
                    HStack(spacing: 16) {
                        AsyncImage(url: character.avatarURL) { phase in
                            if let image = phase.image {
                                image
                                    .resizable()
                                    .aspectRatio(contentMode: .fill)
                            } else if phase.error != nil {
                                Image(systemName: "person.crop.circle.badge.exclamationmark")
                                    .resizable()
                                    .aspectRatio(contentMode: .fill)
                                    .foregroundStyle(.gray)
                            } else {
                                Image(systemName: "person.crop.circle")
                                    .resizable()
                                    .aspectRatio(contentMode: .fill)
                                    .foregroundStyle(.gray)
                                    .opacity(0.25)
                            }
                        }
                        .frame(width: 40, height: 40)
                        .clipShape(Circle())
                        .overlay(
                            Circle().stroke(Color.secondary.opacity(0.3), lineWidth: 1)
                        )

                        VStack(alignment: .leading, spacing: 4) {
                            Text(character.rawName).font(.headline)

                            Text(character.affiliation)
                                .font(.subheadline)
                                .foregroundColor(.secondary)
                        }
                    }
                    .padding(.vertical, 8)
                }
                .buttonStyle(PlainButtonStyle())
            }
            .navigationTitle("Characters")
            .searchable(text: $searchText, placement: .automatic, prompt: "Search Characters")
            .toolbar {
                ToolbarItem {
                    Button(action: fetcher.refreshCharactersForToday) {
                        Image(systemName: "arrow.clockwise")
                    }
                    .help("Refresh Characters")
                }
            }
        }
    }
}