Atoll/DynamicIsland/components/Notch/DynamicIslandHeader.swift
2025-07-17 22:47:04 +05:30

154 lines
6.5 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: {
if webcamManager.isSessionRunning {
webcamManager.stopSession()
} else {
webcamManager.startSession()
}
}) {
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: {
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)
.onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("ToggleClipboardPopover"))) { _ in
// Only toggle if clipboard is enabled
if Defaults[.enableClipboardManager] {
showClipboardPopover.toggle()
}
}
}
}
#Preview {
DynamicIslandHeader()
.environmentObject(DynamicIslandViewModel())
.environmentObject(WebcamManager.shared)
}