diff --git a/packages/plugin-runtime-types/package.json b/packages/plugin-runtime-types/package.json index ae59ee9a..e376f5e9 100644 --- a/packages/plugin-runtime-types/package.json +++ b/packages/plugin-runtime-types/package.json @@ -1,6 +1,6 @@ { "name": "@yaakapp/api", - "version": "0.4.1", + "version": "0.5.0", "main": "lib/index.js", "typings": "./lib/index.d.ts", "files": [ diff --git a/packages/plugin-runtime-types/src/bindings/gen_events.ts b/packages/plugin-runtime-types/src/bindings/gen_events.ts index b2b7e0a6..155214e9 100644 --- a/packages/plugin-runtime-types/src/bindings/gen_events.ts +++ b/packages/plugin-runtime-types/src/bindings/gen_events.ts @@ -346,7 +346,7 @@ export type ImportResponse = { resources: ImportResources, }; export type InternalEvent = { id: string, pluginRefId: string, pluginName: string, replyId: string | null, windowContext: WindowContext, payload: InternalEventPayload, }; -export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; +export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; export type JsonPrimitive = string | number | boolean | null; @@ -354,7 +354,7 @@ export type OpenWindowRequest = { url: string, /** * Label for the window. If not provided, a random one will be generated. */ -label: string, title?: string, size?: WindowSize, }; +label: string, title?: string, size?: WindowSize, dataDirKey?: string, }; export type PromptTextRequest = { id: string, title: string, label: string, description?: string, defaultValue?: string, placeholder?: string, /** diff --git a/packages/plugin-runtime-types/src/plugins/Context.ts b/packages/plugin-runtime-types/src/plugins/Context.ts index 39c288ee..15715c65 100644 --- a/packages/plugin-runtime-types/src/plugins/Context.ts +++ b/packages/plugin-runtime-types/src/plugins/Context.ts @@ -32,7 +32,10 @@ export interface Context { }; window: { openUrl( - args: OpenWindowRequest & { onNavigate?: (args: { url: string }) => void }, + args: OpenWindowRequest & { + onNavigate?: (args: { url: string }) => void; + onClose: () => void; + }, ): Promise<{ close: () => void }>; }; httpRequest: { diff --git a/packages/plugin-runtime/src/EventChannel.ts b/packages/plugin-runtime/src/EventChannel.ts index 4275b6a0..b80802e8 100644 --- a/packages/plugin-runtime/src/EventChannel.ts +++ b/packages/plugin-runtime/src/EventChannel.ts @@ -1,14 +1,19 @@ -import type { InternalEvent } from "@yaakapp/api"; -import EventEmitter from "node:events"; +import type { InternalEvent } from '@yaakapp/api'; export class EventChannel { - emitter: EventEmitter = new EventEmitter(); + #listeners = new Set<(event: InternalEvent) => void>(); emit(e: InternalEvent) { - this.emitter.emit("__plugin_event__", e); + for (const l of this.#listeners) { + l(e); + } } listen(cb: (e: InternalEvent) => void) { - this.emitter.on("__plugin_event__", cb); + this.#listeners.add(cb); + } + + unlisten(cb: (e: InternalEvent) => void) { + this.#listeners.delete(cb); } } diff --git a/packages/plugin-runtime/src/PluginInstance.ts b/packages/plugin-runtime/src/PluginInstance.ts index dc9fab32..997349a7 100644 --- a/packages/plugin-runtime/src/PluginInstance.ts +++ b/packages/plugin-runtime/src/PluginInstance.ts @@ -342,9 +342,9 @@ export class PluginInstance { } #sendEvent(event: InternalEvent) { - if (event.payload.type !== 'empty_response') { - console.log('Sending event to app', event.id, event.payload.type); - } + // if (event.payload.type !== 'empty_response') { + // console.log('Sending event to app', this.#pkg.name, event.id, event.payload.type); + // } this.#pluginToAppEvents.emit(event); } @@ -363,7 +363,7 @@ export class PluginInstance { const promise = new Promise((resolve) => { const cb = (event: InternalEvent) => { if (event.replyId === eventToSend.id) { - this.#appToPluginEvents.listen(cb); // Unlisten, now that we're done + this.#appToPluginEvents.unlisten(cb); // Unlisten, now that we're done const { type: _, ...payload } = event.payload; resolve(payload as T); } @@ -372,7 +372,6 @@ export class PluginInstance { }); // 3. Send the event after we start listening (to prevent race) - console.log("SENDING EVENT FOR REPLY", eventToSend); this.#sendEvent(eventToSend); // 4. Return the listener promise @@ -417,12 +416,14 @@ export class PluginInstance { }, }, window: { - openUrl: async ({ onNavigate, ...args }) => { + openUrl: async ({ onNavigate, onClose, ...args }) => { args.label = args.label || `${Math.random()}`; const payload: InternalEventPayload = { type: 'open_window_request', ...args }; const onEvent = (event: InternalEventPayload) => { if (event.type === 'window_navigate_event') { onNavigate?.(event); + } else if (event.type === 'window_close_event') { + onClose?.(); } }; this.#sendAndListenForEvents(event.windowContext, payload, onEvent); diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index f0998b43..77265f3e 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1658,8 +1658,8 @@ async fn cmd_new_child_window( url, inner_size: Some(inner_size), position: Some(position), - navigation_tx: None, hide_titlebar: true, + ..Default::default() }; let child_window = window::create_window(&app_handle, config); @@ -2014,8 +2014,8 @@ fn create_main_window(handle: &AppHandle, url: &str) -> WebviewWindow { 100.0 + random::() * 20.0, 100.0 + random::() * 20.0, )), - navigation_tx: None, hide_titlebar: true, + ..Default::default() }; window::create_window(handle, config) diff --git a/src-tauri/src/plugin_events.rs b/src-tauri/src/plugin_events.rs index bc35e753..4c991f6b 100644 --- a/src-tauri/src/plugin_events.rs +++ b/src-tauri/src/plugin_events.rs @@ -204,32 +204,55 @@ pub(crate) async fn handle_plugin_event( } InternalEventPayload::OpenWindowRequest(req) => { let label = req.label; - let (tx, mut rx) = tokio::sync::mpsc::channel(128); + let (navigation_tx, mut navigation_rx) = tokio::sync::mpsc::channel(128); + let (close_tx, mut close_rx) = tokio::sync::mpsc::channel(128); let win_config = CreateWindowConfig { url: &req.url, label: &label.clone(), title: &req.title.unwrap_or_default(), - navigation_tx: Some(tx), + navigation_tx: Some(navigation_tx), + close_tx: Some(close_tx), inner_size: req.size.map(|s| (s.width, s.height)), - position: None, - hide_titlebar: false, + data_dir_key: req.data_dir_key, + ..Default::default() }; create_window(app_handle, win_config); - let event_id = event.id.clone(); - let plugin_handle = plugin_handle.clone(); - tauri::async_runtime::spawn(async move { - while let Some(url) = rx.recv().await { - let label = label.clone(); - let url = url.to_string(); - let event_to_send = plugin_handle.build_event_to_send( - &WindowContext::Label { label }, - &InternalEventPayload::WindowNavigateEvent(WindowNavigateEvent { url }), - Some(event_id.clone()), - ); - plugin_handle.send(&event_to_send).await.unwrap(); - } - }); + { + let event_id = event.id.clone(); + let plugin_handle = plugin_handle.clone(); + let label = label.clone(); + tauri::async_runtime::spawn(async move { + while let Some(url) = navigation_rx.recv().await { + let url = url.to_string(); + let label = label.clone(); + let event_to_send = plugin_handle.build_event_to_send( + &WindowContext::Label { label }, + &InternalEventPayload::WindowNavigateEvent(WindowNavigateEvent { url }), + Some(event_id.clone()), + ); + plugin_handle.send(&event_to_send).await.unwrap(); + } + }); + } + + { + let event_id = event.id.clone(); + let plugin_handle = plugin_handle.clone(); + let label = label.clone(); + tauri::async_runtime::spawn(async move { + while let Some(_) = close_rx.recv().await { + let label = label.clone(); + let event_to_send = plugin_handle.build_event_to_send( + &WindowContext::Label { label }, + &InternalEventPayload::WindowCloseEvent, + Some(event_id.clone()), + ); + plugin_handle.send(&event_to_send).await.unwrap(); + } + }); + } + None } InternalEventPayload::CloseWindowRequest(req) => { diff --git a/src-tauri/src/window.rs b/src-tauri/src/window.rs index c2df780d..b6f0a858 100644 --- a/src-tauri/src/window.rs +++ b/src-tauri/src/window.rs @@ -3,7 +3,7 @@ use crate::{DEFAULT_WINDOW_HEIGHT, DEFAULT_WINDOW_WIDTH, MIN_WINDOW_HEIGHT, MIN_ use log::{info, warn}; use std::process::exit; use tauri::{ - AppHandle, Emitter, LogicalSize, Manager, Runtime, WebviewUrl, WebviewWindow, + AppHandle, Emitter, LogicalSize, Manager, Runtime, WebviewUrl, WebviewWindow, WindowEvent, }; use tauri_plugin_opener::OpenerExt; use tokio::sync::mpsc; @@ -16,6 +16,8 @@ pub(crate) struct CreateWindowConfig<'s> { pub inner_size: Option<(f64, f64)>, pub position: Option<(f64, f64)>, pub navigation_tx: Option>, + pub close_tx: Option>, + pub data_dir_key: Option, pub hide_titlebar: bool, } @@ -41,6 +43,22 @@ pub(crate) fn create_window( .disable_drag_drop_handler() // Required for frontend Dnd on windows .min_inner_size(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT); + if let Some(key) = config.data_dir_key { + #[cfg(not(target_os = "macos"))] + { + use std::fs; + let dir = handle.path().temp_dir().unwrap().join("yaak_sessions").join(key); + fs::create_dir_all(dir.clone()).unwrap(); + win_builder = win_builder.data_directory(dir); + } + + // macOS doesn't support data dir so must use this fn instead + #[cfg(target_os = "macos")] + { + win_builder = win_builder.data_store_identifier(to_fixed_hash(&key)); + } + } + if let Some((w, h)) = config.inner_size { win_builder = win_builder.inner_size(w, h); } else { @@ -85,6 +103,18 @@ pub(crate) fn create_window( let win = win_builder.build().unwrap(); + if let Some(tx) = config.close_tx { + win.on_window_event(move |event| match event { + WindowEvent::CloseRequested { .. } => { + let tx = tx.clone(); + tauri::async_runtime::block_on(async move { + tx.send(()).await.unwrap(); + }); + } + _ => {} + }); + } + let webview_window = win.clone(); win.on_menu_event(move |w, event| { if !w.is_focused().unwrap() { @@ -128,3 +158,10 @@ pub(crate) fn create_window( win } + +fn to_fixed_hash(s: &str) -> [u8; 16] { + let hash = md5::compute(s.as_bytes()); + let mut fixed = [0u8; 16]; + fixed.copy_from_slice(&hash[..16]); // Take the first 16 bytes of the hash + fixed +} diff --git a/src-tauri/vendored/plugins/auth-oauth2/build/index.js b/src-tauri/vendored/plugins/auth-oauth2/build/index.js index f30555ea..051fbda1 100644 --- a/src-tauri/vendored/plugins/auth-oauth2/build/index.js +++ b/src-tauri/vendored/plugins/auth-oauth2/build/index.js @@ -102,9 +102,19 @@ async function getToken(ctx, contextId) { async function deleteToken(ctx, contextId) { return ctx.store.delete(tokenStoreKey(contextId)); } +async function resetDataDirKey(ctx, contextId) { + const key = (/* @__PURE__ */ new Date()).toISOString(); + return ctx.store.set(dataDirStoreKey(contextId), key); +} +async function getDataDirKey(ctx, contextId) { + return ctx.store.get(dataDirStoreKey(contextId)); +} function tokenStoreKey(context_id) { return ["token", context_id].join("::"); } +function dataDirStoreKey(context_id) { + return ["data_dir", context_id].join("::"); +} // src/getOrRefreshAccessToken.ts async function getOrRefreshAccessToken(ctx, contextId, { @@ -218,9 +228,16 @@ async function getAuthorizationCode(ctx, contextId, { return new Promise(async (resolve, reject) => { const authorizationUrlStr = authorizationUrl.toString(); console.log("Authorizing", authorizationUrlStr); + let foundCode = false; let { close } = await ctx.window.openUrl({ url: authorizationUrlStr, label: "oauth-authorization-url", + dataDirKey: await getDataDirKey(ctx, contextId), + async onClose() { + if (!foundCode) { + reject(new Error("Authorization window closed")); + } + }, async onNavigate({ url: urlStr }) { const url = new URL(urlStr); if (url.searchParams.has("error")) { @@ -230,6 +247,7 @@ async function getAuthorizationCode(ctx, contextId, { if (!code) { return; } + foundCode = true; close(); const response = await getAccessToken(ctx, { grantType: "authorization_code", @@ -428,7 +446,6 @@ var plugin = { actions: [ { label: "Copy Current Token", - icon: "copy", async onSelect(ctx, { contextId }) { const token = await getToken(ctx, contextId); if (token == null) { @@ -441,7 +458,6 @@ var plugin = { }, { label: "Delete Token", - icon: "trash", async onSelect(ctx, { contextId }) { if (await deleteToken(ctx, contextId)) { await ctx.toast.show({ message: "Token deleted", color: "success" }); @@ -449,6 +465,12 @@ var plugin = { await ctx.toast.show({ message: "No token to delete", color: "warning" }); } } + }, + { + label: "Clear Window Session", + async onSelect(ctx, { contextId }) { + await resetDataDirKey(ctx, contextId); + } } ], args: [ diff --git a/src-tauri/vendored/plugins/exporter-curl/build/index.js b/src-tauri/vendored/plugins/exporter-curl/build/index.js index 2965d8b7..971450fb 100644 --- a/src-tauri/vendored/plugins/exporter-curl/build/index.js +++ b/src-tauri/vendored/plugins/exporter-curl/build/index.js @@ -30,13 +30,9 @@ var plugin = { label: "Copy as Curl", icon: "copy", async onSelect(ctx, args) { - console.log("---------------------------", 0); const rendered_request = await ctx.httpRequest.render({ httpRequest: args.httpRequest, purpose: "preview" }); - console.log("---------------------------", 1); const data = await convertToCurl(rendered_request); - console.log("---------------------------", 2); await ctx.clipboard.copyText(data); - console.log("---------------------------", 3); await ctx.toast.show({ message: "Curl copied to clipboard", icon: "copy", color: "success" }); } }] diff --git a/src-tauri/yaak-plugins/bindings/gen_events.ts b/src-tauri/yaak-plugins/bindings/gen_events.ts index b2b7e0a6..155214e9 100644 --- a/src-tauri/yaak-plugins/bindings/gen_events.ts +++ b/src-tauri/yaak-plugins/bindings/gen_events.ts @@ -346,7 +346,7 @@ export type ImportResponse = { resources: ImportResources, }; export type InternalEvent = { id: string, pluginRefId: string, pluginName: string, replyId: string | null, windowContext: WindowContext, payload: InternalEventPayload, }; -export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; +export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse; export type JsonPrimitive = string | number | boolean | null; @@ -354,7 +354,7 @@ export type OpenWindowRequest = { url: string, /** * Label for the window. If not provided, a random one will be generated. */ -label: string, title?: string, size?: WindowSize, }; +label: string, title?: string, size?: WindowSize, dataDirKey?: string, }; export type PromptTextRequest = { id: string, title: string, label: string, description?: string, defaultValue?: string, placeholder?: string, /** diff --git a/src-tauri/yaak-plugins/src/events.rs b/src-tauri/yaak-plugins/src/events.rs index 3676bbe1..a28b12a0 100644 --- a/src-tauri/yaak-plugins/src/events.rs +++ b/src-tauri/yaak-plugins/src/events.rs @@ -3,7 +3,9 @@ use std::collections::HashMap; use tauri::{Runtime, WebviewWindow}; use ts_rs::TS; -use yaak_models::models::{Environment, Folder, GrpcRequest, HttpRequest, HttpResponse, WebsocketRequest, Workspace}; +use yaak_models::models::{ + Environment, Folder, GrpcRequest, HttpRequest, HttpResponse, WebsocketRequest, Workspace, +}; #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(rename_all = "camelCase")] @@ -108,6 +110,7 @@ pub enum InternalEventPayload { OpenWindowRequest(OpenWindowRequest), WindowNavigateEvent(WindowNavigateEvent), + WindowCloseEvent, CloseWindowRequest(CloseWindowRequest), TemplateRenderRequest(TemplateRenderRequest), @@ -262,10 +265,15 @@ pub struct OpenWindowRequest { pub url: String, /// Label for the window. If not provided, a random one will be generated. pub label: String, + #[ts(optional)] pub title: Option, + #[ts(optional)] pub size: Option, + + #[ts(optional)] + pub data_dir_key: Option, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] diff --git a/src-web/components/core/Banner.tsx b/src-web/components/core/Banner.tsx index 7afa055e..f4776ac3 100644 --- a/src-web/components/core/Banner.tsx +++ b/src-web/components/core/Banner.tsx @@ -9,17 +9,19 @@ interface Props { export function Banner({ children, className, color }: Props) { return ( -
- {children} +
+
+ {children} +
); }