fix(desktop): 네이티브 위젯 picker를 창 전체 뷰로 전환

portal/overlay 대신 widget-main에서 picker 전용 화면으로 전환해
macOS·Windows WebView 모두에서 위젯 선택 팝업이 보이도록 합니다.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Macbook
2026-06-15 16:49:25 +09:00
parent 1804328b9b
commit 36b4679c9a
4 changed files with 130 additions and 73 deletions
+57 -15
View File
@@ -6,6 +6,7 @@ import { LogicalSize } from '@tauri-apps/api/dpi';
import { initStorage, refreshApiBaseFromStorage } from '@goldenchart/shared';
import { ensureDesktopApiBase } from './ensureDesktopApiBase';
import FloatingWidgetWindow from '@frontend/components/floatingWidgets/FloatingWidgetWindow';
import WidgetPickerModal from '@frontend/components/widgetDashboard/WidgetPickerModal';
import {
defaultGridFr,
NATIVE_WIDGET_PICKER_WINDOW,
@@ -131,6 +132,8 @@ const WidgetApp: React.FC = () => {
return () => { unlisten?.(); };
}, [instance?.id]);
const [pickSlotId, setPickSlotId] = useState<string | null>(null);
const handleClose = useCallback(() => {
void getCurrentWindow().close();
}, []);
@@ -174,6 +177,34 @@ const WidgetApp: React.FC = () => {
}
}, []);
const handleNativePickRequest = useCallback((slotId: string) => {
setPickSlotId(slotId);
void Promise.resolve(handlePickerOpenChange(true)).catch(err => {
console.warn('[widget-main] picker open resize failed', err);
});
}, [handlePickerOpenChange]);
const handleNativePickClose = useCallback(() => {
setPickSlotId(null);
void Promise.resolve(handlePickerOpenChange(false)).catch(err => {
console.warn('[widget-main] picker close resize failed', err);
});
}, [handlePickerOpenChange]);
const handleNativePickSelect = useCallback((widgetType: string) => {
if (!pickSlotId) return;
setInstance(prev => {
if (!prev) return prev;
return {
...prev,
slots: prev.slots.map(s => (
s.id === pickSlotId ? { ...s, widgetType, config: {} } : s
)),
};
});
handleNativePickClose();
}, [pickSlotId, handleNativePickClose]);
if (!instance) {
return <p className="wd-widget-empty"> .</p>;
}
@@ -194,21 +225,32 @@ const WidgetApp: React.FC = () => {
paperAutoTradeEnabled={false}
chartRealtimeSource="BACKEND_STOMP"
>
<div className="fw-widget-native-root">
<FloatingWidgetWindow
instance={instance}
focused
nativeShell
onClose={handleClose}
onFocus={() => {}}
onPickerOpenChange={handlePickerOpenChange}
onUpdateSlots={slots => setInstance(prev => (prev ? { ...prev, slots } : prev))}
onUpdateSize={(width, height) => {
setInstance(prev => (prev ? { ...prev, width, height } : prev));
void getCurrentWindow().setSize(new LogicalSize(width, height));
}}
onUpdateGridFr={(rowFr, colFr) => setInstance(prev => (prev ? { ...prev, rowFr, colFr } : prev))}
/>
<div className={`fw-widget-native-root${pickSlotId ? ' fw-widget-native-root--picker' : ''}`}>
{pickSlotId != null ? (
<WidgetPickerModal
open
category="all"
nativeCompact
nativeFullRoot
onClose={handleNativePickClose}
onSelect={handleNativePickSelect}
/>
) : (
<FloatingWidgetWindow
instance={instance}
focused
nativeShell
onClose={handleClose}
onFocus={() => {}}
onNativePickRequest={handleNativePickRequest}
onUpdateSlots={slots => setInstance(prev => (prev ? { ...prev, slots } : prev))}
onUpdateSize={(width, height) => {
setInstance(prev => (prev ? { ...prev, width, height } : prev));
void getCurrentWindow().setSize(new LogicalSize(width, height));
}}
onUpdateGridFr={(rowFr, colFr) => setInstance(prev => (prev ? { ...prev, rowFr, colFr } : prev))}
/>
)}
</div>
</WidgetDashboardProvider>
);