import SwiftUI import FlixyDesign /// Wer angemeldet ist — unten in der Seitenleiste. /// /// Der Platz ist nicht zufällig: dort sucht man sein Konto, weil es auf jedem /// Schreibtisch und in jeder App der letzte Eintrag ist. Und von dort führt /// der Weg in die Einstellungen, statt dass sie als gleichrangiger Eintrag /// zwischen den Mediatheken stehen. /// /// Auf dem iPhone gibt es diese Leiste nicht — dort gehört das Konto in die /// Einstellungen selbst, und die haben ihren eigenen Eintrag. struct AccountBar: View { @Binding var selection: SidebarDestination @Environment(FlixySession.self) private var session @Environment(\.flixyAccent) private var accent @State private var showsSignOutConfirmation = false private var title: String { session.accountName ?? session.serverName } /// Der Server steht nur dann darunter, wenn oben schon der Kontoname /// steht — sonst stünde zweimal dasselbe. private var subtitle: String? { session.accountName == nil ? nil : session.serverName } var body: some View { Menu { Button("account.settings", systemImage: "gearshape") { selection = .settings } Divider() Button("action.signOut", systemImage: "rectangle.portrait.and.arrow.right", role: .destructive) { showsSignOutConfirmation = true } } label: { HStack(spacing: FlixySpacing.snug) { avatar VStack(alignment: .leading, spacing: 0) { Text(title) .font(.flixyCardTitle) .foregroundStyle(Color.flixyTextPrimary) .lineLimit(1) if let subtitle { Text(subtitle) .font(.flixyCaption) .foregroundStyle(Color.flixyTextMuted) .lineLimit(1) } } Spacer(minLength: FlixySpacing.snug) Image(systemName: "chevron.up.chevron.down") .font(.caption2) .foregroundStyle(Color.flixyTextMuted) } .padding(.vertical, FlixySpacing.tight) .contentShape(.rect) } .buttonStyle(.plain) .accessibilityLabel(Text(title)) .confirmationDialog( Text("settings.signOutConfirm"), isPresented: $showsSignOutConfirmation, titleVisibility: .visible ) { Button("action.signOut", role: .destructive) { session.signOut() } Button("action.cancel", role: .cancel) {} } message: { Text("settings.signOutExplanation") } } /// Der erste Buchstabe auf einer Scheibe. /// /// Jellyfin gibt kein Profilbild heraus, ohne dass eines hinterlegt ist, /// und Plex kennt den Kontonamen am Server gar nicht. Ein Buchstabe ist /// ehrlicher als ein graues Platzhalterbild. private var avatar: some View { Text(title.prefix(1).uppercased()) .font(.flixyCaption.weight(.semibold)) .foregroundStyle(Color.flixyCanvas) .frame(width: 26, height: 26) .background(accent, in: .circle) } }