diff --git a/src/hooks/sync/syncTime/index.ts b/src/hooks/sync/syncTime/index.ts new file mode 100644 index 0000000..abfa664 --- /dev/null +++ b/src/hooks/sync/syncTime/index.ts @@ -0,0 +1,3 @@ + +export * from './useSyncTimeFormatting'; +export * from './useSyncTimeEvents'; diff --git a/src/hooks/sync/syncTime/useSyncTimeEvents.ts b/src/hooks/sync/syncTime/useSyncTimeEvents.ts new file mode 100644 index 0000000..2fb60cd --- /dev/null +++ b/src/hooks/sync/syncTime/useSyncTimeEvents.ts @@ -0,0 +1,74 @@ + +import { useCallback } from 'react'; +import { getLastSyncTime } from '@/utils/syncUtils'; + +/** + * 동기화 시간 관련 이벤트를 처리하는 커스텀 훅 + */ +export const useSyncTimeEvents = ( + lastSync: string | null, + setLastSync: React.Dispatch> +) => { + /** + * 동기화 시간 이벤트 리스너 설정 + */ + const setupSyncTimeEventListeners = useCallback(() => { + const updateLastSyncTime = (event?: Event | CustomEvent) => { + const newTime = getLastSyncTime(); + const eventDetails = event instanceof CustomEvent ? ` (이벤트 상세: ${JSON.stringify(event.detail)})` : ''; + console.log(`마지막 동기화 시간 업데이트됨: ${newTime} ${eventDetails}`); + setLastSync(newTime); + }; + + // 이벤트 리스너 등록 - 커스텀 이벤트 사용 + window.addEventListener('syncTimeUpdated', updateLastSyncTime); + + // 스토리지 이벤트도 모니터링 + const handleStorageChange = (event: StorageEvent) => { + if (event.key === 'lastSync' || event.key === null) { + console.log('스토리지 변경 감지 (lastSync):', event.newValue); + updateLastSyncTime(); + } + }; + + window.addEventListener('storage', handleStorageChange); + + // 동기화 완료 이벤트도 모니터링 + window.addEventListener('syncComplete', updateLastSyncTime); + + // 초기 상태 업데이트 + updateLastSyncTime(); + + // 주기적 시간 확인 기능 설정 + const checkInterval = setupPeriodicTimeCheck(lastSync, setLastSync); + + // 정리 함수 반환 + return () => { + window.removeEventListener('syncTimeUpdated', updateLastSyncTime); + window.removeEventListener('storage', handleStorageChange); + window.removeEventListener('syncComplete', updateLastSyncTime); + clearInterval(checkInterval); + }; + }, [lastSync, setLastSync]); + + return { + setupSyncTimeEventListeners + }; +}; + +/** + * 주기적으로 동기화 시간을 확인하는 기능 설정 + */ +const setupPeriodicTimeCheck = ( + lastSync: string | null, + setLastSync: React.Dispatch> +): number => { + // 1초마다 업데이트 상태 확인 (문제 해결을 위한 임시 방안) + return window.setInterval(() => { + const currentTime = getLastSyncTime(); + if (currentTime !== lastSync) { + console.log('주기적 확인에서 동기화 시간 변경 감지:', currentTime); + setLastSync(currentTime); + } + }, 1000); +}; diff --git a/src/hooks/sync/syncTime/useSyncTimeFormatting.ts b/src/hooks/sync/syncTime/useSyncTimeFormatting.ts new file mode 100644 index 0000000..d66e8e6 --- /dev/null +++ b/src/hooks/sync/syncTime/useSyncTimeFormatting.ts @@ -0,0 +1,81 @@ + +/** + * 마지막 동기화 시간 포맷팅을 위한 커스텀 훅 + */ +export const useLastSyncTimeFormatting = (lastSync: string | null) => { + /** + * 마지막 동기화 시간을 사용자 친화적 형식으로 포맷팅 + */ + const formatLastSyncTime = (): string => { + if (!lastSync) { + return '없음'; + } + + try { + const date = new Date(lastSync); + + // 유효한 날짜인지 확인 + if (isNaN(date.getTime())) { + return '없음'; + } + + return formatDateByRelativeTime(date); + } catch (error) { + console.error('날짜 포맷 오류:', error); + return '없음'; + } + }; + + return { + formatLastSyncTime + }; +}; + +/** + * 날짜를 상대적 시간(오늘, 어제 등)으로 포맷팅 + */ +const formatDateByRelativeTime = (date: Date): string => { + // 오늘 날짜인 경우 + const today = new Date(); + const isToday = isSameDay(date, today); + + if (isToday) { + // 시간만 표시 + return `오늘 ${formatTime(date)}`; + } + + // 어제 날짜인 경우 + const yesterday = new Date(today); + yesterday.setDate(yesterday.getDate() - 1); + const isYesterday = isSameDay(date, yesterday); + + if (isYesterday) { + return `어제 ${formatTime(date)}`; + } + + // 그 외 날짜 + return `${formatFullDate(date)} ${formatTime(date)}`; +}; + +/** + * 두 날짜가 같은 날인지 확인 + */ +const isSameDay = (date1: Date, date2: Date): boolean => { + return date1.getDate() === date2.getDate() && + date1.getMonth() === date2.getMonth() && + date1.getFullYear() === date2.getFullYear(); +}; + +/** + * 시간을 HH:MM 형식으로 포맷팅 + */ +const formatTime = (date: Date): string => { + return `${date.getHours()}:${String(date.getMinutes()).padStart(2, '0')}`; +}; + +/** + * 전체 날짜를 YYYY/MM/DD 형식으로 포맷팅 + */ +const formatFullDate = (date: Date): string => { + return `${date.getFullYear()}/${String(date.getMonth() + 1).padStart(2, '0')}/${String(date.getDate()).padStart(2, '0')}`; +}; diff --git a/src/hooks/sync/useSyncStatus.ts b/src/hooks/sync/useSyncStatus.ts index 0f09840..af674a1 100644 --- a/src/hooks/sync/useSyncStatus.ts +++ b/src/hooks/sync/useSyncStatus.ts @@ -1,103 +1,26 @@ import { useState, useEffect } from 'react'; import { getLastSyncTime } from '@/utils/syncUtils'; +import { useLastSyncTimeFormatting } from './syncTime/useSyncTimeFormatting'; +import { useSyncTimeEvents } from './syncTime/useSyncTimeEvents'; /** * 동기화 상태 관리를 위한 커스텀 훅 */ export const useSyncStatus = () => { const [lastSync, setLastSync] = useState(getLastSyncTime()); + const { formatLastSyncTime } = useLastSyncTimeFormatting(lastSync); + const { setupSyncTimeEventListeners } = useSyncTimeEvents(lastSync, setLastSync); - // 마지막 동기화 시간 포맷팅 - const formatLastSyncTime = (): string => { - if (!lastSync) { - return '없음'; - } - - try { - const date = new Date(lastSync); - - // 유효한 날짜인지 확인 - if (isNaN(date.getTime())) { - return '없음'; - } - - // 오늘 날짜인 경우 - const today = new Date(); - const isToday = date.getDate() === today.getDate() && - date.getMonth() === today.getMonth() && - date.getFullYear() === today.getFullYear(); - - if (isToday) { - // 시간만 표시 - return `오늘 ${date.getHours()}:${String(date.getMinutes()).padStart(2, '0')}`; - } - - // 어제 날짜인 경우 - const yesterday = new Date(today); - yesterday.setDate(yesterday.getDate() - 1); - const isYesterday = date.getDate() === yesterday.getDate() && - date.getMonth() === yesterday.getMonth() && - date.getFullYear() === yesterday.getFullYear(); - - if (isYesterday) { - return `어제 ${date.getHours()}:${String(date.getMinutes()).padStart(2, '0')}`; - } - - // 그 외 날짜 - return `${date.getFullYear()}/${String(date.getMonth() + 1).padStart(2, '0')}/${String(date.getDate()).padStart(2, '0')} ${date.getHours()}:${String(date.getMinutes()).padStart(2, '0')}`; - } catch (error) { - console.error('날짜 포맷 오류:', error); - return '없음'; - } - }; - - // 동기화 시간이 변경될 때 상태 업데이트 + // 동기화 시간이 변경될 때 상태 업데이트 및 이벤트 리스너 설정 useEffect(() => { console.log('useSyncStatus 훅 초기화, 현재 마지막 동기화 시간:', lastSync); - const updateLastSyncTime = (event?: Event | CustomEvent) => { - const newTime = getLastSyncTime(); - const eventDetails = event instanceof CustomEvent ? ` (이벤트 상세: ${JSON.stringify(event.detail)})` : ''; - console.log(`마지막 동기화 시간 업데이트됨: ${newTime} ${eventDetails}`); - setLastSync(newTime); - }; + // 이벤트 리스너 및 주기적 확인 설정 + const cleanup = setupSyncTimeEventListeners(); - // 이벤트 리스너 등록 - 커스텀 이벤트 사용 - window.addEventListener('syncTimeUpdated', updateLastSyncTime); - - // 스토리지 이벤트도 모니터링 - const handleStorageChange = (event: StorageEvent) => { - if (event.key === 'lastSync' || event.key === null) { - console.log('스토리지 변경 감지 (lastSync):', event.newValue); - updateLastSyncTime(); - } - }; - - window.addEventListener('storage', handleStorageChange); - - // 동기화 완료 이벤트도 모니터링 (새로 추가) - window.addEventListener('syncComplete', updateLastSyncTime); - - // 초기 상태 업데이트 - updateLastSyncTime(); - - // 1초마다 업데이트 상태 확인 (문제 해결을 위한 임시 방안) - const checkInterval = setInterval(() => { - const currentTime = getLastSyncTime(); - if (currentTime !== lastSync) { - console.log('주기적 확인에서 동기화 시간 변경 감지:', currentTime); - setLastSync(currentTime); - } - }, 1000); - - return () => { - window.removeEventListener('syncTimeUpdated', updateLastSyncTime); - window.removeEventListener('storage', handleStorageChange); - window.removeEventListener('syncComplete', updateLastSyncTime); - clearInterval(checkInterval); - }; - }, [lastSync]); + return cleanup; + }, [lastSync, setupSyncTimeEventListeners]); return { lastSync,