앱 수정

This commit is contained in:
Macbook
2026-05-28 15:37:02 +09:00
parent 3503ef33f5
commit f64dc1e983
21 changed files with 1434 additions and 755 deletions
+63 -36
View File
@@ -1,14 +1,16 @@
import React, { lazy, Suspense, useCallback, useEffect, useState } from 'react';
import React, { lazy, Suspense, useEffect, useState } from 'react';
import { Capacitor } from '@capacitor/core';
import { StatusBar, Style } from '@capacitor/status-bar';
import { SplashScreen } from '@capacitor/splash-screen';
import { initStorage } from './lib/shared';
import { SplashScreen as CapSplashScreen } from '@capacitor/splash-screen';
import { AuthProvider, useAuth } from './contexts/AuthContext';
import { NavigationProvider, useNavigation } from './contexts/NavigationContext';
import { TradeNotificationProvider, useTradeNotification } from './contexts/TradeNotificationContext';
import { useAppSettings, resolveAppDefaults } from './hooks/useAppSettings';
import TabBar, { type TabId } from './components/TabBar';
import { initFcmPush, type FcmPayload } from './services/fcm';
import LiveSignalBridge from './components/LiveSignalBridge';
import LoginScreen from './screens/LoginScreen';
import '@frontend/styles/splashScreen.css';
import './theme/global.css';
const VirtualTradingScreen = lazy(() => import('./screens/virtual/VirtualTradingScreen'));
@@ -33,35 +35,21 @@ function ToastStack() {
);
}
function AppInner() {
const { tab, setTab, openVirtualFocus } = useNavigation();
function MainApp() {
const { tab, setTab, openVirtualFocus, goVirtualList, goNotifyList } = useNavigation();
const { addNotification, refreshHistory, unreadCount } = useTradeNotification();
const { settings, isLoaded } = useAppSettings();
const { sessionKey } = useAuth();
const { settings, isLoaded } = useAppSettings(sessionKey);
const defaults = resolveAppDefaults(settings);
const [ready, setReady] = useState(false);
useEffect(() => {
void (async () => {
await initStorage();
if (Capacitor.isNativePlatform()) {
try {
await StatusBar.setStyle({ style: Style.Dark });
await StatusBar.setBackgroundColor({ color: '#0f0f23' });
await SplashScreen.hide();
} catch { /* web */ }
}
setReady(true);
})();
}, []);
useEffect(() => {
if (!isLoaded || !defaults.fcmPushEnabled) return;
void initFcmPush({
onForeground: (title, body, data) => {
onForeground: (_title, _body, data) => {
if (data?.market && data?.signalType) {
addNotification({
market: data.market,
signalType: data.signalType,
signalType: data.signalType === 'SELL' ? 'SELL' : 'BUY',
price: Number(data.price) || 0,
candleTime: Math.floor(Date.now() / 1000),
dbId: data.signalId ? Number(data.signalId) : undefined,
@@ -85,9 +73,10 @@ function AppInner() {
document.documentElement.setAttribute('data-theme', defaults.theme ?? 'dark');
}, [defaults.theme]);
if (!ready) {
return <div className="loading-center">GoldenChart</div>;
}
useEffect(() => {
if (tab === 'virtual') goNotifyList();
else if (tab === 'notifications') goVirtualList();
}, [tab, goVirtualList, goNotifyList]);
const screens: Record<TabId, React.ReactNode> = {
virtual: <VirtualTradingScreen />,
@@ -105,21 +94,59 @@ function AppInner() {
{screens[tab]}
</Suspense>
</main>
<TabBar
active={tab}
onChange={setTab}
unreadCount={unreadCount}
/>
<TabBar active={tab} onChange={setTab} unreadCount={unreadCount} />
</div>
);
}
function AppRoot() {
const {
authReady,
isAppEntered,
handleLoginSuccess,
handleGuestEnter,
} = useAuth();
const [nativeReady, setNativeReady] = useState(false);
useEffect(() => {
void (async () => {
if (Capacitor.isNativePlatform()) {
try {
await StatusBar.setStyle({ style: Style.Dark });
await StatusBar.setBackgroundColor({ color: '#0f0f23' });
await CapSplashScreen.hide();
} catch { /* web dev */ }
}
setNativeReady(true);
})();
}, []);
if (!authReady || !nativeReady) {
return <div className="loading-center">GoldenChart</div>;
}
if (!isAppEntered) {
return (
<LoginScreen
onLoginSuccess={handleLoginSuccess}
onGuest={handleGuestEnter}
/>
);
}
return (
<NavigationProvider>
<TradeNotificationProvider soundEnabled popupEnabled={false}>
<MainApp />
</TradeNotificationProvider>
</NavigationProvider>
);
}
export default function App() {
return (
<NavigationProvider>
<TradeNotificationProvider soundEnabled={true}>
<AppInner />
</TradeNotificationProvider>
</NavigationProvider>
<AuthProvider>
<AppRoot />
</AuthProvider>
);
}