feat: home screen quick actions (long press app icon)

Adds four UIApplicationShortcutItems registered dynamically at launch:
  • Add Task — opens the add-task sheet immediately, any tab
  • Today — switches to the Today tab
  • Calendar — switches to the Calendar tab
  • Workout — switches to the Workout tab (only registered if the
    workout tab is enabled in settings; re-registers when the setting changes)

Cold-launch and foreground-activation paths both handled via AppDelegate.
ShortcutHandler singleton bridges UIKit callbacks to SwiftUI via @Published.
This commit is contained in:
kutesir
2026-05-30 02:38:15 +03:00
parent e0e4f709b6
commit cab5c4ef05
4 changed files with 116 additions and 3 deletions

View File

@@ -9,9 +9,11 @@ struct ContentView: View {
@AppStorage("showMatrixTab") private var showMatrixTab = true
@AppStorage("showWorkoutTab") private var showWorkoutTab = true
@AppStorage("hasOnboarded") private var hasOnboarded = false
@State private var showOnboarding = false
@State private var selectedTab = 0
@StateObject private var tabState = FloatingTabState()
@State private var showOnboarding = false
@State private var selectedTab = 0
@State private var showQuickAddTask = false
@StateObject private var tabState = FloatingTabState()
@ObservedObject private var shortcuts = ShortcutHandler.shared
@State private var iPadSelection: Int? = 0
@State private var calIconImage: Image = ContentView.buildCalIcon()
@@ -92,6 +94,27 @@ struct ContentView: View {
.onChange(of: workoutVM.doneSets) { _ in
NotificationManager.shared.reschedule(workoutVM: workoutVM, taskVM: taskVM)
}
.onChange(of: shortcuts.pending) { action in
guard let action else { return }
switch action {
case .addTask:
showQuickAddTask = true
case .today:
withAnimation(KisaniSpring.micro) { selectedTab = 0 }
case .calendar:
withAnimation(KisaniSpring.micro) { selectedTab = 1 }
case .workout:
withAnimation(KisaniSpring.micro) { selectedTab = showWorkoutTab ? 3 : 0 }
}
shortcuts.consume()
}
.sheet(isPresented: $showQuickAddTask) {
AddTaskSheet(prefilledDate: Date())
.environmentObject(taskVM)
.presentationDetents([.height(150)])
.presentationDragIndicator(.visible)
}
.onChange(of: showWorkoutTab) { _ in ShortcutHandler.registerShortcuts() }
}
// MARK: - iPhone