mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-22 01:19:13 +01:00
Make settings menu a regular window (#113)
This commit is contained in:
2
src-tauri/.gitignore
vendored
2
src-tauri/.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
target/
|
||||
|
||||
vendored
|
||||
|
||||
@@ -35,12 +35,12 @@
|
||||
"core:window:allow-is-fullscreen",
|
||||
"core:window:allow-maximize",
|
||||
"core:window:allow-minimize",
|
||||
"core:window:allow-toggle-maximize",
|
||||
"core:window:allow-set-decorations",
|
||||
"core:window:allow-set-title",
|
||||
"core:window:allow-start-dragging",
|
||||
"core:window:allow-unmaximize",
|
||||
"core:window:allow-theme",
|
||||
"core:window:allow-toggle-maximize",
|
||||
"core:window:allow-unmaximize",
|
||||
"clipboard-manager:allow-read-text",
|
||||
"clipboard-manager:allow-write-text"
|
||||
]
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"main":{"identifier":"main","description":"Main permissions","local":true,"windows":["*"],"permissions":["core:event:allow-emit","core:event:allow-listen","core:event:allow-unlisten","os:allow-os-type","clipboard-manager:allow-clear","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","dialog:allow-open","dialog:allow-save","fs:allow-read-file","fs:allow-read-text-file",{"identifier":"fs:scope","allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]},"shell:allow-open","core:webview:allow-set-webview-zoom","core:window:allow-close","core:window:allow-is-fullscreen","core:window:allow-maximize","core:window:allow-minimize","core:window:allow-toggle-maximize","core:window:allow-set-decorations","core:window:allow-set-title","core:window:allow-start-dragging","core:window:allow-unmaximize","core:window:allow-theme","clipboard-manager:allow-read-text","clipboard-manager:allow-write-text"]}}
|
||||
{"main":{"identifier":"main","description":"Main permissions","local":true,"windows":["*"],"permissions":["core:event:allow-emit","core:event:allow-listen","core:event:allow-unlisten","os:allow-os-type","clipboard-manager:allow-clear","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","dialog:allow-open","dialog:allow-save","fs:allow-read-file","fs:allow-read-text-file",{"identifier":"fs:scope","allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]},"shell:allow-open","core:webview:allow-set-webview-zoom","core:window:allow-close","core:window:allow-is-fullscreen","core:window:allow-maximize","core:window:allow-minimize","core:window:allow-set-decorations","core:window:allow-set-title","core:window:allow-start-dragging","core:window:allow-theme","core:window:allow-toggle-maximize","core:window:allow-unmaximize","clipboard-manager:allow-read-text","clipboard-manager:allow-write-text"]}}
|
||||
@@ -2,13 +2,13 @@ extern crate core;
|
||||
#[cfg(target_os = "macos")]
|
||||
extern crate objc;
|
||||
|
||||
use std::collections::{BTreeMap};
|
||||
use std::fs;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs::{create_dir_all, read_to_string, File};
|
||||
use std::path::PathBuf;
|
||||
use std::process::exit;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
use std::{fs, panic};
|
||||
|
||||
use base64::prelude::BASE64_STANDARD;
|
||||
use base64::Engine;
|
||||
@@ -83,7 +83,9 @@ const DEFAULT_WINDOW_HEIGHT: f64 = 600.0;
|
||||
|
||||
const MIN_WINDOW_WIDTH: f64 = 300.0;
|
||||
const MIN_WINDOW_HEIGHT: f64 = 300.0;
|
||||
|
||||
const MAIN_WINDOW_PREFIX: &str = "main_";
|
||||
const OTHER_WINDOW_PREFIX: &str = "other_";
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
@@ -1649,19 +1651,83 @@ async fn cmd_list_workspaces(w: WebviewWindow) -> Result<Vec<Workspace>, String>
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn cmd_new_window(app_handle: AppHandle, url: &str) -> Result<(), String> {
|
||||
create_window(&app_handle, url);
|
||||
async fn cmd_new_child_window(
|
||||
parent_window: WebviewWindow,
|
||||
url: &str,
|
||||
label: &str,
|
||||
title: &str,
|
||||
inner_size: (f64, f64),
|
||||
) -> Result<(), String> {
|
||||
let app_handle = parent_window.app_handle();
|
||||
let label = format!("{OTHER_WINDOW_PREFIX}_{label}");
|
||||
let scale_factor = parent_window.scale_factor().unwrap();
|
||||
|
||||
let current_pos = parent_window
|
||||
.inner_position()
|
||||
.unwrap()
|
||||
.to_logical::<f64>(scale_factor);
|
||||
let current_size = parent_window
|
||||
.inner_size()
|
||||
.unwrap()
|
||||
.to_logical::<f64>(scale_factor);
|
||||
|
||||
// Position the new window in the middle of the parent
|
||||
let position = (
|
||||
current_pos.x + current_size.width / 2.0 - inner_size.0 / 2.0,
|
||||
current_pos.y + current_size.height / 2.0 - inner_size.1 / 2.0,
|
||||
);
|
||||
|
||||
let config = CreateWindowConfig {
|
||||
label: label.as_str(),
|
||||
title,
|
||||
url,
|
||||
inner_size,
|
||||
position,
|
||||
};
|
||||
|
||||
let child_window = create_window(&app_handle, config);
|
||||
|
||||
// NOTE: These listeners will remain active even when the windows close. Unfortunately,
|
||||
// there's no way to unlisten to events for now, so we just have to be defensive.
|
||||
|
||||
{
|
||||
let parent_window = parent_window.clone();
|
||||
let child_window = child_window.clone();
|
||||
child_window.clone().on_window_event(move |e| match e {
|
||||
// When the new window is destroyed, bring the other up behind it
|
||||
WindowEvent::Destroyed => {
|
||||
if let Some(w) = parent_window.get_webview_window(child_window.label()) {
|
||||
w.set_focus().unwrap();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
let parent_window = parent_window.clone();
|
||||
let child_window = child_window.clone();
|
||||
parent_window.clone().on_window_event(move |e| match e {
|
||||
// When the parent window is closed, close the child
|
||||
WindowEvent::CloseRequested { .. } => child_window.destroy().unwrap(),
|
||||
// When the parent window is focused, bring the child above
|
||||
WindowEvent::Focused(focus) => {
|
||||
if *focus {
|
||||
if let Some(w) = parent_window.get_webview_window(child_window.label()) {
|
||||
w.set_focus().unwrap();
|
||||
};
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn cmd_new_nested_window(
|
||||
window: WebviewWindow,
|
||||
url: &str,
|
||||
label: &str,
|
||||
title: &str,
|
||||
) -> Result<(), String> {
|
||||
create_nested_window(&window, label, url, title);
|
||||
async fn cmd_new_main_window(app_handle: AppHandle, url: &str) -> Result<(), String> {
|
||||
create_main_window(&app_handle, url);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1721,7 +1787,18 @@ pub fn run() {
|
||||
.build(),
|
||||
)
|
||||
.plugin(tauri_plugin_clipboard_manager::init())
|
||||
.plugin(tauri_plugin_window_state::Builder::default().build())
|
||||
.plugin(
|
||||
tauri_plugin_window_state::Builder::default()
|
||||
.with_denylist(&["ignored"])
|
||||
.map_label(|label| {
|
||||
if label.starts_with(OTHER_WINDOW_PREFIX) {
|
||||
"ignored"
|
||||
} else {
|
||||
label
|
||||
}
|
||||
})
|
||||
.build(),
|
||||
)
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.plugin(tauri_plugin_updater::Builder::default().build())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
@@ -1810,8 +1887,8 @@ pub fn run() {
|
||||
cmd_list_plugins,
|
||||
cmd_list_workspaces,
|
||||
cmd_metadata,
|
||||
cmd_new_nested_window,
|
||||
cmd_new_window,
|
||||
cmd_new_child_window,
|
||||
cmd_new_main_window,
|
||||
cmd_parse_template,
|
||||
cmd_plugin_info,
|
||||
cmd_reload_plugins,
|
||||
@@ -1844,7 +1921,7 @@ pub fn run() {
|
||||
.run(|app_handle, event| {
|
||||
match event {
|
||||
RunEvent::Ready => {
|
||||
let w = create_window(app_handle, "/");
|
||||
let w = create_main_window(app_handle, "/");
|
||||
tauri::async_runtime::spawn(async move {
|
||||
let info = analytics::track_launch_event(&w).await;
|
||||
debug!("Launched Yaak {:?}", info);
|
||||
@@ -1866,7 +1943,9 @@ pub fn run() {
|
||||
tauri::async_runtime::spawn(async move {
|
||||
let val: State<'_, Mutex<YaakUpdater>> = h.state();
|
||||
let update_mode = get_update_mode(&h).await;
|
||||
_ = val.lock().await.check(&h, update_mode).await;
|
||||
if let Err(e) = val.lock().await.check(&h, update_mode).await {
|
||||
warn!("Failed to check for updates {e:?}");
|
||||
};
|
||||
});
|
||||
|
||||
let h = app_handle.clone();
|
||||
@@ -1897,47 +1976,31 @@ fn is_dev() -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn create_nested_window(
|
||||
window: &WebviewWindow,
|
||||
label: &str,
|
||||
url: &str,
|
||||
title: &str,
|
||||
) -> WebviewWindow {
|
||||
info!("Create new nested window label={label}");
|
||||
let mut win_builder = tauri::WebviewWindowBuilder::new(
|
||||
window,
|
||||
format!("nested_{}_{}", window.label(), label),
|
||||
WebviewUrl::App(url.into()),
|
||||
)
|
||||
.resizable(true)
|
||||
.fullscreen(false)
|
||||
.disable_drag_drop_handler() // Required for frontend Dnd on windows
|
||||
.title(title)
|
||||
.parent(&window)
|
||||
.unwrap()
|
||||
.min_inner_size(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT)
|
||||
.inner_size(DEFAULT_WINDOW_WIDTH * 0.7, DEFAULT_WINDOW_HEIGHT * 0.9);
|
||||
|
||||
// Add macOS-only things
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
win_builder = win_builder
|
||||
.hidden_title(true)
|
||||
.title_bar_style(TitleBarStyle::Overlay);
|
||||
}
|
||||
|
||||
// Add non-macOS things
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
win_builder = win_builder.decorations(false);
|
||||
}
|
||||
|
||||
let win = win_builder.build().expect("failed to build window");
|
||||
|
||||
win
|
||||
fn create_main_window(handle: &AppHandle, url: &str) -> WebviewWindow {
|
||||
let label = format!("{MAIN_WINDOW_PREFIX}{}", handle.webview_windows().len());
|
||||
let config = CreateWindowConfig {
|
||||
url,
|
||||
label: label.as_str(),
|
||||
title: "Yaak",
|
||||
inner_size: (DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT),
|
||||
position: (
|
||||
// Offset by random amount so it's easier to differentiate
|
||||
100.0 + random::<f64>() * 20.0,
|
||||
100.0 + random::<f64>() * 20.0,
|
||||
),
|
||||
};
|
||||
create_window(handle, config)
|
||||
}
|
||||
|
||||
fn create_window(handle: &AppHandle, url: &str) -> WebviewWindow {
|
||||
struct CreateWindowConfig<'s> {
|
||||
url: &'s str,
|
||||
label: &'s str,
|
||||
title: &'s str,
|
||||
inner_size: (f64, f64),
|
||||
position: (f64, f64),
|
||||
}
|
||||
|
||||
fn create_window(handle: &AppHandle, config: CreateWindowConfig) -> WebviewWindow {
|
||||
#[allow(unused_variables)]
|
||||
let menu = app_menu(handle).unwrap();
|
||||
|
||||
@@ -1945,22 +2008,17 @@ fn create_window(handle: &AppHandle, url: &str) -> WebviewWindow {
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
handle.set_menu(menu).expect("Failed to set app menu");
|
||||
|
||||
let window_num = handle.webview_windows().len();
|
||||
let label = format!("{MAIN_WINDOW_PREFIX}{window_num}");
|
||||
info!("Create new window label={label}");
|
||||
info!("Create new window label={}", config.label);
|
||||
|
||||
let mut win_builder =
|
||||
tauri::WebviewWindowBuilder::new(handle, label, WebviewUrl::App(url.into()))
|
||||
tauri::WebviewWindowBuilder::new(handle, config.label, WebviewUrl::App(config.url.into()))
|
||||
.title(config.title)
|
||||
.resizable(true)
|
||||
.fullscreen(false)
|
||||
.disable_drag_drop_handler() // Required for frontend Dnd on windows
|
||||
.inner_size(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT)
|
||||
.position(
|
||||
// Randomly offset so windows don't stack exactly
|
||||
100.0 + random::<f64>() * 30.0,
|
||||
100.0 + random::<f64>() * 30.0,
|
||||
)
|
||||
.min_inner_size(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT)
|
||||
.title(handle.package_info().name.to_string());
|
||||
.inner_size(config.inner_size.0, config.inner_size.1)
|
||||
.position(config.position.0, config.position.1)
|
||||
.min_inner_size(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT);
|
||||
|
||||
// Add macOS-only things
|
||||
#[cfg(target_os = "macos")]
|
||||
@@ -1977,7 +2035,16 @@ fn create_window(handle: &AppHandle, url: &str) -> WebviewWindow {
|
||||
win_builder = win_builder.decorations(false);
|
||||
}
|
||||
|
||||
let win = win_builder.build().expect("failed to build window");
|
||||
if let Some(w) = handle.webview_windows().get(config.label) {
|
||||
info!(
|
||||
"Webview with label {} already exists. Focusing existing",
|
||||
config.label
|
||||
);
|
||||
w.set_focus().unwrap();
|
||||
return w.to_owned();
|
||||
}
|
||||
|
||||
let win = win_builder.build().unwrap();
|
||||
|
||||
let webview_window = win.clone();
|
||||
win.on_menu_event(move |w, event| {
|
||||
@@ -1994,10 +2061,13 @@ fn create_window(handle: &AppHandle, url: &str) -> WebviewWindow {
|
||||
"zoom_out" => w.emit("zoom_out", true).unwrap(),
|
||||
"settings" => w.emit("settings", true).unwrap(),
|
||||
"open_feedback" => {
|
||||
_ = webview_window
|
||||
if let Err(e) = webview_window
|
||||
.app_handle()
|
||||
.shell()
|
||||
.open("https://yaak.app/roadmap", None)
|
||||
.open("https://yaak.app/feedback", None)
|
||||
{
|
||||
warn!("Failed to open feedback {e:?}")
|
||||
}
|
||||
}
|
||||
|
||||
// Commands for development
|
||||
|
||||
@@ -2,7 +2,11 @@ use hex_color::HexColor;
|
||||
use log::warn;
|
||||
use objc::{msg_send, sel, sel_impl};
|
||||
use rand::{distributions::Alphanumeric, Rng};
|
||||
use tauri::{plugin::{Builder, TauriPlugin}, Manager, Runtime, Window, WindowEvent, Emitter, Listener};
|
||||
use tauri::{
|
||||
plugin::{Builder, TauriPlugin},
|
||||
Emitter, Listener, Manager, Runtime, Window, WindowEvent,
|
||||
};
|
||||
use crate::MAIN_WINDOW_PREFIX;
|
||||
|
||||
const WINDOW_CONTROL_PAD_X: f64 = 13.0;
|
||||
const WINDOW_CONTROL_PAD_Y: f64 = 18.0;
|
||||
@@ -127,7 +131,7 @@ fn update_window_theme<R: Runtime>(window: Window<R>, color: HexColor) {
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn position_traffic_lights(ns_window_handle: UnsafeWindowHandle, x: f64, y: f64, label: String) {
|
||||
if label.starts_with("nested_") {
|
||||
if !label.starts_with(MAIN_WINDOW_PREFIX) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import classNames from 'classnames';
|
||||
import { search } from 'fast-fuzzy';
|
||||
import type { KeyboardEvent, ReactNode } from 'react';
|
||||
import { useEffect, useRef, useCallback, useMemo, useState } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useActiveCookieJar } from '../hooks/useActiveCookieJar';
|
||||
import { useActiveEnvironment } from '../hooks/useActiveEnvironment';
|
||||
import { useActiveRequest } from '../hooks/useActiveRequest';
|
||||
import { useActiveWorkspace } from '../hooks/useActiveWorkspace';
|
||||
import { useAppRoutes } from '../hooks/useAppRoutes';
|
||||
import { useCreateEnvironment } from '../hooks/useCreateEnvironment';
|
||||
import { useCreateGrpcRequest } from '../hooks/useCreateGrpcRequest';
|
||||
@@ -17,6 +16,7 @@ import { useEnvironments } from '../hooks/useEnvironments';
|
||||
import type { HotkeyAction } from '../hooks/useHotKey';
|
||||
import { useHotKey } from '../hooks/useHotKey';
|
||||
import { useHttpRequestActions } from '../hooks/useHttpRequestActions';
|
||||
import { useOpenSettings } from '../hooks/useOpenSettings';
|
||||
import { useOpenWorkspace } from '../hooks/useOpenWorkspace';
|
||||
import { useRecentEnvironments } from '../hooks/useRecentEnvironments';
|
||||
import { useRecentRequests } from '../hooks/useRecentRequests';
|
||||
@@ -28,7 +28,6 @@ import { useSendAnyHttpRequest } from '../hooks/useSendAnyHttpRequest';
|
||||
import { useSidebarHidden } from '../hooks/useSidebarHidden';
|
||||
import { useWorkspaces } from '../hooks/useWorkspaces';
|
||||
import { fallbackRequestName } from '../lib/fallbackRequestName';
|
||||
import { invokeCmd } from '../lib/tauri';
|
||||
import { CookieDialog } from './CookieDialog';
|
||||
import { Button } from './core/Button';
|
||||
import { Heading } from './core/Heading';
|
||||
@@ -74,11 +73,11 @@ export function CommandPalette({ onClose }: { onClose: () => void }) {
|
||||
const createGrpcRequest = useCreateGrpcRequest();
|
||||
const createEnvironment = useCreateEnvironment();
|
||||
const dialog = useDialog();
|
||||
const workspace = useActiveWorkspace();
|
||||
const sendRequest = useSendAnyHttpRequest();
|
||||
const renameRequest = useRenameRequest(activeRequest?.id ?? null);
|
||||
const deleteRequest = useDeleteRequest(activeRequest?.id ?? null);
|
||||
const [, setSidebarHidden] = useSidebarHidden();
|
||||
const openSettings = useOpenSettings();
|
||||
|
||||
const workspaceCommands = useMemo<CommandPaletteItem[]>(() => {
|
||||
const commands: CommandPaletteItem[] = [
|
||||
@@ -86,14 +85,7 @@ export function CommandPalette({ onClose }: { onClose: () => void }) {
|
||||
key: 'settings.open',
|
||||
label: 'Open Settings',
|
||||
action: 'settings.show',
|
||||
onSelect: async () => {
|
||||
if (workspace == null) return;
|
||||
await invokeCmd('cmd_new_nested_window', {
|
||||
url: routes.paths.workspaceSettings({ workspaceId: workspace.id }),
|
||||
label: 'settings',
|
||||
title: 'Yaak Settings',
|
||||
});
|
||||
},
|
||||
onSelect: openSettings.mutate,
|
||||
},
|
||||
{
|
||||
key: 'app.create',
|
||||
@@ -195,11 +187,10 @@ export function CommandPalette({ onClose }: { onClose: () => void }) {
|
||||
deleteRequest.mutate,
|
||||
dialog,
|
||||
httpRequestActions,
|
||||
openSettings.mutate,
|
||||
renameRequest.mutate,
|
||||
routes.paths,
|
||||
sendRequest,
|
||||
setSidebarHidden,
|
||||
workspace,
|
||||
]);
|
||||
|
||||
const sortedRequests = useMemo(() => {
|
||||
|
||||
@@ -160,9 +160,8 @@ export function GlobalHooks() {
|
||||
return;
|
||||
}
|
||||
|
||||
const { interfaceScale, interfaceFontSize, editorFontSize } = settings;
|
||||
const { interfaceScale, editorFontSize } = settings;
|
||||
getCurrentWebviewWindow().setZoom(interfaceScale).catch(console.error);
|
||||
document.documentElement.style.setProperty('font-size', `${interfaceFontSize}px`);
|
||||
document.documentElement.style.setProperty('--editor-font-size', `${editorFontSize}px`);
|
||||
}, [settings]);
|
||||
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import { open } from '@tauri-apps/plugin-shell';
|
||||
import { useRef } from 'react';
|
||||
import { useActiveWorkspace } from '../hooks/useActiveWorkspace';
|
||||
import { useAppInfo } from '../hooks/useAppInfo';
|
||||
import { useAppRoutes } from '../hooks/useAppRoutes';
|
||||
import { useCheckForUpdates } from '../hooks/useCheckForUpdates';
|
||||
import { useExportData } from '../hooks/useExportData';
|
||||
import { useImportData } from '../hooks/useImportData';
|
||||
import { useListenToTauriEvent } from '../hooks/useListenToTauriEvent';
|
||||
import { invokeCmd } from '../lib/tauri';
|
||||
import { useOpenSettings } from '../hooks/useOpenSettings';
|
||||
import type { DropdownRef } from './core/Dropdown';
|
||||
import { Dropdown } from './core/Dropdown';
|
||||
import { Icon } from './core/Icon';
|
||||
@@ -22,19 +20,9 @@ export function SettingsDropdown() {
|
||||
const dropdownRef = useRef<DropdownRef>(null);
|
||||
const dialog = useDialog();
|
||||
const checkForUpdates = useCheckForUpdates();
|
||||
const routes = useAppRoutes();
|
||||
const workspace = useActiveWorkspace();
|
||||
const openSettings = useOpenSettings();
|
||||
|
||||
const showSettings = async () => {
|
||||
if (!workspace) return;
|
||||
await invokeCmd('cmd_new_nested_window', {
|
||||
url: routes.paths.workspaceSettings({ workspaceId: workspace.id }),
|
||||
label: 'settings',
|
||||
title: 'Yaak Settings',
|
||||
});
|
||||
};
|
||||
|
||||
useListenToTauriEvent('settings', showSettings);
|
||||
useListenToTauriEvent('settings', () => openSettings.mutate());
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
@@ -45,7 +33,7 @@ export function SettingsDropdown() {
|
||||
label: 'Settings',
|
||||
hotKeyAction: 'settings.show',
|
||||
leftSlot: <Icon icon="settings" />,
|
||||
onSelect: showSettings,
|
||||
onSelect: openSettings.mutate,
|
||||
},
|
||||
{
|
||||
key: 'hotkeys',
|
||||
|
||||
15
src-web/font-size.ts
Normal file
15
src-web/font-size.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
// Listen for settings changes, the re-compute theme
|
||||
import { listen } from '@tauri-apps/api/event';
|
||||
import type { ModelPayload } from './components/GlobalHooks';
|
||||
import { getSettings } from './lib/store';
|
||||
|
||||
function setFontSizeOnDocument(fontSize: number) {
|
||||
document.documentElement.style.fontSize = `${fontSize}px`;
|
||||
}
|
||||
|
||||
listen<ModelPayload>('upserted_model', async (event) => {
|
||||
if (event.payload.model.model !== 'settings') return;
|
||||
setFontSizeOnDocument(event.payload.model.interfaceFontSize);
|
||||
}).catch(console.error);
|
||||
|
||||
getSettings().then((settings) => setFontSizeOnDocument(settings.interfaceFontSize));
|
||||
22
src-web/hooks/useOpenSettings.ts
Normal file
22
src-web/hooks/useOpenSettings.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { useMutation } from '@tanstack/react-query';
|
||||
import { invokeCmd } from '../lib/tauri';
|
||||
import { useActiveWorkspace } from './useActiveWorkspace';
|
||||
import { useAppRoutes } from './useAppRoutes';
|
||||
|
||||
export function useOpenSettings() {
|
||||
const routes = useAppRoutes();
|
||||
const workspace = useActiveWorkspace();
|
||||
return useMutation({
|
||||
mutationKey: ['open_settings'],
|
||||
mutationFn: async () => {
|
||||
if (workspace == null) return;
|
||||
|
||||
await invokeCmd('cmd_new_child_window', {
|
||||
url: routes.paths.workspaceSettings({ workspaceId: workspace.id }),
|
||||
label: 'settings',
|
||||
title: 'Yaak Settings',
|
||||
innerSize: [600, 550],
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -26,7 +26,7 @@ export function useOpenWorkspace() {
|
||||
requestId != null
|
||||
? routes.paths.request({ ...baseArgs, requestId })
|
||||
: routes.paths.workspace({ ...baseArgs });
|
||||
await invokeCmd('cmd_new_window', { url: path });
|
||||
await invokeCmd('cmd_new_main_window', { url: path });
|
||||
} else {
|
||||
if (requestId != null) {
|
||||
routes.navigate('request', { ...baseArgs, requestId });
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
<div id="react-portal"></div>
|
||||
<div id="radix-portal" class="cm-portal"></div>
|
||||
<script type="module" src="/theme.ts"></script>
|
||||
<script type="module" src="/font-size.ts"></script>
|
||||
<script type="module" src="/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -51,8 +51,8 @@ type TauriCmd =
|
||||
| 'cmd_list_plugins'
|
||||
| 'cmd_list_workspaces'
|
||||
| 'cmd_metadata'
|
||||
| 'cmd_new_nested_window'
|
||||
| 'cmd_new_window'
|
||||
| 'cmd_new_main_window'
|
||||
| 'cmd_new_child_window'
|
||||
| 'cmd_parse_template'
|
||||
| 'cmd_plugin_info'
|
||||
| 'cmd_render_template'
|
||||
|
||||
Reference in New Issue
Block a user