// // ActionControlWidget.swift // Haru_DanimWidgets // // 제어 센터 컨트롤 (iOS 18+): 화면을 켜자마자 제어 센터/잠금화면 하단/액션 버튼에서 // 행동을 실행한다. 시간형 = 시작/종료 토글, 횟수형 = 켤 때마다 +1. // 실행은 ToggleActionControlIntent(LiveActivityIntent) — 앱 프로세스에서 돌아 // 제어 센터에서 시작해도 다이나믹 아일랜드가 바로 뜬다. // import AppIntents import SwiftUI import WidgetKit // MARK: - 설정 (어떤 행동을 담을지) struct ActionControlConfigIntent: ControlConfigurationIntent { static let title: LocalizedStringResource = "행동 선택" static let description = IntentDescription("제어 센터 버튼으로 실행할 행동을 선택하세요.") @Parameter(title: "행동") var action: ActionEntity? } // MARK: - 값 공급자 /// 컨트롤에 그릴 상태 스냅숏 struct ActionControlValue { var actionID: String var name: String var symbolName: String var isCount: Bool var isRunning: Bool var locked: Bool } struct ActionControlProvider: AppIntentControlValueProvider { func previewValue(configuration: ActionControlConfigIntent) -> ActionControlValue { ActionControlValue( actionID: "", name: String(localized: "독서"), symbolName: "book.fill", isCount: false, isRunning: false, locked: false ) } func currentValue(configuration: ActionControlConfigIntent) async throws -> ActionControlValue { await MainActor.run { IntentStore.refresh() guard WidgetStore.isUnlocked else { return ActionControlValue( actionID: "", name: String(localized: "프리미엄 기능"), symbolName: "crown.fill", isCount: false, isRunning: false, locked: true ) } // 미선택이면 이 기기 배치 순서의 첫 행동 guard let model = WidgetStore.action(configuration.action?.id) ?? WidgetStore.defaultActions(1).first else { return ActionControlValue( actionID: "", name: String(localized: "행동 없음"), symbolName: "square.grid.2x2", isCount: false, isRunning: false, locked: false ) } return ActionControlValue( actionID: model.uuid.uuidString, name: model.name, symbolName: model.symbolName, isCount: model.trackingType == .count, isRunning: model.isRunning, locked: false ) } } } // MARK: - 컨트롤 정의 struct ActionRunControl: ControlWidget { var body: some ControlWidgetConfiguration { AppIntentControlConfiguration( kind: "HaruActionRunControl", provider: ActionControlProvider() ) { value in ControlWidgetToggle( value.name, isOn: value.isRunning, action: ToggleActionControlIntent(actionID: value.actionID) ) { isOn in Label( value.locked ? String(localized: "프리미엄 필요") : value.isCount ? String(localized: "탭해서 +1") : isOn ? String(localized: "측정 중") : String(localized: "시작"), systemImage: SymbolCompat.safe(value.symbolName) ) } } .displayName("행동 실행") .description("행동 하나를 골라 제어 센터에서 바로 실행해요. 시간 측정은 시작/종료 토글, 횟수 기록은 탭마다 +1. (프리미엄)") } }