import { showMessage, hideMessage } from 'react-native-flash-message'; import { View, TouchableOpacity, ActivityIndicator, Image } from 'react-native'; import Text from './text'; import TextButton from './text-button'; import { ErrorSymbolIcon } from './icons/error-symbol'; import { ClearSymbolIcon } from './icons/clear-symbol'; import Spinner from './spinner'; import React from 'react'; type SnackBarVariant = 'default' | 'danger' | 'success' | 'thumbnail'; interface SnackBarProps { message?: string; variant?: 'default' | 'danger' | 'success' | 'thumbnail'; loading?: boolean; buttonText?: string; duration?: number; styleTheme?: 'dark' | 'white'; rightTextButton?: boolean; thumbnailProps?: { imageUrl?: string; title: string; description: string; }; className?: string; } // 스타일 및 아이콘 설정 const getVariantStyles = (variant: SnackBarVariant) => { switch (variant) { case 'success': return { backgroundColor: 'bg-emerald-50', textColor: 'emerald-700', icon: 'check-circle', }; case 'danger': return { backgroundColor: 'bg-red-50', textColor: 'red-700', icon: 'error', }; default: return { backgroundColor: 'bg-gray-50', textColor: 'gray-700', icon: 'info', }; } }; // App.tsx에서 사용할 스타일 설정 export const flashMessageStyle = { backgroundColor: 'transparent', padding: 0, margin: 0, width: 'auto', }; const CustomSnackBarContent = ({ message, variant = 'default', loading = false, buttonText = '확인', styleTheme = 'dark', rightTextButton = false, thumbnailProps, className, }: Omit) => { const styles = getVariantStyles(variant); const renderIcon = () => { if (loading) { return ( ); } switch (variant) { case 'danger': return ; case 'success': return ; default: return null; } }; if (variant === 'thumbnail' && thumbnailProps) { return ( {thumbnailProps.title} {thumbnailProps.description} {rightTextButton && ( hideMessage()} size="medium" /> )} ); } return ( {renderIcon()} {message} {rightTextButton && ( hideMessage()} size="medium" /> )} ); }; // 현재 스낵바 상태 관리 변수 let isSnackBarVisible = false; let currentSnackBarId: number | null = null; let isSwitchingSnackBar = false; const showSnackBar = ({ message, variant = 'default', loading = false, buttonText = '확인', duration = loading ? 0 : 3000, rightTextButton = false, styleTheme = 'dark', thumbnailProps, className, }: SnackBarProps) => { // 이미 전환 중이면 무시 if (isSwitchingSnackBar) return; // 전환 중 상태로 설정 isSwitchingSnackBar = true; const displayNewSnackBar = () => { // 상태 업데이트 isSnackBarVisible = true; currentSnackBarId = Date.now(); isSwitchingSnackBar = false; // 스낵바 설정 const commonConfig = { message: '', duration: duration, backgroundColor: 'transparent', hideStatusBar: false, autoHide: !loading, hideOnPress: !loading, animated: true, animationDuration: 150, renderCustomContent: () => ( ), onPress: loading ? () => {} : () => hideMessage(), onHide: () => { isSnackBarVisible = false; currentSnackBarId = null; }, }; showMessage(commonConfig); }; if (isSnackBarVisible) { hideMessage(); // 기존 스낵바가 완전히 사라질 시간을 더 충분히 확보 setTimeout(displayNewSnackBar, 250); } else { displayNewSnackBar(); } }; // 스낵바 상태를 업데이트하는 함수 export const updateSnackBar = (props: SnackBarProps) => { showSnackBar(props); }; // 스낵바를 명시적으로 닫는 함수 export const closeSnackBar = () => { if (isSnackBarVisible) { hideMessage(); isSnackBarVisible = false; currentSnackBarId = null; isSwitchingSnackBar = false; } }; // 로딩 중인 스낵바만 즉시 닫는 함수 export const dismissLoadingSnackBar = () => { if (isSnackBarVisible) { hideMessage(); isSnackBarVisible = false; currentSnackBarId = null; isSwitchingSnackBar = false; } }; export default showSnackBar;