위젯 추가 팝업 수정

This commit is contained in:
Macbook
2026-06-15 17:17:06 +09:00
parent 271392bc49
commit 51fdcf40e5
16 changed files with 435 additions and 238 deletions
+3
View File
@@ -13525,6 +13525,9 @@ html.theme-light .tam-disclaimer { color: #90a4ae; }
display: flex; justify-content: flex-end; gap: 8px;
}
.desktop-startup-update {
position: fixed;
inset: 0;
z-index: 20000;
min-height: 100vh; display: flex; align-items: center; justify-content: center;
padding: 24px; background: var(--bg, #1a1b26);
}
+12 -4
View File
@@ -9,6 +9,9 @@ import {
type DesktopUpdatePhase,
type DesktopUpdateProgress,
} from '../utils/desktopBridge';
/** 다른 오버레이(플로팅 위젯 13000 등)보다 위에 표시 */
const DESKTOP_UPDATE_MODAL_Z = 15000;
import { isMacDesktop, isWindowsDesktop } from '../utils/platform';
import { PlatformBrandIcon, type PlatformBrandIconId } from './icons/PlatformBrandIcons';
@@ -52,12 +55,14 @@ const DesktopUpdateModal: React.FC<Props> = ({ open, onClose, autoStart = true }
? 'desktop-update-progress--active'
: '';
const handleRun = useCallback(async () => {
const handleRun = useCallback(async (opts?: { bypassLoopGuard?: boolean }) => {
if (busy) return;
setBusy(true);
setProgress({ phase: 'checking', message: '서버에서 새 버전을 확인하는 중…', currentVersion: appVersion });
try {
await runDesktopUpdate(p => setProgress(p));
await runDesktopUpdate(p => setProgress(p), {
bypassLoopGuard: opts?.bypassLoopGuard ?? true,
});
} finally {
setBusy(false);
}
@@ -66,6 +71,8 @@ const DesktopUpdateModal: React.FC<Props> = ({ open, onClose, autoStart = true }
useEffect(() => {
if (!open) {
startedRef.current = false;
setProgress(null);
setBusy(false);
return;
}
void getDesktopAppVersion().then(v => {
@@ -73,7 +80,7 @@ const DesktopUpdateModal: React.FC<Props> = ({ open, onClose, autoStart = true }
});
if (autoStart && !startedRef.current) {
startedRef.current = true;
void handleRun();
void handleRun({ bypassLoopGuard: true });
}
}, [open, autoStart, handleRun]);
@@ -97,6 +104,7 @@ const DesktopUpdateModal: React.FC<Props> = ({ open, onClose, autoStart = true }
onClose={isActive ? () => {} : onClose}
closeOnBackdrop={!isActive}
width={440}
zIndex={DESKTOP_UPDATE_MODAL_Z}
dialogClassName="sp-modal desktop-update-modal"
>
<div className="desktop-update-modal-body">
@@ -200,7 +208,7 @@ const DesktopUpdateModal: React.FC<Props> = ({ open, onClose, autoStart = true }
<div className="desktop-update-actions">
{phase === 'error' && (
<button type="button" className="stg-btn-secondary" disabled={busy} onClick={() => { void handleRun(); }}>
<button type="button" className="stg-btn-secondary" disabled={busy} onClick={() => { void handleRun({ bypassLoopGuard: true }); }}>
</button>
)}
+45 -1
View File
@@ -1241,7 +1241,51 @@
max-height: none;
}
/* Tauri 네이티브 위젯 창 — 서버와 동일 AppPopup (720×860 OS 창) */
/* Tauri 위젯 선택 전용 OS 창 (720×860) — 서버 AppPopup과 동일 */
html.fw-native-picker-window,
html.fw-native-picker-window body {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
background: var(--bg, #1a1b26);
}
html.fw-native-picker-window #root {
width: 100%;
height: 100%;
min-height: 0;
}
html.fw-native-picker-window .wd-picker-native-loading {
position: fixed;
inset: 0;
z-index: 13199;
display: flex;
align-items: center;
justify-content: center;
background: var(--bg, #1a1b26);
color: var(--text2);
font-size: 13px;
}
html.fw-native-picker-window .app-popup-overlay {
position: fixed;
inset: 0;
z-index: 13200;
}
html.fw-native-picker-window .app-popup-shell--widget-picker {
width: min(720px, calc(100vw - 16px)) !important;
max-height: min(860px, calc(100vh - 16px));
}
html.fw-native-picker-window .app-popup-shell--widget-picker .wd-picker-popup-body {
max-height: min(760px, calc(100vh - 120px));
overflow-y: auto;
}
/* (legacy) Tauri 네이티브 위젯 창 — in-window picker */
html.fw-native-widget.fw-native-picker-mode,
html.fw-native-widget.fw-native-picker-mode body {
overflow: hidden;
+8 -1
View File
@@ -9,6 +9,11 @@ export type DesktopUpdatePhase =
| 'relaunching'
| 'error';
export interface DesktopUpdateOptions {
/** 수동 업데이트·재시도 시 반복 실패 가드 무시 */
bypassLoopGuard?: boolean;
}
export interface DesktopUpdateProgress {
phase: DesktopUpdatePhase;
message: string;
@@ -35,6 +40,7 @@ export interface DesktopBridge {
checkForUpdates: () => Promise<{ available: boolean; version?: string; message?: string }>;
runDesktopUpdate: (
onProgress?: (progress: DesktopUpdateProgress) => void,
options?: DesktopUpdateOptions,
) => Promise<DesktopUpdateResult>;
getAppVersion: () => Promise<string>;
syncMainWindowTitle: () => Promise<string>;
@@ -69,12 +75,13 @@ export async function checkDesktopUpdates(): Promise<{ available: boolean; versi
export async function runDesktopUpdate(
onProgress?: (progress: DesktopUpdateProgress) => void,
options?: DesktopUpdateOptions,
): Promise<DesktopUpdateResult> {
const bridge = getDesktopBridge();
if (!bridge?.runDesktopUpdate) {
return { ok: false, phase: 'error', message: '데스크톱 앱에서만 사용 가능합니다.' };
}
return bridge.runDesktopUpdate(onProgress);
return bridge.runDesktopUpdate(onProgress, options);
}
export async function getDesktopAppVersion(): Promise<string | null> {