mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
Working stuff
This commit is contained in:
parent
41118ddb4c
commit
8e003b620f
6 changed files with 91 additions and 3 deletions
|
|
@ -406,7 +406,7 @@ struct ContentView: View {
|
||||||
.frame(width: 76, alignment: .trailing)
|
.frame(width: 76, alignment: .trailing)
|
||||||
}
|
}
|
||||||
.frame(height: vm.effectiveClosedNotchHeight + (isHovering ? 8 : 0), alignment: .center)
|
.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 != .volume || vm.notchState == .closed) {
|
} 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)
|
InlineHUD(type: $coordinator.sneakPeek.type, value: $coordinator.sneakPeek.value, icon: $coordinator.sneakPeek.icon, hoverAnimation: $isHovering, gestureProgress: $gestureProgress)
|
||||||
.transition(.opacity)
|
.transition(.opacity)
|
||||||
} else if (!coordinator.expandingView.show || coordinator.expandingView.type == .music) && vm.notchState == .closed && (musicManager.isPlaying || !musicManager.isPlayerIdle) && coordinator.musicLiveActivityEnabled && !vm.hideOnClosed && !lockScreenManager.isLocked {
|
} else if (!coordinator.expandingView.show || coordinator.expandingView.type == .music) && vm.notchState == .closed && (musicManager.isPlaying || !musicManager.isPlayerIdle) && coordinator.musicLiveActivityEnabled && !vm.hideOnClosed && !lockScreenManager.isLocked {
|
||||||
|
|
@ -469,6 +469,19 @@ struct ContentView: View {
|
||||||
.padding(.bottom, 10)
|
.padding(.bottom, 10)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if coordinator.sneakPeek.type == .reminder {
|
||||||
|
if !vm.hideOnClosed && Defaults[.sneakPeekStyles] == .standard, let reminder = reminderManager.activeReminder {
|
||||||
|
GeometryReader { geo in
|
||||||
|
MarqueeText(
|
||||||
|
.constant(reminderSneakPeekText(for: reminder)),
|
||||||
|
textColor: reminderColor(for: reminder.event),
|
||||||
|
minDuration: 1,
|
||||||
|
frameWidth: geo.size.width
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.padding(.bottom, 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -509,6 +522,32 @@ struct ContentView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func reminderColor(for event: EventModel) -> Color {
|
||||||
|
Color(nsColor: event.calendar.color).ensureMinimumBrightness(factor: 0.7)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func reminderSneakPeekText(for entry: ReminderLiveActivityManager.ReminderEntry) -> String {
|
||||||
|
let title = entry.event.title.isEmpty ? "Upcoming Reminder" : entry.event.title
|
||||||
|
let remaining = max(entry.event.start.timeIntervalSince(reminderManager.currentDate), 0)
|
||||||
|
let minutes = Int(ceil(remaining / 60))
|
||||||
|
let timeString = reminderTimeFormatter.string(from: entry.event.start)
|
||||||
|
|
||||||
|
if minutes <= 0 {
|
||||||
|
return "\(title) • starts now @ \(timeString)"
|
||||||
|
} else if minutes == 1 {
|
||||||
|
return "\(title) • in 1 min @ \(timeString)"
|
||||||
|
} else {
|
||||||
|
return "\(title) • in \(minutes) min @ \(timeString)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private let reminderTimeFormatter: DateFormatter = {
|
||||||
|
let formatter = DateFormatter()
|
||||||
|
formatter.dateStyle = .none
|
||||||
|
formatter.timeStyle = .short
|
||||||
|
return formatter
|
||||||
|
}()
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
func DynamicIslandFaceAnimation() -> some View {
|
func DynamicIslandFaceAnimation() -> some View {
|
||||||
HStack {
|
HStack {
|
||||||
|
|
|
||||||
|
|
@ -144,9 +144,17 @@ class DynamicIslandViewCoordinator: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
func toggleSneakPeek(status: Bool, type: SneakContentType, duration: TimeInterval = 1.5, value: CGFloat = 0, icon: String = "") {
|
func toggleSneakPeek(status: Bool, type: SneakContentType, duration: TimeInterval = 1.5, value: CGFloat = 0, icon: String = "") {
|
||||||
let resolvedDuration = type == .timer ? 10 : duration
|
let resolvedDuration: TimeInterval
|
||||||
|
switch type {
|
||||||
|
case .timer:
|
||||||
|
resolvedDuration = 10
|
||||||
|
case .reminder:
|
||||||
|
resolvedDuration = Defaults[.reminderSneakPeekDuration]
|
||||||
|
default:
|
||||||
|
resolvedDuration = duration
|
||||||
|
}
|
||||||
sneakPeekDuration = resolvedDuration
|
sneakPeekDuration = resolvedDuration
|
||||||
if type != .music && type != .timer {
|
if type != .music && type != .timer && type != .reminder {
|
||||||
// close()
|
// close()
|
||||||
if !hudReplacement {
|
if !hudReplacement {
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -872,6 +872,10 @@
|
||||||
"comment" : "A text label displaying the current value of the \"Notify before\" slider. The argument is the current value of the slider, expressed in minutes.",
|
"comment" : "A text label displaying the current value of the \"Notify before\" slider. The argument is the current value of the slider, expressed in minutes.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated" : true
|
||||||
},
|
},
|
||||||
|
"%lld s" : {
|
||||||
|
"comment" : "A text view displaying the duration of the \"sneak peek\" feature in the reminder live activity section of the calendar settings view. The text is followed by a unit of measurement (\"s\").",
|
||||||
|
"isCommentAutoGenerated" : true
|
||||||
|
},
|
||||||
"%lld%%" : {
|
"%lld%%" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"ar" : {
|
"ar" : {
|
||||||
|
|
@ -17177,6 +17181,10 @@
|
||||||
"comment" : "A description of how the color-coding feature works.",
|
"comment" : "A description of how the color-coding feature works.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated" : true
|
||||||
},
|
},
|
||||||
|
"Sneak peek duration" : {
|
||||||
|
"comment" : "A label describing the duration of the \"sneak peek\" feature in the calendar settings.",
|
||||||
|
"isCommentAutoGenerated" : true
|
||||||
|
},
|
||||||
"Sneak Peek shows the media title and artist under the notch for a few seconds." : {
|
"Sneak Peek shows the media title and artist under the notch for a few seconds." : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"ar" : {
|
"ar" : {
|
||||||
|
|
|
||||||
|
|
@ -956,6 +956,7 @@ struct CalendarSettings: View {
|
||||||
@Default(.enableReminderLiveActivity) var enableReminderLiveActivity
|
@Default(.enableReminderLiveActivity) var enableReminderLiveActivity
|
||||||
@Default(.reminderPresentationStyle) var reminderPresentationStyle
|
@Default(.reminderPresentationStyle) var reminderPresentationStyle
|
||||||
@Default(.reminderLeadTime) var reminderLeadTime
|
@Default(.reminderLeadTime) var reminderLeadTime
|
||||||
|
@Default(.reminderSneakPeekDuration) var reminderSneakPeekDuration
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
|
|
@ -1026,6 +1027,19 @@ struct CalendarSettings: View {
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
.frame(width: 60, alignment: .trailing)
|
.frame(width: 60, alignment: .trailing)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HStack {
|
||||||
|
Text("Sneak peek duration")
|
||||||
|
Slider(
|
||||||
|
value: $reminderSneakPeekDuration,
|
||||||
|
in: 3...20,
|
||||||
|
step: 1
|
||||||
|
)
|
||||||
|
.disabled(!enableReminderLiveActivity)
|
||||||
|
Text("\(Int(reminderSneakPeekDuration)) s")
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.frame(width: 60, alignment: .trailing)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Section(header: Text("Select Calendars")) {
|
Section(header: Text("Select Calendars")) {
|
||||||
|
|
|
||||||
|
|
@ -259,6 +259,13 @@ final class ReminderLiveActivityManager: ObservableObject {
|
||||||
}
|
}
|
||||||
if activeReminder != entry {
|
if activeReminder != entry {
|
||||||
activeReminder = entry
|
activeReminder = entry
|
||||||
|
DynamicIslandViewCoordinator.shared.toggleSneakPeek(
|
||||||
|
status: true,
|
||||||
|
type: .reminder,
|
||||||
|
duration: Defaults[.reminderSneakPeekDuration],
|
||||||
|
value: 0,
|
||||||
|
icon: glyphName(for: entry.event)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
startTickerIfNeeded()
|
startTickerIfNeeded()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -269,4 +276,15 @@ final class ReminderLiveActivityManager: ObservableObject {
|
||||||
scheduleEvaluation(at: entry.triggerDate)
|
scheduleEvaluation(at: entry.triggerDate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func glyphName(for event: EventModel) -> String {
|
||||||
|
switch event.type {
|
||||||
|
case .birthday:
|
||||||
|
return "gift.fill"
|
||||||
|
case .reminder(let completed):
|
||||||
|
return completed ? "checkmark.circle" : "bell.fill"
|
||||||
|
case .event:
|
||||||
|
return event.isMeeting ? "person.2.fill" : "calendar"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -463,6 +463,7 @@ extension Defaults.Keys {
|
||||||
static let enableReminderLiveActivity = Key<Bool>("enableReminderLiveActivity", default: true)
|
static let enableReminderLiveActivity = Key<Bool>("enableReminderLiveActivity", default: true)
|
||||||
static let reminderPresentationStyle = Key<ReminderPresentationStyle>("reminderPresentationStyle", default: .ringCountdown)
|
static let reminderPresentationStyle = Key<ReminderPresentationStyle>("reminderPresentationStyle", default: .ringCountdown)
|
||||||
static let reminderLeadTime = Key<Int>("reminderLeadTime", default: 5)
|
static let reminderLeadTime = Key<Int>("reminderLeadTime", default: 5)
|
||||||
|
static let reminderSneakPeekDuration = Key<Double>("reminderSneakPeekDuration", default: 10)
|
||||||
static let timerControlWindowEnabled = Key<Bool>("timerControlWindowEnabled", default: true)
|
static let timerControlWindowEnabled = Key<Bool>("timerControlWindowEnabled", default: true)
|
||||||
|
|
||||||
// MARK: ColorPicker Feature
|
// MARK: ColorPicker Feature
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue