aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HoloBar/CharacterFetcher.swift9
-rw-r--r--HoloBar/ContentView.swift70
-rw-r--r--HoloBar/HoloBarApp.swift29
3 files changed, 97 insertions, 11 deletions
diff --git a/HoloBar/CharacterFetcher.swift b/HoloBar/CharacterFetcher.swift
index 7ba6854..c9d5a9b 100644
--- a/HoloBar/CharacterFetcher.swift
+++ b/HoloBar/CharacterFetcher.swift
@@ -122,4 +122,13 @@ class CharacterFetcher: ObservableObject {
self.characters = updatedCharacters
}
}
+
+ func refreshCharactersForToday() {
+ let today = Calendar.current.dateComponents([.month, .day], from: Date())
+
+ if let month = today.month, let day = today.day {
+ characters.removeAll()
+ fetchCharacters(for: month, day: day)
+ }
+ }
}
diff --git a/HoloBar/ContentView.swift b/HoloBar/ContentView.swift
new file mode 100644
index 0000000..784f45e
--- /dev/null
+++ b/HoloBar/ContentView.swift
@@ -0,0 +1,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")
+ }
+ }
+ }
+ }
+}
diff --git a/HoloBar/HoloBarApp.swift b/HoloBar/HoloBarApp.swift
index eac0acd..3fadf0c 100644
--- a/HoloBar/HoloBarApp.swift
+++ b/HoloBar/HoloBarApp.swift
@@ -1,11 +1,17 @@
import SwiftUI
+#Preview { ContentView().environmentObject(CharacterFetcher()) }
+
@main
struct HoloBarApp: App {
@StateObject private var fetcher = CharacterFetcher()
@State private var showAvatars = false
var body: some Scene {
+ Window("HoloBar", id: "main") {
+ ContentView().environmentObject(fetcher)
+ }
+
MenuBarExtra {
VStack {
if fetcher.characters.isEmpty {
@@ -50,27 +56,28 @@ struct HoloBarApp: App {
}
#endif
+ Button("Show UI") {
+ for window in NSApp.windows {
+ if window.identifier?.rawValue == "main" {
+ window.makeKeyAndOrderFront(nil)
+
+ return
+ }
+ }
+ }
+
Button("\(showAvatars ? "Hide" : "Show") Avatars") {
showAvatars.toggle()
}
- Button("Refresh", action: refreshCharacters)
+ Button("Refresh", action: fetcher.refreshCharactersForToday)
Button("Quit", action: { NSApplication.shared.terminate(nil) })
}
.onReceive(NotificationCenter.default.publisher(for: .NSCalendarDayChanged)) { _ in
- refreshCharacters()
+ fetcher.refreshCharactersForToday()
}
} label: {
Text("HL")
}
}
-
- private func refreshCharacters() {
- let today = Calendar.current.dateComponents([.month, .day], from: Date())
-
- if let month = today.month, let day = today.day {
- fetcher.characters.removeAll()
- fetcher.fetchCharacters(for: month, day: day)
- }
- }
}