mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
168 lines
7.2 KiB
Swift
168 lines
7.2 KiB
Swift
//
|
|
// DynamicIslandHeader.swift
|
|
// DynamicIsland
|
|
//
|
|
// Created by Harsh Vardhan Goswami on 04/08/24.
|
|
//
|
|
|
|
import Defaults
|
|
import SwiftUI
|
|
|
|
struct DynamicIslandHeader: View {
|
|
@EnvironmentObject var vm: DynamicIslandViewModel
|
|
@EnvironmentObject var webcamManager: WebcamManager
|
|
@ObservedObject var batteryModel = BatteryStatusViewModel.shared
|
|
@ObservedObject var coordinator = DynamicIslandViewCoordinator.shared
|
|
@ObservedObject var clipboardManager = ClipboardManager.shared
|
|
@StateObject var tvm = TrayDrop.shared
|
|
@State private var showClipboardPopover = false
|
|
|
|
var body: some View {
|
|
HStack(spacing: 0) {
|
|
HStack {
|
|
if (!tvm.isEmpty || coordinator.alwaysShowTabs) && Defaults[.dynamicShelf] {
|
|
TabSelectionView()
|
|
} else if vm.notchState == .open {
|
|
EmptyView()
|
|
}
|
|
}
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
.opacity(vm.notchState == .closed ? 0 : 1)
|
|
.blur(radius: vm.notchState == .closed ? 20 : 0)
|
|
.animation(.smooth.delay(0.1), value: vm.notchState)
|
|
.zIndex(2)
|
|
|
|
if vm.notchState == .open {
|
|
Rectangle()
|
|
.fill(NSScreen.screens
|
|
.first(where: { $0.localizedName == coordinator.selectedScreen })?.safeAreaInsets.top ?? 0 > 0 ? .black : .clear)
|
|
.frame(width: vm.closedNotchSize.width)
|
|
.mask {
|
|
NotchShape()
|
|
}
|
|
}
|
|
|
|
HStack(spacing: 4) {
|
|
if vm.notchState == .open {
|
|
if Defaults[.showMirror] {
|
|
Button(action: {
|
|
vm.toggleCameraPreview()
|
|
}) {
|
|
Capsule()
|
|
.fill(.black)
|
|
.frame(width: 30, height: 30)
|
|
.overlay {
|
|
Image(systemName: "web.camera")
|
|
.foregroundColor(.white)
|
|
.padding()
|
|
.imageScale(.medium)
|
|
}
|
|
}
|
|
.buttonStyle(PlainButtonStyle())
|
|
}
|
|
|
|
if Defaults[.enableClipboardManager] && Defaults[.showClipboardIcon] {
|
|
Button(action: {
|
|
// Use the same smart logic as the keyboard shortcut
|
|
let displayMode = Defaults[.clipboardDisplayMode]
|
|
let shouldUseWindow: Bool
|
|
|
|
switch displayMode {
|
|
case .window:
|
|
shouldUseWindow = true
|
|
case .popover:
|
|
shouldUseWindow = false
|
|
case .auto:
|
|
// For header button clicks, prefer popover since user is already interacting with notch
|
|
shouldUseWindow = false
|
|
}
|
|
|
|
if shouldUseWindow {
|
|
ClipboardWindowManager.shared.toggleClipboardWindow()
|
|
} else {
|
|
showClipboardPopover.toggle()
|
|
}
|
|
}) {
|
|
Capsule()
|
|
.fill(.black)
|
|
.frame(width: 30, height: 30)
|
|
.overlay {
|
|
Image(systemName: "doc.on.clipboard")
|
|
.foregroundColor(.white)
|
|
.padding()
|
|
.imageScale(.medium)
|
|
}
|
|
}
|
|
.buttonStyle(PlainButtonStyle())
|
|
.popover(isPresented: $showClipboardPopover, arrowEdge: .bottom) {
|
|
ClipboardHistoryPopover(isPresented: $showClipboardPopover)
|
|
.onAppear {
|
|
vm.isClipboardPopoverActive = true
|
|
}
|
|
.onDisappear {
|
|
vm.isClipboardPopoverActive = false
|
|
}
|
|
}
|
|
.onChange(of: showClipboardPopover) { isOpen in
|
|
vm.isClipboardPopoverActive = isOpen
|
|
}
|
|
.onAppear {
|
|
if Defaults[.enableClipboardManager] && !clipboardManager.isMonitoring {
|
|
clipboardManager.startMonitoring()
|
|
}
|
|
}
|
|
}
|
|
|
|
if Defaults[.settingsIconInNotch] {
|
|
Button(action: {
|
|
SettingsWindowController.shared.showWindow()
|
|
}) {
|
|
Capsule()
|
|
.fill(.black)
|
|
.frame(width: 30, height: 30)
|
|
.overlay {
|
|
Image(systemName: "gear")
|
|
.foregroundColor(.white)
|
|
.padding()
|
|
.imageScale(.medium)
|
|
}
|
|
}
|
|
.buttonStyle(PlainButtonStyle())
|
|
}
|
|
if Defaults[.showBatteryIndicator] {
|
|
DynamicIslandBatteryView(
|
|
batteryWidth: 30,
|
|
isCharging: batteryModel.isCharging,
|
|
isInLowPowerMode: batteryModel.isInLowPowerMode,
|
|
isPluggedIn: batteryModel.isPluggedIn,
|
|
levelBattery: batteryModel.levelBattery,
|
|
maxCapacity: batteryModel.maxCapacity,
|
|
timeToFullCharge: batteryModel.timeToFullCharge,
|
|
isForNotification: false
|
|
)
|
|
}
|
|
}
|
|
}
|
|
.font(.system(.headline, design: .rounded))
|
|
.frame(maxWidth: .infinity, alignment: .trailing)
|
|
.opacity(vm.notchState == .closed ? 0 : 1)
|
|
.blur(radius: vm.notchState == .closed ? 20 : 0)
|
|
.animation(.smooth.delay(0.1), value: vm.notchState)
|
|
.zIndex(2)
|
|
}
|
|
.foregroundColor(.gray)
|
|
.environmentObject(vm)
|
|
.onChange(of: coordinator.shouldToggleClipboardPopover) { _ in
|
|
// Only toggle if clipboard is enabled
|
|
if Defaults[.enableClipboardManager] {
|
|
showClipboardPopover.toggle()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
DynamicIslandHeader()
|
|
.environmentObject(DynamicIslandViewModel())
|
|
.environmentObject(WebcamManager.shared)
|
|
}
|