feat(settings): '짧은 기록 무시'를 iCloud 키-값 저장소로 전 기기 동기화 (1.1)
- 검사가 종료 실행 기기 기준이라 기기별 값이면 교차 사용(아이패드 시작→아이폰 종료)에서 결과가 갈리던 문제 해소 — 값 자체를 모든 기기에서 통일 - SettingsCloudSync: 시작 시 iCloud 값 채택(없으면 로컬 값 시드), 외부 변경·포그라운드 복귀 때 pull, 설정 변경 때 push(동일 값 가드). App Group 저장은 유지(위젯·인텐트 읽기 경로 무변경), CloudKit 스키마·프리미엄 토글과 무관 — ubiquity-kvstore 엔타이틀먼트만 추가 - 설정: 측정 섹션을 나눠 '짧은 기록 무시' 바로 밑에 전 기기 공통 안내 푸터, '장시간 측정 알림'은 기기별 유지 명시. 도움말도 갱신, en/ja 번역(missing 0·stale 0, 실렌더 확인) - whats-new-1.1 3개 언어에 항목 추가, CLAUDE.md §6.8 갱신 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVeduv1eNdXjk1ay4tSgBg
This commit is contained in:
parent
183b0a6fa0
commit
2fb7b3c75a
@ -234,7 +234,7 @@ xcrun xcstringstool sync Widgets/Localizable.xcstrings --stringsdata "${widget_f
|
||||
### 6.8 설정 탭 (`SettingsView`)
|
||||
- 테마(**시스템 설정 따름(기본)**/라이트/다크 — 즉시 적용, App Group 저장으로 위젯 공유. "system"은 스킴을 강제하지 않아 앱·위젯 모두 시스템 모드를 따름 — 2026-07-23 UX 감사에서 추가, 기본값도 light→system) / 언어(재시작 적용, AppleLanguages 오버라이드)
|
||||
- iPhone만: 내비게이션 방식(탭바/버블) + 탭바 구성 or 버블 순서·두 번 눌러 바로 이동(토글+대상 탭)
|
||||
- 모음 탭 목표 카드 선택(개수 무제한)+표시 방식 / 주 시작 요일 / 하루 시작 시간 / 짧은 기록 무시(**기기별 설정** — App Group defaults라 iCloud 동기화 안 됨. 검사는 종료를 실행한 기기의 설정 기준이고 워치 종료는 페어링 아이폰에서 실행되므로 아이폰 설정 적용 — 기기 간 시작·종료 시 값이 다르면 짧은 기록이 저장될 수 있음. 실사용 보고로 확인된 의도된 동작, 설정 푸터·도움말에 명시) / **장시간 측정 알림**(1~12시간, 켜는 순간 알림 권한 요청 — `SessionAlertManager`가 LiveActivityManager.sync 길목에서 진행 세션과 예약을 동기화, 세션 종료·설정 변경 시 예약 제거) / 대표 시간 기준(가장 먼저·나중에 시작 — 기본 latest)
|
||||
- 모음 탭 목표 카드 선택(개수 무제한)+표시 방식 / 주 시작 요일 / 하루 시작 시간 / 짧은 기록 무시(**전 기기 공통 — iCloud 키-값 저장소 동기화**(1.1, `IOS/Core/SettingsCloudSync.swift` + `ubiquity-kvstore-identifier` 엔타이틀먼트): 검사는 종료를 실행한 기기의 설정 기준이라 기기별 값이면 교차 사용(아이패드 시작→아이폰 종료)에서 결과가 갈리던 실사용 보고의 해소. 값 저장은 여전히 App Group defaults고 KVS가 미러 — 시작 시 iCloud 값 채택(없으면 로컬 값 시드), 외부 변경·포그라운드 복귀 때 pull, 설정 변경 때 push(동일 값 가드로 되울림 방지). CloudKit 데이터 동기화(프리미엄 토글)와 별개라 iCloud 로그인만으로 동작, 미로그인이면 로컬 값 유지. 워치 종료는 페어링 아이폰에서 실행되므로 아이폰 설정 적용. 다른 Int 설정을 공통화하려면 syncedKeys에 추가만 하면 됨) / **장시간 측정 알림**(1~12시간, 켜는 순간 알림 권한 요청 — `SessionAlertManager`가 LiveActivityManager.sync 길목에서 진행 세션과 예약을 동기화, 세션 종료·설정 변경 시 예약 제거) / 대표 시간 기준(가장 먼저·나중에 시작 — 기본 latest)
|
||||
- 데이터: **데이터 내보내기** — 행동·시간·횟수·목표·다짐을 CSV 5파일로 (ISO 8601, UTF-8 BOM, 무료 포함) / **데이터 가져오기**(1.1, 프리미엄 — `IOS/Core/CSVImport.swift`+`DataImportView`): 내보낸 CSV에서 행동·시간·횟수 기록 복원. **추가 전용**(수정·삭제 없음), 파일 선택(복수)→미리 보기→확인→저장 1회(DataChange.commit), **멱등**(기록 중복은 초 단위 절사 동일성으로 건너뜀 — 내보내기가 초 단위라 원본의 소수점 초 유사 중복까지 흡수), 파일 종류는 헤더가 아니라 **데이터 행 모양으로 판별**(UUID·ISO 날짜·time/count — 내보낸 언어와 무관), 행동 연결은 uuid 우선→이름+방식 폴백→새로 생성(csv uuid 보존, 꼬리표는 이름으로 재사용/프리셋 색 생성), '측정 중'(종료 없음) 행은 건너뜀(유령 Live Activity 방지), 목표·다짐은 비대상(다짐 CSV는 주기가 표시 문자열이라 재구성 불가 — 사용자 결정). 프리미엄 게이트 이유: CSV로 무료 한도(행동 10개) 우회 방지. 검증 `-csvImportTest`(§14)
|
||||
- 프리미엄 화면(§8) / 도움말(`HelpView` — 기기별 주제 분기, DisclosureGroup. **그룹당 대표 주제 1개에 예시 스크린샷**(IOS/HelpImages/help-<이름>-<ko|en|ja>.jpg, 총 18장 ≈1.6MB) — 언어별 파일을 HelpImage 로더가 표시 언어로 선택(jpg라 UIImage(named:) 대신 URL 로드). 앱 화면·문구가 크게 바뀌면 해당 스크린샷도 재촬영할 것: 시뮬 로케일별 재시드 후 §14 인자로 촬영, 워치는 상태바 크롭) / 버전(번들 CFBundleShortVersionString 표시)
|
||||
|
||||
|
||||
@ -14,6 +14,8 @@
|
||||
</array>
|
||||
<key>com.apple.developer.siri</key>
|
||||
<true/>
|
||||
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
|
||||
<string>$(TeamIdentifierPrefix)$(CFBundleIdentifier)</string>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.com.yechan.HaruDanim</string>
|
||||
|
||||
70
myApp/HaruDanim/IOS/Core/SettingsCloudSync.swift
Normal file
70
myApp/HaruDanim/IOS/Core/SettingsCloudSync.swift
Normal file
@ -0,0 +1,70 @@
|
||||
//
|
||||
// SettingsCloudSync.swift
|
||||
// Haru_Danim
|
||||
//
|
||||
// "모든 기기에서 같아야 하는" 설정의 iCloud 키-값 저장소 동기화 (현재: 짧은 기록 무시)
|
||||
// - 짧은 기록 검사는 종료를 실행한 기기의 설정을 쓰므로(§6.8), 기기마다 값이 다르면
|
||||
// 아이패드에서 시작해 아이폰에서 끝내는 식의 교차 사용에서 결과가 갈렸다 — 값 자체를 맞춘다.
|
||||
// - CloudKit 데이터 동기화(프리미엄 + cloudSync 토글)와 별개 저장소라 스키마·심사 절차 없이
|
||||
// iCloud 로그인만 되어 있으면 동작한다. 미로그인이면 조용히 로컬 값 유지.
|
||||
// - 시작 시: iCloud 값이 있으면 로컬(App Group)에 반영, 없으면 현재 로컬 값을 올려 시드.
|
||||
// 이후 외부 변경 알림·포그라운드 복귀 때 당겨오고, 설정 화면의 변경은 push로 올린다.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@MainActor
|
||||
final class SettingsCloudSync {
|
||||
static let shared = SettingsCloudSync()
|
||||
|
||||
/// 동기화 대상 키 — 추가할 설정이 생기면 여기에만 더하면 된다 (Int 값 한정)
|
||||
private let syncedKeys = [SettingsKeys.minSessionSeconds]
|
||||
private var observers: [any NSObjectProtocol] = []
|
||||
|
||||
/// 앱 시작 시 1회 호출
|
||||
func start() {
|
||||
guard observers.isEmpty else { return }
|
||||
let kvs = NSUbiquitousKeyValueStore.default
|
||||
let center = NotificationCenter.default
|
||||
observers.append(center.addObserver(
|
||||
forName: NSUbiquitousKeyValueStore.didChangeExternallyNotification,
|
||||
object: kvs, queue: nil
|
||||
) { _ in
|
||||
Task { @MainActor in SettingsCloudSync.shared.pull(seedIfMissing: false) }
|
||||
})
|
||||
observers.append(center.addObserver(
|
||||
forName: UIApplication.willEnterForegroundNotification,
|
||||
object: nil, queue: nil
|
||||
) { _ in
|
||||
Task { @MainActor in
|
||||
NSUbiquitousKeyValueStore.default.synchronize()
|
||||
SettingsCloudSync.shared.pull(seedIfMissing: false)
|
||||
}
|
||||
})
|
||||
kvs.synchronize()
|
||||
pull(seedIfMissing: true)
|
||||
}
|
||||
|
||||
/// iCloud → 로컬(App Group). 최초 1회는 iCloud에 값이 없으면 현재 로컬 값을 올려
|
||||
/// 이후 기기들이 따라오게 한다(먼저 업데이트한 기기의 값으로 통일).
|
||||
private func pull(seedIfMissing: Bool) {
|
||||
let kvs = NSUbiquitousKeyValueStore.default
|
||||
for key in syncedKeys {
|
||||
if let remote = kvs.object(forKey: key) as? Int {
|
||||
if AppGroup.defaults.object(forKey: key) as? Int != remote {
|
||||
AppGroup.defaults.set(remote, forKey: key)
|
||||
}
|
||||
} else if seedIfMissing, let local = AppGroup.defaults.object(forKey: key) {
|
||||
kvs.set(local, forKey: key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 설정 화면에서 값이 바뀔 때 호출 — 같은 값이면 올리지 않는다(원격 반영의 되울림 방지)
|
||||
func push(_ value: Int, forKey key: String) {
|
||||
let kvs = NSUbiquitousKeyValueStore.default
|
||||
guard kvs.object(forKey: key) as? Int != value else { return }
|
||||
kvs.set(value, forKey: key)
|
||||
kvs.synchronize()
|
||||
}
|
||||
}
|
||||
@ -35,6 +35,8 @@ struct Haru_DanimApp: App {
|
||||
// 실결제 권한 제공자 주입 (다른 무엇보다 먼저 — shared 최초 접근 전에 교체)
|
||||
PremiumManager.bootstrap(provider: StoreKitEntitlementProvider())
|
||||
SettingsMigration.runIfNeeded()
|
||||
// 짧은 기록 무시 등 "모든 기기 공통" 설정을 iCloud 키-값 저장소와 동기화
|
||||
SettingsCloudSync.shared.start()
|
||||
container = DataStore.shared
|
||||
DataStore.ensureUniqueEntityIDs(context: container.mainContext)
|
||||
// 배치·노출 등 기기별 UI 설정: 구버전에 모델(@Model)로 저장하던 값을 로컬로 1회 이관
|
||||
|
||||
@ -7026,18 +7026,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"설정 → 측정에서 '짧은 기록 무시'를 켜면 설정한 시간보다 짧게 측정하고 끝낸 기록은 저장하지 않아요. 행동 버튼을 실수로 눌렀다가 바로 껐을 때 의미 없는 기록이 쌓이는 것을 막아 줘요. 기준 시간은 3초부터 1분까지 고를 수 있고, 위젯·워치·시리로 종료할 때도 적용돼요. 이 설정은 기기마다 따로 저장되고 측정을 끝낸 기기의 설정이 적용되니, 아이폰과 아이패드를 함께 쓴다면 두 기기 모두 설정해 주세요. 애플워치에서 끝낸 측정은 페어링된 아이폰의 설정을 따라요.": {
|
||||
"설정 → 측정에서 '짧은 기록 무시'를 켜면 설정한 시간보다 짧게 측정하고 끝낸 기록은 저장하지 않아요. 행동 버튼을 실수로 눌렀다가 바로 껐을 때 의미 없는 기록이 쌓이는 것을 막아 줘요. 기준 시간은 3초부터 1분까지 고를 수 있고, 위젯·워치·시리로 종료할 때도 적용돼요. 이 설정은 iCloud를 통해 모든 기기에서 동일하게 적용되고, 애플워치에서 끝낸 측정은 페어링된 아이폰의 설정을 따라요.": {
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Turn on 'Ignore short sessions' in Settings → Tracking, and sessions shorter than the time you set won't be saved. It keeps meaningless records from piling up when you tap an action button by mistake and stop it right away. You can choose from 3 seconds to 1 minute, and it also applies when you stop from widgets, Apple Watch, or Siri. This setting is saved separately on each device and the setting of the device that ends the measurement applies, so if you use both an iPhone and an iPad, set it on both. Measurements ended on Apple Watch follow the paired iPhone's setting."
|
||||
"value": "Turn on 'Ignore short records' in Settings → Tracking to skip saving records that end sooner than the chosen time. It keeps meaningless entries from piling up when you tap an action button by mistake and stop right away. You can pick from 3 seconds to 1 minute, and it also applies when you stop from widgets, Apple Watch, or Siri. This setting syncs over iCloud and applies equally on every device, and a session stopped on Apple Watch follows the paired iPhone's setting."
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "設定 → 計測で「短い記録を無視」をオンにすると、設定した時間より短く計測して終えた記録は保存されません。アクションボタンを誤って押してすぐ止めたときに、意味のない記録がたまるのを防げます。基準時間は3秒〜1分から選べ、ウィジェット・Apple Watch・Siriから終了したときも同じように適用されます。 この設定は端末ごとに別々に保存され、計測を終了した端末の設定が適用されるため、iPhoneとiPadを併用している場合は両方で設定してください。Apple Watchで終了した計測は、ペアリングされたiPhoneの設定に従います。"
|
||||
"value": "設定 → 計測で「短い記録を無視」をオンにすると、設定した時間より短く計測して終了した記録は保存されません。アクションボタンを誤って押してすぐ止めたときに、意味のない記録が溜まるのを防ぎます。基準時間は3秒から1分まで選べ、ウィジェット・Apple Watch・Siriから終了するときにも適用されます。この設定はiCloudですべてのデバイスに同じく適用され、Apple Watchで終了した計測はペアリングされたiPhoneの設定に従います。"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7090,18 +7090,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"설정한 시간보다 짧게 측정하고 종료한 기록은 저장하지 않아요. 버튼을 실수로 눌렀을 때 유용해요. 장시간 측정 알림은 측정이 설정한 시간을 넘기면 알려줘요 — 끄는 걸 잊었을 때 유용해요.\n이 설정들은 기기마다 따로 저장돼요. 짧은 기록 무시는 측정을 끝낸 기기의 설정이 적용되니, 아이폰과 아이패드를 함께 쓴다면 두 기기 모두 설정해 주세요. 애플워치에서 끝낸 측정은 페어링된 아이폰의 설정을 따라요.": {
|
||||
"설정한 시간보다 짧게 측정하고 종료한 기록은 저장하지 않아요. 버튼을 실수로 눌렀을 때 유용해요.\n이 설정은 iCloud를 통해 모든 기기에서 동일하게 적용돼요 — 한 기기에서 바꾸면 아이폰·아이패드·맥에 함께 반영되고, 애플워치에서 끝낸 측정은 페어링된 아이폰의 설정을 따라요.": {
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Sessions shorter than the set time aren't saved — useful for accidental taps. The long-session alert notifies you when tracking passes the set time — useful when you forget to stop.\nThese settings are saved separately on each device. 'Ignore short sessions' uses the setting of the device that ends the measurement, so if you use both an iPhone and an iPad, set it on both. Measurements ended on Apple Watch follow the paired iPhone's setting."
|
||||
"value": "Records that end sooner than the chosen time are not saved. Useful when a button is tapped by mistake.\nThis setting syncs over iCloud and applies equally on every device — change it on one device and it carries to iPhone, iPad, and Mac. A session stopped on Apple Watch follows the paired iPhone's setting."
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "設定した時間より短い計測は保存されません。誤タップに便利です。長時間計測の通知は、計測が設定時間を超えるとお知らせします — 終了し忘れたときに便利です。\nこれらの設定は端末ごとに別々に保存されます。「短い記録を無視」は計測を終了した端末の設定が適用されるため、iPhoneとiPadを併用している場合は両方で設定してください。Apple Watchで終了した計測は、ペアリングされたiPhoneの設定に従います。"
|
||||
"value": "設定した時間より短く計測して終了した記録は保存されません。ボタンを誤って押したときに便利です。\nこの設定はiCloudですべてのデバイスに同じく適用されます — 1台で変更するとiPhone・iPad・Macにも反映され、Apple Watchで終了した計測はペアリングされたiPhoneの設定に従います。"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11563,6 +11563,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"측정이 설정한 시간을 넘기면 알려줘요 — 끄는 걸 잊었을 때 유용해요. 이 알림 설정은 기기마다 따로 저장돼요.": {
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Notifies you when a session runs past the chosen time — useful when you forget to stop. This notification setting is stored per device."
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "計測が設定した時間を超えるとお知らせします — 止め忘れたときに便利です。この通知設定はデバイスごとに保存されます。"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"캘린더 일정": {
|
||||
"localizations": {
|
||||
"en": {
|
||||
|
||||
@ -184,7 +184,7 @@ struct HelpView: View {
|
||||
HelpTopic(
|
||||
symbol: "clock.badge.xmark",
|
||||
title: "짧은 기록 무시",
|
||||
body: "설정 → 측정에서 '짧은 기록 무시'를 켜면 설정한 시간보다 짧게 측정하고 끝낸 기록은 저장하지 않아요. 행동 버튼을 실수로 눌렀다가 바로 껐을 때 의미 없는 기록이 쌓이는 것을 막아 줘요. 기준 시간은 3초부터 1분까지 고를 수 있고, 위젯·워치·시리로 종료할 때도 적용돼요. 이 설정은 기기마다 따로 저장되고 측정을 끝낸 기기의 설정이 적용되니, 아이폰과 아이패드를 함께 쓴다면 두 기기 모두 설정해 주세요. 애플워치에서 끝낸 측정은 페어링된 아이폰의 설정을 따라요."
|
||||
body: "설정 → 측정에서 '짧은 기록 무시'를 켜면 설정한 시간보다 짧게 측정하고 끝낸 기록은 저장하지 않아요. 행동 버튼을 실수로 눌렀다가 바로 껐을 때 의미 없는 기록이 쌓이는 것을 막아 줘요. 기준 시간은 3초부터 1분까지 고를 수 있고, 위젯·워치·시리로 종료할 때도 적용돼요. 이 설정은 iCloud를 통해 모든 기기에서 동일하게 적용되고, 애플워치에서 끝낸 측정은 페어링된 아이폰의 설정을 따라요."
|
||||
),
|
||||
HelpTopic(
|
||||
symbol: "star.fill",
|
||||
|
||||
@ -191,17 +191,26 @@ struct SettingsView: View {
|
||||
Text(option.label).tag(option.seconds)
|
||||
}
|
||||
}
|
||||
// 짧은 기록 검사는 종료를 실행한 기기 기준(§6.8) — 기기마다 값이 다르면
|
||||
// 교차 사용(아이패드 시작→아이폰 종료)에서 결과가 갈리므로 값을 iCloud로 통일
|
||||
.onChange(of: minSessionSeconds) { _, newValue in
|
||||
SettingsCloudSync.shared.push(newValue, forKey: SettingsKeys.minSessionSeconds)
|
||||
}
|
||||
} header: {
|
||||
Text("측정")
|
||||
} footer: {
|
||||
Text("설정한 시간보다 짧게 측정하고 종료한 기록은 저장하지 않아요. 버튼을 실수로 눌렀을 때 유용해요.\n이 설정은 iCloud를 통해 모든 기기에서 동일하게 적용돼요 — 한 기기에서 바꾸면 아이폰·아이패드·맥에 함께 반영되고, 애플워치에서 끝낸 측정은 페어링된 아이폰의 설정을 따라요.")
|
||||
}
|
||||
.id("measureSection")
|
||||
Section {
|
||||
Picker("장시간 측정 알림", selection: $longSessionAlertHours) {
|
||||
ForEach(LongSessionAlertOption.choices, id: \.hours) { option in
|
||||
Text(option.label).tag(option.hours)
|
||||
}
|
||||
}
|
||||
} header: {
|
||||
Text("측정")
|
||||
} footer: {
|
||||
Text("설정한 시간보다 짧게 측정하고 종료한 기록은 저장하지 않아요. 버튼을 실수로 눌렀을 때 유용해요. 장시간 측정 알림은 측정이 설정한 시간을 넘기면 알려줘요 — 끄는 걸 잊었을 때 유용해요.\n이 설정들은 기기마다 따로 저장돼요. 짧은 기록 무시는 측정을 끝낸 기기의 설정이 적용되니, 아이폰과 아이패드를 함께 쓴다면 두 기기 모두 설정해 주세요. 애플워치에서 끝낸 측정은 페어링된 아이폰의 설정을 따라요.")
|
||||
Text("측정이 설정한 시간을 넘기면 알려줘요 — 끄는 걸 잊었을 때 유용해요. 이 알림 설정은 기기마다 따로 저장돼요.")
|
||||
}
|
||||
.id("measureSection")
|
||||
Section {
|
||||
Picker("대표 시간 기준", selection: $liveActivityMode) {
|
||||
ForEach(LiveActivityMode.allCases) { mode in
|
||||
|
||||
@ -4,16 +4,19 @@
|
||||
• 일기를 이제 맥에서도 — 사이드바에 일기 탭이 열리고, 텍스트 입력과 함께 '그리기'를 켜면 마우스·트랙패드로도 그릴 수 있어요
|
||||
• CSV 가져오기(프리미엄) — 내보냈던 CSV에서 행동과 시간·횟수 기록을 복원해요. 기존 데이터는 바꾸지 않고, 이미 있는 기록은 자동으로 건너뛰어요
|
||||
• 일기 기본 표시 설정 — 캘린더 일정을 기본으로 넣을지, 어떤 목표·행동을 기본으로 숨길지 한 번만 정하면 모든 날짜에 적용돼요. 날짜별로 다르게 고르는 것도 그대로예요
|
||||
• '짧은 기록 무시' 설정이 이제 iCloud로 모든 기기에서 동일하게 적용돼요 — 한 기기에서 시작하고 다른 기기에서 끝내도 같은 기준으로 판단해요
|
||||
• 도움말과 안내 문구를 다듬었어요
|
||||
|
||||
[en]
|
||||
• Diary on Mac — the Diary tab now appears in the sidebar; type as usual, or turn on 'Draw' to sketch with your mouse or trackpad
|
||||
• CSV import (Premium) — restore actions and time/count records from exported CSVs. Existing data is never changed, and duplicates are skipped automatically
|
||||
• Diary default display settings — decide once whether calendar events appear by default and which goals or actions stay hidden, and it applies to every date. Per-date choices still work as before
|
||||
• 'Ignore short records' now syncs over iCloud and applies equally on every device — start on one device and stop on another with the same rule
|
||||
• Polished help topics and descriptions
|
||||
|
||||
[ja]
|
||||
• Macでも日記が使えるように — サイドバーに日記タブが追加され、テキスト入力に加えて「描く」をオンにするとマウス・トラックパッドで描けます
|
||||
• CSV読み込み(プレミアム)— 書き出したCSVからアクションと時間・回数記録を復元。既存データは変更せず、重複は自動でスキップします
|
||||
• 日記のデフォルト表示設定 — カレンダーの予定をデフォルトで入れるか、どの目標・アクションをデフォルトで隠すかを一度決めれば、すべての日付に適用されます。日付ごとの選択もこれまでどおり使えます
|
||||
• 「短い記録を無視」の設定がiCloudですべてのデバイスに同じく適用されるように — あるデバイスで開始して別のデバイスで終了しても同じ基準で判定します
|
||||
• ヘルプと説明文を改善しました
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user