aboutsummaryrefslogtreecommitdiff
path: root/Hotline/macOS/HotlinePanelView.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Hotline/macOS/HotlinePanelView.swift')
-rw-r--r--Hotline/macOS/HotlinePanelView.swift175
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())
}