chore: up

This commit is contained in:
rain9
2026-01-04 11:39:03 +08:00
parent 42ab7b51dd
commit 81579c37b5
7 changed files with 51 additions and 28 deletions

View File

@@ -291,8 +291,9 @@ pub(crate) async fn open(
to_value(permission).unwrap(),
to_value(ui).unwrap(),
];
use crate::common::MAIN_WINDOW_LABEL;
tauri_app_handle
.emit("open_view_extension", view_extension_opened)
.emit_to(MAIN_WINDOW_LABEL, "open_view_extension", view_extension_opened)
.unwrap();
}
}

View File

@@ -407,6 +407,13 @@ async fn show_view_extension(
height: Option<f64>,
) {
log::debug!("view extension menu item was clicked");
if query
.as_ref()
.map(|q| !(q.contains("manual=1") && q.contains("ext=")))
.unwrap_or(true)
{
return;
}
let window_label = label.unwrap_or_else(|| VIEW_EXTENSION_WINDOW_LABEL.to_string());
if let Some(window) = app_handle.get_webview_window(&window_label) {

View File

@@ -19,6 +19,7 @@ type ControlsProps = {
showFocus?: boolean;
forceResizable?: boolean;
initialViewExtensionOpened?: ViewExtensionOpened | null;
isStandalone?: boolean;
};
const ViewExtensionContent: React.FC<ControlsProps> = ({
@@ -26,9 +27,10 @@ const ViewExtensionContent: React.FC<ControlsProps> = ({
showFocus = true,
forceResizable = false,
initialViewExtensionOpened = null,
isStandalone = false,
}) => {
const storeView = useExtensionStore((state) =>
state.viewExtensions.length > 0 ? state.viewExtensions[state.viewExtensions.length - 1] : undefined
initialViewExtensionOpened ? undefined : (state.viewExtensions.length > 0 ? state.viewExtensions[state.viewExtensions.length - 1] : undefined)
);
const viewExtensionOpened = initialViewExtensionOpened ?? storeView;
@@ -189,7 +191,7 @@ const ViewExtensionContent: React.FC<ControlsProps> = ({
iframeRef,
focusIframe,
setBaseSize,
} = useViewExtensionWindow({ forceResizable });
} = useViewExtensionWindow({ forceResizable, viewExtension: viewExtensionOpened, isStandalone });
const [iframeReady, setIframeReady] = useState(false);
@@ -214,11 +216,11 @@ const ViewExtensionContent: React.FC<ControlsProps> = ({
const ext = viewExtensionOpened!;
const name = ext[0] || "extension";
const safe = name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
const label = `view_extension_${safe}_${Date.now()}`;
const label = `view_extension_${safe}`;
const payload = btoa(encodeURIComponent(JSON.stringify(ext)));
platformAdapter.invokeBackend("show_view_extension", {
label,
query: `?ext=${payload}`,
query: `?manual=1&ext=${payload}`,
width: baseWidth,
height: baseHeight,
});
@@ -245,10 +247,12 @@ const ViewExtensionContent: React.FC<ControlsProps> = ({
};
const ViewExtension: React.FC<ControlsProps> = (props) => {
const viewExtensionOpened = useExtensionStore(
(state) => state.viewExtensions.length > 0 ? state.viewExtensions[state.viewExtensions.length - 1] : undefined
const storeView = useExtensionStore(
(state) => props.initialViewExtensionOpened ? undefined : (state.viewExtensions.length > 0 ? state.viewExtensions[state.viewExtensions.length - 1] : undefined)
);
const viewExtensionOpened = props.initialViewExtensionOpened ?? storeView;
if (viewExtensionOpened == null) {
return (
<div className="flex h-full w-full items-center justify-center text-muted-foreground">

View File

@@ -23,15 +23,15 @@ const applyHideScrollbarToIframe = (
const style = doc.createElement("style");
style.id = HIDE_SCROLLBAR_STYLE_ID;
style.textContent = `
* {
scrollbar-width: none;
-ms-overflow-style: none;
}
*::-webkit-scrollbar {
width: 0px;
height: 0px;
}
`;
* {
scrollbar-width: none;
-ms-overflow-style: none;
}
*::-webkit-scrollbar {
width: 0px;
height: 0px;
}
`;
const parent = doc.head ?? doc.documentElement;
parent?.appendChild(style);

View File

@@ -17,10 +17,11 @@ export function useViewExtensionWindow(opts?: {
forceResizable?: boolean;
ignoreExplicitSize?: boolean;
viewExtension?: ViewExtensionOpened | null;
isStandalone?: boolean;
}) {
const isTauri = useAppStore((state) => state.isTauri);
const storeViewExtension = useExtensionStore((state) =>
state.viewExtensions.length > 0 ? state.viewExtensions[state.viewExtensions.length - 1] : undefined
opts?.viewExtension ? undefined : (state.viewExtensions.length > 0 ? state.viewExtensions[state.viewExtensions.length - 1] : undefined)
);
const viewExtensionOpened = opts?.viewExtension ?? storeViewExtension;
@@ -126,7 +127,8 @@ export function useViewExtensionWindow(opts?: {
// If we are in the standalone view extension window (not the preview in main window),
// we need to show the window explicitly because it is created hidden to avoid flickering.
if (window.location.pathname.includes("/ui/view-extension")) {
// This ensures the window only becomes visible after the initial resize and setup are complete.
if (opts?.isStandalone) {
await platformAdapter.showWindow();
}

View File

@@ -22,8 +22,6 @@ function MainApp() {
// Events will be sent when users try to open a View extension via hotkey,
// whose payload contains the needed information to load the View page.
platformAdapter.listenEvent("open_view_extension", async ({ payload }) => {
await platformAdapter.showWindow();
addViewExtension(payload);
});
}, []);

View File

@@ -1,18 +1,26 @@
import React from "react";
import React, { useMemo } from "react";
import ViewExtension from "@/components/Search/ViewExtension";
import type { ViewExtensionOpened } from "@/stores/extensionStore";
const ViewExtensionPage: React.FC = () => {
// Parse the 'ext' query parameter from the URL.
// This parameter contains the base64-encoded JSON data of the extension to be opened.
// It allows the standalone window to initialize with the correct extension data passed from the main window.
const params = new URLSearchParams(window.location.search);
const encoded = params.get("ext");
let initial: ViewExtensionOpened | null = null;
if (encoded) {
try {
const json = decodeURIComponent(atob(encoded));
initial = JSON.parse(json) as ViewExtensionOpened;
} catch {}
}
const manual = params.get("manual") === "1";
const initial = useMemo(() => {
if (encoded) {
try {
const json = decodeURIComponent(atob(encoded));
return JSON.parse(json) as ViewExtensionOpened;
} catch {}
}
return null;
}, [encoded]);
return (
<div className="w-screen h-screen bg-background text-foreground overflow-hidden">
<ViewExtension
@@ -20,6 +28,9 @@ const ViewExtensionPage: React.FC = () => {
showDetach={false}
showFocus
forceResizable
isStandalone={manual}
// Pass the parsed extension data as the initial state to ensure immediate rendering
// without relying on the store, which might be empty in this new window.
initialViewExtensionOpened={initial}
/>
</div>