앱 버전표시

This commit is contained in:
Macbook
2026-06-14 18:38:42 +09:00
parent 0aeea1634c
commit b2c6650cd5
15 changed files with 142 additions and 1 deletions
@@ -10,6 +10,7 @@
"core:window:allow-hide",
"core:window:allow-show",
"core:window:allow-set-focus",
"core:window:allow-set-title",
"core:window:allow-start-dragging",
"core:webview:allow-create-webview-window",
"core:webview:allow-webview-close",
+6
View File
@@ -21,6 +21,12 @@ pub fn run() {
.plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_opener::init())
.setup(|app| {
let version = app.package_info().version.to_string();
let main_title = format!("GoldenChart (v{version})");
if let Some(w) = app.get_webview_window("main") {
let _ = w.set_title(&main_title);
}
let show_i = MenuItemBuilder::with_id("show", "GoldenChart 열기").build(app)?;
let quit_i = MenuItemBuilder::with_id("quit", "종료").build(app)?;
let menu = MenuBuilder::new(app)
+2
View File
@@ -4,6 +4,7 @@ import {
type DesktopUpdatePhase,
type DesktopUpdateProgress,
} from './bridge/updater';
import { scheduleMainWindowTitleSync } from './setMainWindowTitle';
import '@frontend/App.css';
const PHASE_LABEL: Record<DesktopUpdatePhase, string> = {
@@ -143,6 +144,7 @@ export function StartupUpdateGate({ children }: { children: React.ReactNode }) {
if (result.phase === 'error') {
console.warn('[startup-update]', result.message);
}
scheduleMainWindowTitleSync();
setReady(true);
});
@@ -1,6 +1,7 @@
import { openWidgetWindow, closeWidgetWindow, focusWidgetWindow } from './widgetWindows';
import { showNativeNotification } from './notifications';
import { checkForUpdates, getAppVersion, runDesktopUpdate } from './updater';
import { syncMainWindowTitle } from '../setMainWindowTitle';
import type { DesktopBridge } from './types';
/** frontend App 로드 전 호출 — window.__goldenDesktopBridge 등록 */
@@ -13,6 +14,7 @@ export function installDesktopBridge(): void {
checkForUpdates,
runDesktopUpdate,
getAppVersion,
syncMainWindowTitle,
};
window.__goldenDesktopBridge = bridge;
}
+1
View File
@@ -16,6 +16,7 @@ export interface DesktopBridge {
onProgress?: (progress: DesktopUpdateProgress) => void,
) => Promise<DesktopUpdateResult>;
getAppVersion: () => Promise<string>;
syncMainWindowTitle: () => Promise<string>;
}
declare global {
+8
View File
@@ -4,6 +4,7 @@ import ReactDOM from 'react-dom/client';
import { initStorage, refreshApiBaseFromStorage } from '@goldenchart/shared';
import { installDesktopBridge } from './bridge/installDesktopBridge';
import { ensureDesktopApiBase } from './ensureDesktopApiBase';
import { scheduleMainWindowTitleSync, syncMainWindowTitle } from './setMainWindowTitle';
import { StartupUpdateGate } from './StartupUpdateGate';
import App from '@frontend/App';
@@ -13,6 +14,13 @@ async function bootstrap() {
await initStorage();
ensureDesktopApiBase();
refreshApiBaseFromStorage();
document.documentElement.classList.add('desktop-client');
try {
await syncMainWindowTitle();
} catch {
/* 권한·타이밍 이슈 — scheduleMainWindowTitleSync 가 재시도 */
}
scheduleMainWindowTitleSync();
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
+40
View File
@@ -0,0 +1,40 @@
import { getVersion } from '@tauri-apps/api/app';
import { getCurrentWindow } from '@tauri-apps/api/window';
const APP_NAME = 'GoldenChart';
export function formatDesktopWindowTitle(version: string): string {
const v = version.trim();
return v ? `${APP_NAME} (v${v})` : APP_NAME;
}
/** macOS/Windows 네이티브 창 타이틀 — GoldenChart (vX.Y.Z) */
export async function syncMainWindowTitle(): Promise<string> {
try {
const version = await getVersion();
const title = formatDesktopWindowTitle(version);
await getCurrentWindow().setTitle(title);
if (typeof document !== 'undefined') {
document.title = title;
}
return title;
} catch (e) {
console.warn('[desktop] syncMainWindowTitle failed:', e);
throw e;
}
}
/** WebView 로드 후 macOS가 document.title로 타이틀을 덮어쓸 수 있어 재시도 */
export function scheduleMainWindowTitleSync(): void {
const delays = [0, 150, 600, 2000];
for (const ms of delays) {
window.setTimeout(() => {
void syncMainWindowTitle().catch(() => {});
}, ms);
}
void getCurrentWindow()
.listen('tauri://focus', () => {
void syncMainWindowTitle().catch(() => {});
})
.catch(() => {});
}
+2
View File
@@ -1 +1,3 @@
/// <reference types="vite/client" />
declare const __DESKTOP_APP_VERSION__: string;
+12
View File
@@ -1,6 +1,7 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
import { readFileSync } from 'fs';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -9,6 +10,16 @@ const sharedRoot = path.resolve(__dirname, '../packages/shared/src');
const host = process.env.TAURI_DEV_HOST;
function readDesktopAppVersion(): string {
try {
const confPath = path.resolve(__dirname, 'src-tauri/tauri.conf.json');
const conf = JSON.parse(readFileSync(confPath, 'utf8')) as { version?: string };
return String(conf.version ?? '0.0.0');
} catch {
return '0.0.0';
}
}
export default defineConfig({
/** Tauri 패키지 앱 — 절대 경로(/assets) 사용 시 빈 화면 */
base: './',
@@ -18,6 +29,7 @@ export default defineConfig({
/** desktop은 항상 exdev 서버 (localhost 금지) */
'import.meta.env.VITE_API_BASE_URL': JSON.stringify('http://exdev.co.kr/api'),
__DESKTOP_CLIENT__: 'true',
__DESKTOP_APP_VERSION__: JSON.stringify(readDesktopAppVersion()),
},
envDir: __dirname,
plugins: [react()],