mirror of
https://github.com/infinilabs/coco-app.git
synced 2026-02-24 04:01:27 +01:00
chore: up
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}, []);
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user