Преглед изворни кода

Fix alignment on Snooze button when using iOS Display Zoom (#482)

* Fix alignment on Snooze button when using iOS Display Zoom

* Auto-hide Snooze all button after alarm
Daniel Mini Johansson пре 7 месеци
родитељ
комит
46e98de683
1 измењених фајлова са 71 додато и 50 уклоњено
  1. 71 50
      LoopFollow/Snoozer/SnoozerView.swift

+ 71 - 50
LoopFollow/Snoozer/SnoozerView.swift

@@ -74,8 +74,11 @@ struct SnoozerView: View {
                     if alarm != nil {
                         showSnoozerBar = true
                         cancelAutoHide()
-                    } else if !isGlobalSnoozeActive {
-                        scheduleAutoHide()
+                    } else {
+                        // When alarm is dismissed, schedule auto-hide if no global snooze is active
+                        if !isGlobalSnoozeActive {
+                            scheduleAutoHide()
+                        }
                     }
                 }
                 .onChange(of: isGlobalSnoozeActive) { active in
@@ -95,6 +98,56 @@ struct SnoozerView: View {
                         .transition(.move(edge: .top).combined(with: .opacity))
                 }
             }
+            .overlay(alignment: .bottom) {
+                if let alarm = vm.activeAlarm {
+                    VStack(spacing: 16) {
+                        // Alarm name at the top
+                        Text(alarm.name)
+                            .font(.system(size: 30, weight: .semibold))
+                            .foregroundColor(.white)
+                            .lineLimit(1)
+                            .minimumScaleFactor(0.5)
+                            .padding(.top, 20)
+
+                        Divider()
+
+                        // Snooze duration controls
+                        if alarm.type.snoozeTimeUnit != .none {
+                            HStack {
+                                VStack(alignment: .leading, spacing: 4) {
+                                    Text("Snooze for")
+                                        .font(.headline)
+                                    Text("\(vm.snoozeUnits) \(vm.timeUnitLabel)")
+                                        .font(.title3).bold()
+                                }
+                                Spacer()
+                                Stepper("", value: $vm.snoozeUnits,
+                                        in: alarm.type.snoozeRange,
+                                        step: alarm.type.snoozeStep)
+                                    .labelsHidden()
+                            }
+                            .padding(.horizontal, 24)
+                        }
+
+                        // Snooze button anchored to tab bar edge (bottom of VStack)
+                        Button(action: vm.snoozeTapped) {
+                            Text(vm.snoozeUnits == 0 ? "Acknowledge" : "Snooze")
+                                .font(.system(size: 30, weight: .bold))
+                                .frame(maxWidth: .infinity, minHeight: 60)
+                                .background(Color.orange)
+                                .foregroundColor(.white)
+                                .clipShape(Capsule())
+                        }
+                        .padding(.horizontal, 24)
+                        .padding(.bottom, 20)
+                    }
+                    .background(.ultraThinMaterial)
+                    .cornerRadius(20, corners: [.topLeft, .topRight])
+                    .transition(.move(edge: .bottom).combined(with: .opacity))
+                    .animation(.spring(), value: vm.activeAlarm != nil)
+                    .padding(.bottom, 0) // Anchor directly to bottom edge
+                }
+            }
             .sheet(isPresented: $showDatePickerDate) { datePickerSheetDate() }
             .sheet(isPresented: $showDatePickerTime) { datePickerSheetTime() }
         }
@@ -171,57 +224,23 @@ struct SnoozerView: View {
                     .padding(.bottom, 8)
             }
 
-            if let alarm = vm.activeAlarm {
-                VStack(spacing: 16) {
-                    Text(alarm.name)
-                        .font(.system(size: 30, weight: .semibold))
-                        .foregroundColor(.white)
-                        .lineLimit(1)
-                        .minimumScaleFactor(0.5)
-                        .padding(.top, 20)
-                    Divider()
-
-                    if alarm.type.snoozeTimeUnit != .none {
-                        HStack {
-                            VStack(alignment: .leading, spacing: 4) {
-                                Text("Snooze for")
-                                    .font(.headline)
-                                Text("\(vm.snoozeUnits) \(vm.timeUnitLabel)")
-                                    .font(.title3).bold()
-                            }
-                            Spacer()
-                            Stepper("", value: $vm.snoozeUnits,
-                                    in: alarm.type.snoozeRange,
-                                    step: alarm.type.snoozeStep)
-                                .labelsHidden()
-                        }
-                        .padding(.horizontal, 24)
-                    }
+            if snoozerEmoji.value {
+                TimelineView(.periodic(from: .now, by: 1)) { context in
+                    VStack(spacing: 4) {
+                        Text(bgEmoji)
+                            .font(.system(size: 128))
+                            .minimumScaleFactor(0.5)
 
-                    Button(action: vm.snoozeTapped) {
-                        Text(vm.snoozeUnits == 0 ? "Acknowledge" : "Snooze")
-                            .font(.system(size: 30, weight: .bold))
-                            .frame(maxWidth: .infinity, minHeight: 60)
-                            .background(Color.orange)
+                        Text(context.date, format: Date.FormatStyle(date: .omitted, time: .shortened))
+                            .font(.system(size: 70))
+                            .minimumScaleFactor(0.5)
                             .foregroundColor(.white)
-                            .clipShape(Capsule())
+                            .frame(height: 78)
                     }
-                    .padding(.horizontal, 24)
-                    .padding(.bottom, 20)
                 }
-                .background(.ultraThinMaterial)
-                .cornerRadius(20, corners: [.topLeft, .topRight])
-                .transition(.move(edge: .bottom).combined(with: .opacity))
-                .animation(.spring(), value: vm.activeAlarm != nil)
             } else {
                 TimelineView(.periodic(from: .now, by: 1)) { context in
                     VStack(spacing: 4) {
-                        if snoozerEmoji.value {
-                            Text(bgEmoji)
-                                .font(.system(size: 128))
-                                .minimumScaleFactor(0.5)
-                        }
-
                         Text(context.date, format: Date.FormatStyle(date: .omitted, time: .shortened))
                             .font(.system(size: 70))
                             .minimumScaleFactor(0.5)
@@ -229,8 +248,8 @@ struct SnoozerView: View {
                             .frame(height: 78)
                     }
                 }
-                Spacer()
             }
+            Spacer()
         }
     }
 
@@ -471,10 +490,12 @@ struct SnoozerView: View {
 
     private func scheduleAutoHide() {
         cancelAutoHide()
-        if isGlobalSnoozeActive || vm.activeAlarm != nil { return }
+        // Always schedule the task - it will check conditions when it executes
+        // This ensures auto-hide works even if conditions change between scheduling and execution
         let task = DispatchWorkItem {
-            if !isGlobalSnoozeActive && vm.activeAlarm == nil {
-                withAnimation { showSnoozerBar = false }
+            // Only hide if neither global snooze nor active alarm exists
+            if !self.isGlobalSnoozeActive && self.vm.activeAlarm == nil {
+                withAnimation { self.showSnoozerBar = false }
             }
         }
         autoHideTask = task