mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
Fix: Caps Lock View
This commit is contained in:
parent
5822d9a232
commit
168dc27af5
6 changed files with 100 additions and 38 deletions
|
|
@ -485,10 +485,14 @@ struct ContentView: View {
|
|||
.frame(height: vm.effectiveClosedNotchHeight + (isHovering ? 8 : 0), alignment: .center)
|
||||
} else if coordinator.sneakPeek.show && Defaults[.inlineHUD] && (coordinator.sneakPeek.type != .music) && (coordinator.sneakPeek.type != .battery) && (coordinator.sneakPeek.type != .timer) && (coordinator.sneakPeek.type != .reminder) && (coordinator.sneakPeek.type != .volume || vm.notchState == .closed) {
|
||||
InlineHUD(type: $coordinator.sneakPeek.type, value: $coordinator.sneakPeek.value, icon: $coordinator.sneakPeek.icon, hoverAnimation: $isHovering, gestureProgress: $gestureProgress)
|
||||
.transition(.opacity)
|
||||
.transition(
|
||||
coordinator.sneakPeek.type == .capsLock
|
||||
? .move(edge: .trailing).combined(with: .opacity)
|
||||
: .opacity
|
||||
)
|
||||
} else if vm.notchState == .closed && capsLockManager.isCapsLockActive && Defaults[.enableCapsLockIndicator] && !vm.hideOnClosed && !lockScreenManager.isLocked {
|
||||
InlineHUD(type: .constant(.capsLock), value: .constant(1.0), icon: .constant(""), hoverAnimation: $isHovering, gestureProgress: $gestureProgress)
|
||||
.transition(.opacity)
|
||||
.transition(.move(edge: .trailing).combined(with: .opacity))
|
||||
} else if (!coordinator.expandingView.show || coordinator.expandingView.type == .music) && vm.notchState == .closed && (musicManager.isPlaying || !musicManager.isPlayerIdle) && coordinator.musicLiveActivityEnabled && !vm.hideOnClosed && !lockScreenManager.isLocked {
|
||||
MusicLiveActivity()
|
||||
} else if (!coordinator.expandingView.show || coordinator.expandingView.type == .timer) && vm.notchState == .closed && timerManager.isTimerActive && coordinator.timerLiveActivityEnabled && !vm.hideOnClosed {
|
||||
|
|
|
|||
|
|
@ -2362,6 +2362,9 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Adds a notch HUD when Caps Lock is enabled, with optional label and tint controls." : {
|
||||
|
||||
},
|
||||
"Adds the AirPlay/route picker button back to the customizable controls palette." : {
|
||||
|
||||
|
|
@ -4625,6 +4628,9 @@
|
|||
},
|
||||
"Caps Lock" : {
|
||||
|
||||
},
|
||||
"Caps Lock Indicator" : {
|
||||
|
||||
},
|
||||
"Center" : {
|
||||
"extractionState" : "stale",
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ struct InlineHUD: View {
|
|||
@Default(.showBluetoothBatteryPercentageText) var showBluetoothBatteryPercentageText
|
||||
@Default(.showBluetoothDeviceNameMarquee) var showBluetoothDeviceNameMarquee
|
||||
@Default(.enableMinimalisticUI) var enableMinimalisticUI
|
||||
@Default(.showCapsLockLabel) var showCapsLockLabel
|
||||
@ObservedObject var bluetoothManager = BluetoothAudioManager.shared
|
||||
|
||||
@State private var displayName: String = ""
|
||||
|
|
@ -32,55 +33,87 @@ struct InlineHUD: View {
|
|||
var body: some View {
|
||||
let useCircularIndicator = useCircularBluetoothBatteryIndicator
|
||||
let hasBatteryLevel = value > 0
|
||||
let capsLockAccentColor: Color = Defaults[.capsLockIndicatorUseGreenColor] ? .green : .white
|
||||
|
||||
let baseInfoWidth: CGFloat = {
|
||||
guard type == .bluetoothAudio else { return 100 }
|
||||
if showBluetoothDeviceNameMarquee {
|
||||
return enableMinimalisticUI ? 128 : 140
|
||||
if type == .bluetoothAudio {
|
||||
if showBluetoothDeviceNameMarquee {
|
||||
return enableMinimalisticUI ? 128 : 140
|
||||
}
|
||||
return enableMinimalisticUI ? 64 : 72
|
||||
}
|
||||
return enableMinimalisticUI ? 64 : 72
|
||||
|
||||
if type == .capsLock && !showCapsLockLabel {
|
||||
return enableMinimalisticUI ? 56 : 64
|
||||
}
|
||||
|
||||
return 100
|
||||
}()
|
||||
|
||||
let infoWidth: CGFloat = {
|
||||
var width = baseInfoWidth + gestureProgress / 2
|
||||
if !hoverAnimation { width -= 8 }
|
||||
let minimum: CGFloat = {
|
||||
guard type == .bluetoothAudio else { return 88 }
|
||||
if showBluetoothDeviceNameMarquee {
|
||||
return enableMinimalisticUI ? 112 : 120
|
||||
if type == .bluetoothAudio {
|
||||
if showBluetoothDeviceNameMarquee {
|
||||
return enableMinimalisticUI ? 112 : 120
|
||||
}
|
||||
return enableMinimalisticUI ? 56 : 68
|
||||
}
|
||||
return enableMinimalisticUI ? 56 : 68
|
||||
|
||||
if type == .capsLock && !showCapsLockLabel {
|
||||
return enableMinimalisticUI ? 44 : 52
|
||||
}
|
||||
|
||||
return 88
|
||||
}()
|
||||
return max(width, minimum)
|
||||
}()
|
||||
|
||||
let baseTrailingWidth: CGFloat = {
|
||||
guard type == .bluetoothAudio else { return 100 }
|
||||
if !hasBatteryLevel {
|
||||
return showBluetoothDeviceNameMarquee ? (enableMinimalisticUI ? 104 : 118) : (enableMinimalisticUI ? 74 : 88)
|
||||
if type == .bluetoothAudio {
|
||||
if !hasBatteryLevel {
|
||||
return showBluetoothDeviceNameMarquee ? (enableMinimalisticUI ? 104 : 118) : (enableMinimalisticUI ? 74 : 88)
|
||||
}
|
||||
|
||||
if useCircularIndicator {
|
||||
return showBluetoothBatteryPercentageText ? (enableMinimalisticUI ? 108 : 120) : (enableMinimalisticUI ? 72 : 84)
|
||||
}
|
||||
|
||||
return showBluetoothBatteryPercentageText ? (enableMinimalisticUI ? 118 : 136) : (enableMinimalisticUI ? 92 : 108)
|
||||
}
|
||||
|
||||
if useCircularIndicator {
|
||||
return showBluetoothBatteryPercentageText ? (enableMinimalisticUI ? 108 : 120) : (enableMinimalisticUI ? 72 : 84)
|
||||
if type == .capsLock {
|
||||
if showCapsLockLabel {
|
||||
return enableMinimalisticUI ? 84 : 96
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
return showBluetoothBatteryPercentageText ? (enableMinimalisticUI ? 118 : 136) : (enableMinimalisticUI ? 92 : 108)
|
||||
return 100
|
||||
}()
|
||||
|
||||
let trailingWidth: CGFloat = {
|
||||
var width = baseTrailingWidth + gestureProgress / 2
|
||||
if !hoverAnimation { width -= 8 }
|
||||
let minimum: CGFloat = {
|
||||
guard type == .bluetoothAudio else { return 90 }
|
||||
if !hasBatteryLevel {
|
||||
return showBluetoothDeviceNameMarquee ? (enableMinimalisticUI ? 96 : 110) : (enableMinimalisticUI ? 62 : 88)
|
||||
if type == .bluetoothAudio {
|
||||
if !hasBatteryLevel {
|
||||
return showBluetoothDeviceNameMarquee ? (enableMinimalisticUI ? 96 : 110) : (enableMinimalisticUI ? 62 : 88)
|
||||
}
|
||||
|
||||
if useCircularIndicator {
|
||||
return showBluetoothBatteryPercentageText ? (enableMinimalisticUI ? 92 : 110) : (enableMinimalisticUI ? 56 : 72)
|
||||
}
|
||||
|
||||
return showBluetoothBatteryPercentageText ? (enableMinimalisticUI ? 104 : 120) : (enableMinimalisticUI ? 72 : 90)
|
||||
}
|
||||
|
||||
if useCircularIndicator {
|
||||
return showBluetoothBatteryPercentageText ? (enableMinimalisticUI ? 92 : 110) : (enableMinimalisticUI ? 56 : 72)
|
||||
if type == .capsLock {
|
||||
return showCapsLockLabel ? (enableMinimalisticUI ? 68 : 80) : 0
|
||||
}
|
||||
|
||||
return showBluetoothBatteryPercentageText ? (enableMinimalisticUI ? 104 : 120) : (enableMinimalisticUI ? 72 : 90)
|
||||
return 90
|
||||
}()
|
||||
return max(width, minimum)
|
||||
}()
|
||||
|
|
@ -133,7 +166,7 @@ struct InlineHUD: View {
|
|||
.symbolRenderingMode(.hierarchical)
|
||||
.contentTransition(.interpolate)
|
||||
.frame(width: 20, height: 15, alignment: .center)
|
||||
.foregroundStyle(Defaults[.capsLockIndicatorUseGreenColor] ? .green : .white)
|
||||
.foregroundStyle(capsLockAccentColor)
|
||||
default:
|
||||
EmptyView()
|
||||
}
|
||||
|
|
@ -187,15 +220,17 @@ struct InlineHUD: View {
|
|||
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
.contentTransition(.interpolate)
|
||||
} else if (type == .capsLock) {
|
||||
Text("Caps Lock")
|
||||
.foregroundStyle(Defaults[.capsLockIndicatorUseGreenColor] ? .green : .white)
|
||||
.font(.subheadline)
|
||||
.fontWeight(.medium)
|
||||
.lineLimit(1)
|
||||
.allowsTightening(true)
|
||||
.multilineTextAlignment(.trailing)
|
||||
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
.contentTransition(.interpolate)
|
||||
if showCapsLockLabel {
|
||||
Text("Caps Lock")
|
||||
.foregroundStyle(capsLockAccentColor)
|
||||
.font(.subheadline)
|
||||
.fontWeight(.medium)
|
||||
.lineLimit(1)
|
||||
.allowsTightening(true)
|
||||
.multilineTextAlignment(.trailing)
|
||||
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
.contentTransition(.interpolate)
|
||||
}
|
||||
} else if (type == .bluetoothAudio) {
|
||||
if hasBatteryLevel {
|
||||
let indicatorSpacing: CGFloat = {
|
||||
|
|
|
|||
|
|
@ -1735,11 +1735,6 @@ private struct DevicesSettingsView: View {
|
|||
Section {
|
||||
Defaults.Toggle("Show Bluetooth device connections", key: .showBluetoothDeviceConnections)
|
||||
.settingsHighlight(id: highlightID("Show Bluetooth device connections"))
|
||||
Defaults.Toggle("Show Caps Lock Indicator", key: .enableCapsLockIndicator)
|
||||
.settingsHighlight(id: highlightID("Show Caps Lock Indicator"))
|
||||
Defaults.Toggle("Use green color for Caps Lock text", key: .capsLockIndicatorUseGreenColor)
|
||||
.disabled(!Defaults[.enableCapsLockIndicator])
|
||||
.settingsHighlight(id: highlightID("Use green color for Caps Lock text"))
|
||||
Defaults.Toggle("Use circular battery indicator", key: .useCircularBluetoothBatteryIndicator)
|
||||
.settingsHighlight(id: highlightID("Use circular battery indicator"))
|
||||
Defaults.Toggle("Show battery percentage text in HUD", key: .showBluetoothBatteryPercentageText)
|
||||
|
|
@ -2644,6 +2639,23 @@ struct LiveActivitiesSettings: View {
|
|||
Text("Listens for Focus session changes via distributed notifications")
|
||||
}
|
||||
|
||||
Section {
|
||||
Defaults.Toggle("Show Caps Lock Indicator", key: .enableCapsLockIndicator)
|
||||
.settingsHighlight(id: highlightID("Show Caps Lock Indicator"))
|
||||
|
||||
Defaults.Toggle("Show Caps Lock label", key: .showCapsLockLabel)
|
||||
.disabled(!Defaults[.enableCapsLockIndicator])
|
||||
.settingsHighlight(id: highlightID("Show Caps Lock label"))
|
||||
|
||||
Defaults.Toggle("Use green color for Caps Lock text", key: .capsLockIndicatorUseGreenColor)
|
||||
.disabled(!Defaults[.enableCapsLockIndicator])
|
||||
.settingsHighlight(id: highlightID("Use green color for Caps Lock text"))
|
||||
} header: {
|
||||
Text("Caps Lock Indicator")
|
||||
} footer: {
|
||||
Text("Adds a notch HUD when Caps Lock is enabled, with optional label and tint controls.")
|
||||
}
|
||||
|
||||
Section {
|
||||
Defaults.Toggle("Enable Camera Detection", key: .enableCameraDetection)
|
||||
.settingsHighlight(id: highlightID("Enable Camera Detection"))
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import Foundation
|
|||
import Combine
|
||||
import AppKit
|
||||
import Defaults
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
class CapsLockManager: ObservableObject {
|
||||
|
|
@ -20,6 +21,7 @@ class CapsLockManager: ObservableObject {
|
|||
private var localEventMonitor: Any?
|
||||
private var globalEventMonitor: Any?
|
||||
private let coordinator = DynamicIslandViewCoordinator.shared
|
||||
private let capsLockAnimation = Animation.spring(response: 0.32, dampingFraction: 0.85)
|
||||
|
||||
private init() {
|
||||
// Get initial state
|
||||
|
|
@ -55,7 +57,9 @@ class CapsLockManager: ObservableObject {
|
|||
|
||||
guard newState != isCapsLockActive else { return }
|
||||
|
||||
isCapsLockActive = newState
|
||||
withAnimation(capsLockAnimation) {
|
||||
isCapsLockActive = newState
|
||||
}
|
||||
|
||||
print("CapsLockManager: Caps Lock \(newState ? "ACTIVATED" : "DEACTIVATED")")
|
||||
|
||||
|
|
|
|||
|
|
@ -741,6 +741,7 @@ extension Defaults.Keys {
|
|||
// MARK: Caps Lock Indicator
|
||||
static let enableCapsLockIndicator = Key<Bool>("enableCapsLockIndicator", default: true)
|
||||
static let capsLockIndicatorUseGreenColor = Key<Bool>("capsLockIndicatorUseGreenColor", default: false)
|
||||
static let showCapsLockLabel = Key<Bool>("showCapsLockLabel", default: true)
|
||||
|
||||
// MARK: ImageService
|
||||
static let didClearLegacyURLCacheV1 = Key<Bool>("didClearLegacyURLCacheV1", default: false)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue