Fix toast and sync settings
- Fix issue where toast notifications were not disappearing. - Ensure sync settings are turned off upon logout.
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { Switch } from "@/components/ui/switch";
|
import { Switch } from "@/components/ui/switch";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
@@ -16,21 +17,41 @@ const SyncSettings = () => {
|
|||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
// 사용자 로그인 상태 변경 감지
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 마지막 동기화 시간 업데이트
|
// 사용자 로그인 상태에 따라 동기화 설정 업데이트
|
||||||
setLastSync(getLastSyncTime());
|
const updateSyncState = () => {
|
||||||
|
if (!user && isSyncEnabled()) {
|
||||||
// 세션 상태 변경 감지
|
// 사용자가 로그아웃했고 동기화가 활성화되어 있으면 비활성화
|
||||||
const handleAuthChange = () => {
|
setSyncEnabled(false);
|
||||||
|
setEnabled(false);
|
||||||
|
setLastSync(null);
|
||||||
|
console.log('로그아웃으로 인해 동기화 설정이 비활성화되었습니다.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 동기화 상태 업데이트
|
||||||
setEnabled(isSyncEnabled());
|
setEnabled(isSyncEnabled());
|
||||||
setLastSync(getLastSyncTime());
|
setLastSync(getLastSyncTime());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 초기 호출
|
||||||
|
updateSyncState();
|
||||||
|
|
||||||
window.addEventListener('auth-state-changed', handleAuthChange);
|
// 인증 상태 변경 이벤트 리스너
|
||||||
|
window.addEventListener('auth-state-changed', updateSyncState);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('auth-state-changed', handleAuthChange);
|
window.removeEventListener('auth-state-changed', updateSyncState);
|
||||||
};
|
};
|
||||||
|
}, [user]);
|
||||||
|
|
||||||
|
// 마지막 동기화 시간 정기적으로 업데이트
|
||||||
|
useEffect(() => {
|
||||||
|
const intervalId = setInterval(() => {
|
||||||
|
setLastSync(getLastSyncTime());
|
||||||
|
}, 10000); // 10초마다 업데이트
|
||||||
|
|
||||||
|
return () => clearInterval(intervalId);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleSyncToggle = async (checked: boolean) => {
|
const handleSyncToggle = async (checked: boolean) => {
|
||||||
@@ -171,6 +192,7 @@ const SyncSettings = () => {
|
|||||||
checked={enabled}
|
checked={enabled}
|
||||||
onCheckedChange={handleSyncToggle}
|
onCheckedChange={handleSyncToggle}
|
||||||
className="data-[state=checked]:bg-neuro-income"
|
className="data-[state=checked]:bg-neuro-income"
|
||||||
|
disabled={!user && enabled} // 사용자가 로그아웃 상태이면서 동기화가 켜져있을 때 비활성화
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Session, User } from '@supabase/supabase-js';
|
|||||||
import { toast } from '@/hooks/useToast.wrapper';
|
import { toast } from '@/hooks/useToast.wrapper';
|
||||||
import { AuthContextType } from './types';
|
import { AuthContextType } from './types';
|
||||||
import * as authActions from './authActions';
|
import * as authActions from './authActions';
|
||||||
|
import { clearAllToasts } from '@/hooks/toast/toastManager';
|
||||||
|
|
||||||
const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
||||||
|
|
||||||
@@ -45,6 +46,12 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
|||||||
} else if (event === 'SIGNED_OUT') {
|
} else if (event === 'SIGNED_OUT') {
|
||||||
setSession(null);
|
setSession(null);
|
||||||
setUser(null);
|
setUser(null);
|
||||||
|
|
||||||
|
// 로그아웃 시 열려있는 모든 토스트 제거
|
||||||
|
clearAllToasts();
|
||||||
|
|
||||||
|
// 로그아웃 이벤트 발생시켜 SyncSettings 등에서 감지하도록 함
|
||||||
|
window.dispatchEvent(new Event('auth-state-changed'));
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
|
|
||||||
export const TOAST_LIMIT = 5 // 최대 5개로 제한
|
export const TOAST_LIMIT = 5 // 최대 5개로 제한
|
||||||
export const TOAST_REMOVE_DELAY = 5000 // 5초 후 DOM에서 제거
|
export const TOAST_REMOVE_DELAY = 3000 // 3초 후 DOM에서 제거 (5초에서 3초로 변경)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ function toast({ ...props }: Toast) {
|
|||||||
onOpenChange: (open) => {
|
onOpenChange: (open) => {
|
||||||
if (!open) dismiss()
|
if (!open) dismiss()
|
||||||
},
|
},
|
||||||
duration: props.duration || 3000, // 기본 지속 시간 3초로 단축
|
duration: props.duration || 3000, // 기본 지속 시간 3초로 설정
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ export const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()
|
|||||||
// 토스트 자동 제거 함수
|
// 토스트 자동 제거 함수
|
||||||
export const addToRemoveQueue = (toastId: string) => {
|
export const addToRemoveQueue = (toastId: string) => {
|
||||||
if (toastTimeouts.has(toastId)) {
|
if (toastTimeouts.has(toastId)) {
|
||||||
return
|
// 이미 존재하는 타이머가 있다면 제거 후 새로 설정
|
||||||
|
clearTimeout(toastTimeouts.get(toastId)!);
|
||||||
|
toastTimeouts.delete(toastId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
@@ -26,6 +28,10 @@ export const addToRemoveQueue = (toastId: string) => {
|
|||||||
export const reducer = (state: State, action: Action): State => {
|
export const reducer = (state: State, action: Action): State => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case actionTypes.ADD_TOAST:
|
case actionTypes.ADD_TOAST:
|
||||||
|
// 토스트 추가 시 자동 제거 타이머 설정
|
||||||
|
if (action.toast.id) {
|
||||||
|
addToRemoveQueue(action.toast.id);
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
|
toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
|
||||||
|
|||||||
@@ -47,11 +47,26 @@ export function dispatch(action: Action) {
|
|||||||
time: now
|
time: now
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// REMOVE_TOAST 액션 우선순위 높임
|
||||||
|
if (action.type === actionTypes.REMOVE_TOAST) {
|
||||||
|
// 즉시 처리
|
||||||
|
memoryState = reducer(memoryState, action);
|
||||||
|
listeners.forEach((listener) => {
|
||||||
|
listener(memoryState);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 실제 상태 업데이트 및 리스너 호출
|
// 실제 상태 업데이트 및 리스너 호출
|
||||||
memoryState = reducer(memoryState, action)
|
memoryState = reducer(memoryState, action);
|
||||||
listeners.forEach((listener) => {
|
listeners.forEach((listener) => {
|
||||||
listener(memoryState)
|
listener(memoryState);
|
||||||
})
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 토스트 모두 제거 헬퍼 함수
|
||||||
|
export function clearAllToasts() {
|
||||||
|
dispatch({ type: actionTypes.REMOVE_TOAST });
|
||||||
}
|
}
|
||||||
|
|
||||||
export { memoryState };
|
export { memoryState };
|
||||||
|
|||||||
Reference in New Issue
Block a user