pc 프로그램 다운로드 기능 적용

This commit is contained in:
Macbook
2026-06-14 10:25:22 +09:00
parent 86b99d8c10
commit 92f67580e3
25 changed files with 1031 additions and 125 deletions
+50 -14
View File
@@ -4,11 +4,13 @@
* 레이아웃:
* [로고] | [대시보드] [실시간차트] [전략편집기] … | [테마토글] [로그인]
*/
import React, { memo, useEffect, useState } from 'react';
import React, { memo, useCallback, useEffect, useState } from 'react';
import type { Theme } from '../types';
import type { AuthSession } from '../utils/auth';
import type { TradeAlertPopupLayout, TradeAlertPopupPosition } from '../utils/tradeAlertPopupLayout';
import { canAccessMenu } from '../utils/permissions';
import { isDesktop } from '../utils/platform';
import { checkDesktopUpdates } from '../utils/desktopBridge';
export type MenuPage = 'dashboard' | 'chart' | 'paper' | 'virtual' | 'trend-search' | 'verification-board' | 'strategy' | 'strategy-editor' | 'strategy-evaluation' | 'backtest' | 'analysis-report' | 'notifications' | 'settings' | 'widget-dashboard';
@@ -105,6 +107,13 @@ const IcAppDownload = () => (
</svg>
);
const IcDesktopUpdate = () => (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M13.5 8a5.5 5.5 0 1 1-1.6-3.9"/>
<polyline points="13.5,2.5 13.5,5.5 10.5,5.5"/>
</svg>
);
const IcNotify = () => (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M8 1.5a4.5 4.5 0 0 0-4.5 4.5c0 3.5-1 4.5-1.5 4.5h12c-.5 0-1.5-1-1.5-4.5A4.5 4.5 0 0 0 8 1.5z"/>
@@ -257,6 +266,24 @@ export const TopMenuBar = memo(function TopMenuBar({
menuPermissions,
}: TopMenuBarProps) {
const [isFullscreen, setIsFullscreen] = useState(() => !!document.fullscreenElement);
const [desktopUpdateBusy, setDesktopUpdateBusy] = useState(false);
const [desktopUpdateHint, setDesktopUpdateHint] = useState('');
const desktopClient = isDesktop();
const handleDesktopUpdate = useCallback(async () => {
if (desktopUpdateBusy) return;
setDesktopUpdateBusy(true);
setDesktopUpdateHint('업데이트 확인 중…');
try {
const res = await checkDesktopUpdates();
setDesktopUpdateHint(res.message ?? (res.available ? `v${res.version ?? ''} 설치` : '최신 버전'));
} catch {
setDesktopUpdateHint('업데이트 확인 실패');
} finally {
setDesktopUpdateBusy(false);
}
}, [desktopUpdateBusy]);
useEffect(() => {
const sync = () => setIsFullscreen(!!document.fullscreenElement);
document.addEventListener('fullscreenchange', sync);
@@ -326,19 +353,28 @@ export const TopMenuBar = memo(function TopMenuBar({
</div>
)}
{onOpenAppDownload && (
<>
<button
type="button"
className="tmb-app-download-btn"
onClick={onOpenAppDownload}
title="GoldenChart 모바일 앱 다운로드"
aria-label="앱 다운로드"
>
<IcAppDownload />
</button>
</>
)}
{desktopClient ? (
<button
type="button"
className={`tmb-app-download-btn tmb-desktop-update-btn${desktopUpdateBusy ? ' busy' : ''}`}
onClick={() => { void handleDesktopUpdate(); }}
disabled={desktopUpdateBusy}
title={desktopUpdateHint || 'PC 프로그램 업데이트'}
aria-label="PC 프로그램 업데이트"
>
<IcDesktopUpdate />
</button>
) : onOpenAppDownload ? (
<button
type="button"
className="tmb-app-download-btn"
onClick={onOpenAppDownload}
title="GoldenChart 앱·PC 프로그램 다운로드"
aria-label="앱·PC 프로그램 다운로드"
>
<IcAppDownload />
</button>
) : null}
{onFullscreen && (
<>