fix(diary): clean up empty entries created by merely viewing a day
일기 상세는 진입만 해도 DiaryEntry를 생성(loadEntry)해서, 열람만 한 날짜의 빈 엔트리가 스토어와 CloudKit에 계속 쌓였다. 달력 화면 onAppear에서 완전히 빈 엔트리만 정리한다 (상세에서 달력으로 돌아올 때마다 실행되고, 이 수정 이전에 쌓인 빈 엔트리도 함께 청소됨). 보존 조건을 엄격히 판정: - hasContent(기분·할 일·내용 있는 페이지)는 물론 - 달력 마커에 안 잡히는 캘린더 일정(calendarEventIDs)·타임테이블 필터(hiddenActionIDs) 선택이 있으면 보존 - 아직 내용 없는 노트 페이지를 만들어 둔 날도 보존 (페이지 0개일 때만 삭제) 검증(iPad 시뮬레이터, 스토어 직접 조회): - 열람만 하고 나간 빈 엔트리 → 달력 재진입 시 삭제 (1건 → 0건) - 타임테이블 필터만 설정한 엔트리 → 정리 후에도 보존, 재진입 시 필터 배지(1)와 숨김 상태 유지 확인 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013yKDMhuF39GVYy3FMcGHh7
This commit is contained in:
parent
0aed7a9ec5
commit
a9473be937
@ -182,6 +182,7 @@ xcrun xcstringstool sync IOS/Localizable.xcstrings --stringsdata "${files[@]}"
|
||||
|
||||
### 6.7 일기 탭 (iPad 전용, 프리미엄 — `DiaryView`, `DiaryNotePage`, `DiaryCalendarEvents`, `DiaryExportSheet`)
|
||||
- 루트: 월 달력(작성일에 기분 이모지/연필 마커), 날짜 탭 → 일기 상세. 툴바에서 기간/복수 날짜 내보내기(PDF=페이지별 1장, 이미지=세로 스티치 PNG, 2배율)
|
||||
- 상세는 진입만 해도 엔트리를 생성(loadEntry)하므로, 달력 onAppear가 **완전히 빈 엔트리만 정리**(기분·할일·페이지 없음 + calendarEventIDs·hiddenActionIDs 비어있음 + 페이지 0개 — 캘린더/필터 선택이나 빈 노트 페이지가 있으면 보존)
|
||||
- 상세: 좌우 페이지 넘김. 1페이지=하루 정리 요약, 이후=펜슬 노트, 마지막=페이지 추가 자리
|
||||
- **요약 페이지 섹션** (표시·순서는 "첫 화면 구성" 시트, 전 날짜 공통, standard defaults): 오늘 기분(대형 정사각 타일: 이모지/사진) · 요약 지표 · 이 날의 목표(그날 기준 다짐 현황, 주간/월간은 그날까지 누적) · 오늘 할 일 · 타임테이블 · 기록 상세 · 통계 막대. 화면 720pt 이상이면 타임테이블 좌측 고정 2컬럼
|
||||
- 타임테이블 카드 우상단 버튼: **필터**(그날 기록된 행동만 나열된 팝업에서 표시 선택, 날짜별 저장 `hiddenActionIDs`, 숨긴 개수 노란 배지 — 타임테이블에만 적용, 요약 수치·기록 목록은 전체 유지) + **캘린더**(그날의 EKEvent 선택, 날짜별 저장, 외곽선 스타일 블록). 둘 다 내보내기에 동일 반영
|
||||
|
||||
@ -90,6 +90,9 @@ struct DiaryRootView: View {
|
||||
DiaryExportSheet()
|
||||
}
|
||||
.onAppear {
|
||||
// 일기 상세는 진입만 해도 엔트리를 만들므로(loadEntry), 달력으로 돌아올 때
|
||||
// 아무 흔적도 남기지 않은 빈 엔트리를 정리한다 (CloudKit에 빈 레코드 누적 방지)
|
||||
cleanupEmptyEntries()
|
||||
#if DEBUG
|
||||
if UserDefaults.standard.bool(forKey: "diaryShowExport") {
|
||||
showingExport = true
|
||||
@ -98,6 +101,22 @@ struct DiaryRootView: View {
|
||||
}
|
||||
}
|
||||
|
||||
/// 완전히 빈 엔트리만 삭제. hasContent(기분·할 일·내용 있는 페이지)뿐 아니라
|
||||
/// 달력 마커에는 안 잡혀도 사용자에게 의미 있는 캘린더 일정·타임테이블 필터 선택이
|
||||
/// 있으면 보존하고, (아직 내용 없는) 노트 페이지를 만들어 둔 날도 보존한다.
|
||||
private func cleanupEmptyEntries() {
|
||||
var changed = false
|
||||
for entry in diaryEntries
|
||||
where !entry.hasContent
|
||||
&& entry.calendarEventIDs.isEmpty
|
||||
&& entry.hiddenActionIDs.isEmpty
|
||||
&& (entry.pagesStorage ?? []).isEmpty {
|
||||
context.delete(entry)
|
||||
changed = true
|
||||
}
|
||||
if changed { try? context.save() }
|
||||
}
|
||||
|
||||
/// 작성된 일기(내용 있는 것만)를 하루 키로 색인
|
||||
private var entriesByDay: [Date: DiaryEntry] {
|
||||
var result: [Date: DiaryEntry] = [:]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user