diff options
| author | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-11-27 23:38:04 +0100 |
|---|---|---|
| committer | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-11-27 23:38:04 +0100 |
| commit | 213710bf5bd6413c747bf126db50816ef5de5a6e (patch) | |
| tree | 912f8cf87955a08077c92fea8ad934f50b7ab975 /Hotline/macOS/HotlinePanelView.swift | |
| parent | f466b21dc02f78c984ba6748e703f6780a7a0db4 (diff) | |
| parent | 6a95b53616a4abfa306ddce43151cf4fefbd20ed (diff) | |
Merge remote-tracking branch 'upstream/main'
Diffstat (limited to 'Hotline/macOS/HotlinePanelView.swift')
| -rw-r--r-- | Hotline/macOS/HotlinePanelView.swift | 175 |
1 files changed, 126 insertions, 49 deletions
diff --git a/Hotline/macOS/HotlinePanelView.swift b/Hotline/macOS/HotlinePanelView.swift index 2617bc8..aec00df 100644 --- a/Hotline/macOS/HotlinePanelView.swift +++ b/Hotline/macOS/HotlinePanelView.swift @@ -1,23 +1,44 @@ import SwiftUI +import Kingfisher struct HotlinePanelView: View { @Environment(\.openWindow) var openWindow @Environment(\.colorScheme) var colorScheme + @Environment(\.appState) private var appState + + private var activeServerState: ServerState? { + self.appState.activeServerState + } + + private var activeHotline: HotlineState? { + self.appState.activeHotline + } + + private var bannerImage: Image { + self.activeHotline?.bannerImage ?? Image("Default Banner") + } + + private var backgroundColor: Color { + Color(nsColor: self.activeHotline?.bannerColors?.backgroundColor ?? NSColor.controlBackgroundColor) + } + + private var bannerFileURL: URL? { + self.activeHotline?.bannerFileURL + } + + private var bannerIsAnimated: Bool { + self.activeHotline?.bannerImageFormat == .gif + } var body: some View { VStack(spacing: 0) { - Image( - nsImage: ApplicationState.shared.activeServerBanner ?? NSImage(named: "Default Banner")! - ) - .interpolation(.high) - .resizable() - .scaledToFill() - .frame(width: 468, height: 60) - .frame(minWidth: 468, maxWidth: 468, minHeight: 60, maxHeight: 60) - .clipped() - .background(.black) - // .clipShape(RoundedRectangle(cornerRadius: 6.0)) - // .padding([.top, .leading, .trailing], 4) + + self.bannerView + .id("banner image view") + .animation(.default, value: self.bannerFileURL) + .background { + Color.black + } HStack(spacing: 12) { Button { @@ -36,71 +57,86 @@ struct HotlinePanelView: View { .help("Hotline Servers") Button { - ApplicationState.shared.activeServerState?.selection = .chat - } label: { + self.activeServerState?.selection = .chat + } + label: { Image("Section Chat") .resizable() .scaledToFit() } .buttonStyle(.plain) .frame(width: 20, height: 20) - .disabled(ApplicationState.shared.activeServerState == nil) + .disabled(self.activeServerState == nil) .help("Public Chat") Button { - ApplicationState.shared.activeServerState?.selection = .board - } label: { + self.activeServerState?.selection = .board + } + label: { Image("Section Board") .resizable() .scaledToFit() } .buttonStyle(.plain) .frame(width: 20, height: 20) - .disabled(ApplicationState.shared.activeServerState == nil) + .disabled(self.activeServerState == nil) .help("Message Board") Button { - ApplicationState.shared.activeServerState?.selection = .news - } label: { + self.activeServerState?.selection = .news + } + label: { Image("Section News") .resizable() .scaledToFit() } .buttonStyle(.plain) .frame(width: 20, height: 20) - .disabled( - ApplicationState.shared.activeServerState == nil - || (ApplicationState.shared.activeHotline?.serverVersion ?? 0) < 151 - ) + .disabled(self.activeServerState == nil || (self.activeHotline?.serverVersion ?? 0) < 151) .help("News") Button { - ApplicationState.shared.activeServerState?.selection = .files - } label: { + self.activeServerState?.selection = .files + } + label: { Image("Section Files") .resizable() .scaledToFit() } .buttonStyle(.plain) .frame(width: 20, height: 20) - .disabled(ApplicationState.shared.activeServerState == nil) + .disabled(self.activeServerState == nil) .help("Files") Spacer() - if ApplicationState.shared.activeHotline?.access?.contains(.canOpenUsers) == true { + if self.activeHotline?.access?.contains(.canOpenUsers) == true { Button { - ApplicationState.shared.activeServerState?.selection = .accounts - } label: { +// self.activeServerState?.selection = .accounts + self.activeServerState?.accountsShown = true + } + label: { Image("Section Users") .resizable() .scaledToFit() } .buttonStyle(.plain) .frame(width: 20, height: 20) - .disabled(ApplicationState.shared.activeServerState == nil) - .help("Accounts") + .disabled(self.activeServerState == nil) + .help("Manage Accounts") + } + + Button { + self.openWindow(id: "transfers") } + label: { + Image("Section Transfers") + .resizable() + .scaledToFit() + } + .buttonStyle(.plain) + .frame(width: 20, height: 20) + .help("File Transfers") SettingsLink(label: { Image("Section Settings") @@ -114,22 +150,24 @@ struct HotlinePanelView: View { .padding(.top, 12) .padding(.bottom, 12) .padding([.leading, .trailing], 12) - // .background(Color.red.opacity(0.5).blendMode(.multiply)) - - // GroupBox { - // HStack(spacing: 0) { - // Text("Not Connected") - // .font(.system(size: 10.0)) - // .lineLimit(1) - // .truncationMode(.tail) - // .opacity(0.5) - // .padding(.vertical, 0.0) - // .padding(.horizontal, 4.0) - // - // Spacer() - // } - // } - // .padding([.leading, .bottom, .trailing], 4.0) + .background(self.backgroundColor) + .foregroundStyle(.primary) + .animation(.default, value: self.backgroundColor) + +// GroupBox { +// HStack(spacing: 0) { +// Text("Not Connected") +// .font(.system(size: 10.0)) +// .lineLimit(1) +// .truncationMode(.tail) +// .opacity(0.5) +// .padding(.vertical, 0.0) +// .padding(.horizontal, 4.0) +// +// Spacer() +// } +// } +// .padding([.leading, .bottom, .trailing], 4.0) } // .frame(width: 468) // .background(colorScheme == .dark ? .black : .white) @@ -138,9 +176,48 @@ struct HotlinePanelView: View { // .cornerRadius(10.0) // ) } + + private var bannerView: some View { + ZStack { + if self.bannerIsAnimated { + KFAnimatedImage + .url(self.bannerFileURL) + .placeholder { + Image("Default Banner") + } + .cacheMemoryOnly() + .cacheOriginalImage() + .scaledToFill() + .frame(width: 468, height: 60) + .frame(minWidth: 468, maxWidth: 468, minHeight: 60, maxHeight: 60) + .clipped() + .transition(.opacity) + .id("animated banner \(self.bannerFileURL?.absoluteString ?? "")") + } + else { + KFImage + .url(self.bannerFileURL) + .resizable() + .interpolation(.high) + .placeholder { + Image("Default Banner") + } + .cacheMemoryOnly() + .cacheOriginalImage() + .scaledToFill() + .frame(width: 468, height: 60) + .frame(minWidth: 468, maxWidth: 468, minHeight: 60, maxHeight: 60) + .clipped() + .transition(.opacity) + .id("static banner \(self.bannerFileURL?.absoluteString ?? "")") + } + } + .animation(.default, value: self.bannerIsAnimated) + .animation(.default, value: self.bannerFileURL) + } } #Preview { HotlinePanelView() - .environment(Hotline(trackerClient: HotlineTrackerClient(), client: HotlineClient())) + .environment(HotlineState()) } |