mycode/myApp/HaruDanim/IOS/Core/Settings.swift
songyc macbook ecc4c016f7 feat(main): implement snap-scrolling carousel for goal widgets with unified display options
- Remove the maximum limit for selected goal widgets on the main tab
- Unify the display format (aggregate vs. individual) to apply globally across all selected goals
- Redesign the horizontal scrolling into a full-width snap carousel (pagination style)
- Ensure only one widget is fully visible at a time with no adjacent cards partially showing
- Apply snap scrolling so light swipes firmly transition to the next or previous widget
2026-07-10 04:11:14 +09:00

123 lines
3.8 KiB
Swift

//
// Settings.swift
// Haru_Danim
//
// , (CLAUDE.md §6.6, §7)
//
import Foundation
enum SettingsKeys {
/// "light" | "dark"
static let theme = "settings.theme"
/// "ko" | "en" | "ja"
static let language = "settings.language"
/// Calendar.weekday (1= ... 7=). 2()
static let weekStartWeekday = "settings.weekStartWeekday"
/// . 0 (00:00)
static let dayStartMinutes = "settings.dayStartMinutes"
/// "latest"( ) | "earliest"( ). latest
static let liveActivityMode = "settings.liveActivityMode"
///
static let isPremium = "settings.isPremium"
/// . 3
static let gridColumns = "settings.gridColumns"
/// () . 0 =
static let minSessionSeconds = "settings.minSessionSeconds"
/// ( 1~3). AppTab rawValue
static let visibleTabs = "settings.visibleTabs"
/// . GoalCardStyle rawValue ("perQuest" | "combined")
static let goalCardStyle = "settings.goalCardStyle"
}
/// ( )
enum GoalCardStyle: String, CaseIterable, Identifiable {
/// ( 3) //
case perQuest
/// // ()
case combined
var id: String { rawValue }
var label: String {
switch self {
case .perQuest: return "다짐별로 각각"
case .combined: return "전체 다짐 합산"
}
}
}
enum TabBarConfig {
/// : · · (+)
static let defaultVisibleTabs = "main,action,history"
static let maxVisible = 3
static let minVisible = 1
}
/// ()
enum MinSessionOption {
static let choices: [(seconds: Int, label: String)] = [
(0, "사용 안 함"),
(3, "3초"),
(5, "5초"),
(10, "10초"),
(30, "30초"),
(60, "1분"),
]
}
enum LiveActivityMode: String, CaseIterable, Identifiable {
case latest
case earliest
var id: String { rawValue }
var label: String {
switch self {
case .latest: return "가장 나중에 시작한 행동"
case .earliest: return "가장 먼저 시작한 행동"
}
}
}
enum AppLanguage: String, CaseIterable, Identifiable {
case ko, en, ja
var id: String { rawValue }
var label: String {
switch self {
case .ko: return "한국어"
case .en: return "English"
case .ja: return "日本語"
}
}
}
/// (CLAUDE.md §7.1)
enum FreeLimits {
static let actions = 10
static let goals = 2
static let questsPerGoal = 3
}
///
struct TrackingSettings {
var weekStartWeekday: Int
var dayStartMinutes: Int
static func current() -> TrackingSettings {
let defaults = UserDefaults.standard
return TrackingSettings(
weekStartWeekday: defaults.object(forKey: SettingsKeys.weekStartWeekday) as? Int ?? 2,
dayStartMinutes: defaults.object(forKey: SettingsKeys.dayStartMinutes) as? Int ?? 0
)
}
var calendar: Calendar {
var cal = Calendar.current
cal.firstWeekday = weekStartWeekday
return cal
}
}