v0.1.13 - 로컬·클라우드 데이터 분리
This commit is contained in:
41
src/App.vue
41
src/App.vue
@@ -16,6 +16,7 @@ import { fetchPlannerEntries, savePlannerEntry } from './lib/plannerApi'
|
||||
import {
|
||||
createInitialPlannerRecords,
|
||||
persistPlannerState,
|
||||
readPlannerStorageState,
|
||||
restorePlannerUiState,
|
||||
} from './lib/plannerStorage'
|
||||
|
||||
@@ -557,6 +558,7 @@ watch(
|
||||
calendarViewDate: calendarViewDate.value,
|
||||
statsRangeStart: normalizedStatsRange.value.startKey,
|
||||
statsRangeEnd: normalizedStatsRange.value.endKey,
|
||||
includeRecords: !isAuthenticated.value,
|
||||
})
|
||||
},
|
||||
{ deep: true },
|
||||
@@ -607,7 +609,6 @@ async function applyAuthSuccess(data) {
|
||||
user: data.user,
|
||||
})
|
||||
await hydratePlannerRecordsFromApi()
|
||||
queueSyncAllPlannerRecords()
|
||||
closeAuthDialog()
|
||||
}
|
||||
|
||||
@@ -672,6 +673,31 @@ function logout() {
|
||||
syncStatus.value = 'local'
|
||||
syncMessage.value = '로컬 저장 모드'
|
||||
clearAuthState()
|
||||
restoreLocalPlannerRecords()
|
||||
}
|
||||
|
||||
function replacePlannerRecords(nextRecords) {
|
||||
Object.keys(plannerRecords).forEach((key) => {
|
||||
delete plannerRecords[key]
|
||||
})
|
||||
|
||||
Object.entries(nextRecords).forEach(([key, record]) => {
|
||||
plannerRecords[key] = record
|
||||
})
|
||||
}
|
||||
|
||||
function restoreLocalPlannerRecords() {
|
||||
replacePlannerRecords(createInitialPlannerRecords(plannerSeed, normalizeRecord))
|
||||
|
||||
const savedState = readPlannerStorageState()
|
||||
|
||||
if (savedState.selectedDate) {
|
||||
selectedDate.value = toDateValue(savedState.selectedDate, selectedDate.value)
|
||||
}
|
||||
|
||||
if (savedState.calendarViewDate) {
|
||||
calendarViewDate.value = toDateValue(savedState.calendarViewDate, selectedDate.value)
|
||||
}
|
||||
}
|
||||
|
||||
function findRecordKey(record) {
|
||||
@@ -685,14 +711,6 @@ function clearPendingSyncTimers() {
|
||||
syncTimers.clear()
|
||||
}
|
||||
|
||||
function queueSyncAllPlannerRecords() {
|
||||
Object.entries(plannerRecords).forEach(([key, record]) => {
|
||||
if (hasPlannerContent(record)) {
|
||||
schedulePlannerSync(key)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function schedulePlannerSyncForRecord(record) {
|
||||
const recordKey = findRecordKey(record)
|
||||
|
||||
@@ -760,11 +778,14 @@ async function hydratePlannerRecordsFromApi() {
|
||||
|
||||
try {
|
||||
const result = await fetchPlannerEntries(authToken.value)
|
||||
const remoteRecords = {}
|
||||
|
||||
result.entries.forEach((entry) => {
|
||||
plannerRecords[entry.entryDate] = normalizeRecord(entry.payload)
|
||||
remoteRecords[entry.entryDate] = normalizeRecord(entry.payload)
|
||||
})
|
||||
|
||||
replacePlannerRecords(remoteRecords)
|
||||
|
||||
syncStatus.value = 'cloud'
|
||||
syncMessage.value = '클라우드 동기화 연결됨'
|
||||
} catch (error) {
|
||||
|
||||
@@ -13,6 +13,10 @@ function readStorageState() {
|
||||
}
|
||||
}
|
||||
|
||||
export function readPlannerStorageState() {
|
||||
return readStorageState()
|
||||
}
|
||||
|
||||
export function createInitialPlannerRecords(seedRecords, normalizeRecord) {
|
||||
const baseRecords = Object.fromEntries(
|
||||
Object.entries(seedRecords).map(([key, record]) => [key, normalizeRecord(record)]),
|
||||
@@ -62,31 +66,37 @@ export function persistPlannerState({
|
||||
calendarViewDate,
|
||||
statsRangeStart,
|
||||
statsRangeEnd,
|
||||
includeRecords = true,
|
||||
}) {
|
||||
if (typeof window === 'undefined') {
|
||||
return
|
||||
}
|
||||
|
||||
const serializableRecords = Object.fromEntries(
|
||||
Object.entries(plannerRecords).map(([key, record]) => [
|
||||
key,
|
||||
{
|
||||
...record,
|
||||
tasks: record.tasks.map((task) => ({ ...task })),
|
||||
memo: record.memo.map((item) => ({ ...item })),
|
||||
timetable: [...record.timetable],
|
||||
},
|
||||
]),
|
||||
)
|
||||
const previousState = readStorageState()
|
||||
const nextState = {
|
||||
...previousState,
|
||||
selectedDate: selectedDate.toISOString(),
|
||||
calendarViewDate: calendarViewDate.toISOString(),
|
||||
statsRangeStart,
|
||||
statsRangeEnd,
|
||||
}
|
||||
|
||||
if (includeRecords) {
|
||||
nextState.records = Object.fromEntries(
|
||||
Object.entries(plannerRecords).map(([key, record]) => [
|
||||
key,
|
||||
{
|
||||
...record,
|
||||
tasks: record.tasks.map((task) => ({ ...task })),
|
||||
memo: record.memo.map((item) => ({ ...item })),
|
||||
timetable: [...record.timetable],
|
||||
},
|
||||
]),
|
||||
)
|
||||
}
|
||||
|
||||
window.localStorage.setItem(
|
||||
STORAGE_KEY,
|
||||
JSON.stringify({
|
||||
selectedDate: selectedDate.toISOString(),
|
||||
calendarViewDate: calendarViewDate.toISOString(),
|
||||
statsRangeStart,
|
||||
statsRangeEnd,
|
||||
records: serializableRecords,
|
||||
}),
|
||||
JSON.stringify(nextState),
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user