diff --git a/electron/main.cjs b/electron/main.cjs index 03685cb..e4691e6 100644 --- a/electron/main.cjs +++ b/electron/main.cjs @@ -2,9 +2,32 @@ // 라이브 사이트(https://app.sblog.kr)를 직접 로드한다 → 프론트 변경이 자동 반영(재설치 불필요), // 같은 출처라 CORS 우회도 불필요. 배포된 웹 게이트가 Electron 을 감지해 안내페이지 대신 전체 앱을 띄운다. const { app, BrowserWindow, shell } = require('electron') +const fs = require('fs') +const path = require('path') const APP_URL = 'https://app.sblog.kr' +// 창 크기/위치를 userData 에 저장해 다음 실행 때 복원 (기본 해상도 고정 대신 사용자가 맞춘 크기 유지) +function stateFile() { + return path.join(app.getPath('userData'), 'window-state.json') +} +function loadState() { + try { + return JSON.parse(fs.readFileSync(stateFile(), 'utf-8')) + } catch { + return null + } +} +function saveState(win) { + try { + if (win.isMinimized()) return + const b = win.getBounds() + fs.writeFileSync(stateFile(), JSON.stringify({ ...b, maximized: win.isMaximized() })) + } catch { + /* 저장 실패 무시 */ + } +} + // 오프라인/로드 실패 시 안내 화면 (다시 시도 버튼) function offlineHtml() { const html = `Slim Budget @@ -19,9 +42,12 @@ font-size:15px;font-weight:600;cursor:pointer} } function createWindow() { + const s = loadState() const win = new BrowserWindow({ - width: 1200, - height: 820, + width: s?.width || 1024, + height: s?.height || 720, + x: s?.x, + y: s?.y, minWidth: 360, minHeight: 560, backgroundColor: '#1a1a1a', @@ -31,11 +57,15 @@ function createWindow() { nodeIntegration: false, }, }) + if (s?.maximized) win.maximize() // 기본 메뉴바 제거(앱 자체 내비게이션 사용) win.removeMenu() win.loadURL(APP_URL) + // 닫을 때 창 크기/위치 저장 → 다음 실행에 복원 + win.on('close', () => saveState(win)) + // 메인 프레임 로드 실패(오프라인 등) 시 안내 화면. -3(aborted, 리다이렉트 등)은 무시. win.webContents.on('did-fail-load', (event, errorCode, errorDescription, validatedURL, isMainFrame) => { if (isMainFrame && errorCode !== -3) win.loadURL(offlineHtml()) diff --git a/src/App.vue b/src/App.vue index 686b527..7e0b6e5 100644 --- a/src/App.vue +++ b/src/App.vue @@ -42,10 +42,13 @@ watch(() => route.fullPath, () => ui.closeSidebar())