refactor: 항해일지 작성 모달로 변경 및 꾹 눌러서 종료
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
import { getCurrentVoyage, getPreferences, saveCurrentVoyage } from '@/shared/lib/store';
|
||||
import { getCurrentVoyage, saveCurrentVoyage } from '@/shared/lib/store';
|
||||
import { Voyage } from '@/shared/types';
|
||||
|
||||
const getVoyageFromStore = () => {
|
||||
@@ -17,18 +17,38 @@ const getEndTime = (voyage: Voyage | null) => {
|
||||
return voyage.startedAt + voyage.durationMinutes * 60 * 1000;
|
||||
};
|
||||
|
||||
const getInitialTimerSeconds = (voyage: Voyage | null) => {
|
||||
if (!voyage) return 0;
|
||||
|
||||
if (voyage.durationMinutes === 0) {
|
||||
return Math.max(0, Math.floor((Date.now() - voyage.startedAt) / 1000));
|
||||
}
|
||||
|
||||
const endTime = getEndTime(voyage);
|
||||
if (!endTime) return 0;
|
||||
return Math.max(0, Math.ceil((endTime - Date.now()) / 1000));
|
||||
};
|
||||
|
||||
const formatHHMMSS = (totalSeconds: number) => {
|
||||
const hours = Math.floor(totalSeconds / 3600);
|
||||
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||
const seconds = totalSeconds % 60;
|
||||
|
||||
return `${hours.toString().padStart(2, '0')}:${minutes
|
||||
.toString()
|
||||
.padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
export function useFlightSession() {
|
||||
const router = useRouter();
|
||||
const [voyage] = useState<Voyage | null>(() => getVoyageFromStore());
|
||||
const [timeLeft, setTimeLeft] = useState<number>(() => {
|
||||
const current = getVoyageFromStore();
|
||||
const endTime = getEndTime(current);
|
||||
if (!endTime) return 0;
|
||||
return Math.max(0, Math.ceil((endTime - Date.now()) / 1000));
|
||||
});
|
||||
const [timeLeft, setTimeLeft] = useState<number>(() =>
|
||||
getInitialTimerSeconds(getVoyageFromStore()),
|
||||
);
|
||||
const [isPaused, setIsPaused] = useState(false);
|
||||
const [hideSeconds] = useState(() => getPreferences().hideSeconds);
|
||||
const endTimeRef = useRef<number>(getEndTime(getVoyageFromStore()));
|
||||
const pausedElapsedMsRef = useRef<number>(0);
|
||||
const pausedAtMsRef = useRef<number | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (voyage) return;
|
||||
@@ -40,6 +60,12 @@ export function useFlightSession() {
|
||||
if (!voyage || isPaused) return;
|
||||
|
||||
const interval = setInterval(() => {
|
||||
if (voyage.durationMinutes === 0) {
|
||||
const elapsedMs = Date.now() - voyage.startedAt - pausedElapsedMsRef.current;
|
||||
setTimeLeft(Math.max(0, Math.floor(elapsedMs / 1000)));
|
||||
return;
|
||||
}
|
||||
|
||||
const diff = endTimeRef.current - Date.now();
|
||||
|
||||
if (diff <= 0) {
|
||||
@@ -55,6 +81,21 @@ export function useFlightSession() {
|
||||
}, [voyage, isPaused]);
|
||||
|
||||
const handlePauseToggle = () => {
|
||||
if (voyage?.durationMinutes === 0) {
|
||||
if (isPaused) {
|
||||
if (pausedAtMsRef.current !== null) {
|
||||
pausedElapsedMsRef.current += Date.now() - pausedAtMsRef.current;
|
||||
}
|
||||
pausedAtMsRef.current = null;
|
||||
setIsPaused(false);
|
||||
return;
|
||||
}
|
||||
|
||||
pausedAtMsRef.current = Date.now();
|
||||
setIsPaused(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPaused) {
|
||||
endTimeRef.current = Date.now() + timeLeft * 1000;
|
||||
setIsPaused(false);
|
||||
@@ -65,33 +106,23 @@ export function useFlightSession() {
|
||||
};
|
||||
|
||||
const handleFinish = () => {
|
||||
if (!voyage) return;
|
||||
if (!voyage) return null;
|
||||
|
||||
const endedVoyage: Voyage = {
|
||||
...voyage,
|
||||
endedAt: Date.now(),
|
||||
endedAt: voyage.endedAt || Date.now(),
|
||||
};
|
||||
|
||||
saveCurrentVoyage(endedVoyage);
|
||||
router.push('/debrief');
|
||||
return endedVoyage;
|
||||
};
|
||||
|
||||
const formatTime = (seconds: number) => {
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const remainingSeconds = seconds % 60;
|
||||
|
||||
if (hideSeconds) {
|
||||
return `${minutes}m`;
|
||||
}
|
||||
|
||||
return `${minutes.toString().padStart(2, '0')}:${remainingSeconds
|
||||
.toString()
|
||||
.padStart(2, '0')}`;
|
||||
};
|
||||
const formatTime = (seconds: number) => formatHHMMSS(seconds);
|
||||
|
||||
return {
|
||||
voyage,
|
||||
timeLeft,
|
||||
isCountdownCompleted: Boolean(voyage && voyage.durationMinutes > 0 && timeLeft === 0),
|
||||
isPaused,
|
||||
formattedTime: formatTime(timeLeft),
|
||||
handlePauseToggle,
|
||||
|
||||
Reference in New Issue
Block a user