Fix(ish) multiwindow updates

This commit is contained in:
Gregory Schier
2023-03-29 11:15:37 -07:00
parent cd5ae6691c
commit b91d1b8b3c
4 changed files with 59 additions and 35 deletions

View File

@@ -13,16 +13,16 @@ use std::env::current_dir;
use std::fs::create_dir_all; use std::fs::create_dir_all;
use base64::Engine; use base64::Engine;
use http::header::{HeaderName, ACCEPT, USER_AGENT};
use http::{HeaderMap, HeaderValue, Method}; use http::{HeaderMap, HeaderValue, Method};
use http::header::{ACCEPT, HeaderName, USER_AGENT};
use reqwest::redirect::Policy; use reqwest::redirect::Policy;
use sqlx::{Pool, Sqlite};
use sqlx::migrate::Migrator; use sqlx::migrate::Migrator;
use sqlx::sqlite::SqlitePoolOptions; use sqlx::sqlite::SqlitePoolOptions;
use sqlx::types::Json; use sqlx::types::Json;
use sqlx::{Pool, Sqlite};
use tauri::regex::Regex;
use tauri::{AppHandle, Menu, MenuItem, State, Submenu, TitleBarStyle, Window, Wry}; use tauri::{AppHandle, Menu, MenuItem, State, Submenu, TitleBarStyle, Window, Wry};
use tauri::{CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, WindowEvent}; use tauri::{CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, WindowEvent};
use tauri::regex::Regex;
use tokio::sync::Mutex; use tokio::sync::Mutex;
use window_ext::WindowExt; use window_ext::WindowExt;
@@ -538,12 +538,6 @@ fn main() {
.system_tray(system_tray) .system_tray(system_tray)
.setup(|app| { .setup(|app| {
let handle = app.handle(); let handle = app.handle();
std::thread::spawn(move || {
let win = create_window(handle);
if let Err(e) = win.show() {
println!("Failed to show window {}", e)
}
});
let dir = match is_dev() { let dir = match is_dev() {
true => current_dir().unwrap(), true => current_dir().unwrap(),
false => app.path_resolver().app_data_dir().unwrap(), false => app.path_resolver().app_data_dir().unwrap(),
@@ -559,11 +553,21 @@ fn main() {
.connect(url.as_str()) .connect(url.as_str())
.await .await
.expect("Failed to connect to database"); .expect("Failed to connect to database");
// Create the initial window
let app_id = get_or_create_client_id(&pool).await;
let win = create_window(handle, app_id);
if let Err(e) = win.show() {
println!("Failed to show window {}", e)
}
// Setup the DB handle
let m = Mutex::new(pool); let m = Mutex::new(pool);
migrate_db(app.handle(), &m) migrate_db(app.handle(), &m)
.await .await
.expect("Failed to migrate database"); .expect("Failed to migrate database");
app.manage(m); app.manage(m);
Ok(()) Ok(())
}) })
}) })
@@ -609,7 +613,7 @@ fn is_dev() -> bool {
env.unwrap_or("production") != "production" env.unwrap_or("production") != "production"
} }
fn create_window(handle: AppHandle<Wry>) -> Window<Wry> { fn create_window(handle: AppHandle<Wry>, app_id: String) -> Window<Wry> {
let default_menu = Menu::os_default("Yaak".to_string().as_str()); let default_menu = Menu::os_default("Yaak".to_string().as_str());
let mut test_menu = Menu::new() let mut test_menu = Menu::new()
.add_item( .add_item(
@@ -646,8 +650,9 @@ fn create_window(handle: AppHandle<Wry>) -> Window<Wry> {
let submenu = Submenu::new("Test Menu", test_menu); let submenu = Submenu::new("Test Menu", test_menu);
let window_num = handle.windows().len();
let window_id = format!("{}_{}", app_id, window_num);
let menu = default_menu.add_submenu(submenu); let menu = default_menu.add_submenu(submenu);
let window_id = generate_id("win");
let win = tauri::WindowBuilder::new( let win = tauri::WindowBuilder::new(
&handle, &handle,
window_id, window_id,
@@ -664,28 +669,26 @@ fn create_window(handle: AppHandle<Wry>) -> Window<Wry> {
.expect("failed to build window"); .expect("failed to build window");
let win2 = win.clone(); let win2 = win.clone();
win.on_menu_event(move |event| { win.on_menu_event(move |event| match event.menu_item_id() {
match event.menu_item_id() { "quit" => std::process::exit(0),
"quit" => std::process::exit(0), "close" => win2.close().unwrap(),
"close" => win2.close().unwrap(), "zoom_reset" => win2.emit("zoom", 0).unwrap(),
"zoom_reset" => win2.emit("zoom", 0).unwrap(), "zoom_in" => win2.emit("zoom", 1).unwrap(),
"zoom_in" => win2.emit("zoom", 1).unwrap(), "zoom_out" => win2.emit("zoom", -1).unwrap(),
"zoom_out" => win2.emit("zoom", -1).unwrap(), "toggle_sidebar" => win2.emit("toggle_sidebar", true).unwrap(),
"toggle_sidebar" => win2.emit("toggle_sidebar", true).unwrap(), "refresh" => win2.emit("refresh", true).unwrap(),
"refresh" => win2.emit("refresh", true).unwrap(), "send_request" => win2.emit("send_request", true).unwrap(),
"send_request" => win2.emit("send_request", true).unwrap(), "new_window" => {
"new_window" => { create_window(handle.clone(), app_id.clone());
create_window(handle.clone()).show().unwrap(); }
"toggle_devtools" => {
if win2.is_devtools_open() {
win2.close_devtools();
} else {
win2.open_devtools();
} }
"toggle_devtools" => { }
if win2.is_devtools_open() { _ => {}
win2.close_devtools();
} else {
win2.open_devtools();
}
}
_ => {}
};
}); });
let win3 = win.clone(); let win3 = win.clone();
@@ -707,3 +710,16 @@ fn create_window(handle: AppHandle<Wry>) -> Window<Wry> {
win win
} }
async fn get_or_create_client_id(pool: &Pool<Sqlite>) -> String {
match models::get_key_value("global", "client_id", pool).await {
Some(kv) => kv.value,
None => {
let id = &generate_id("yaak");
models::set_key_value("global", "client_id", id, pool)
.await
.expect("Failed to set client id")
.value
}
}
}

View File

@@ -125,8 +125,12 @@ export const RequestPane = memo(function RequestPane({ style, fullHeight, classN
[], [],
); );
const forceUpdateKey = const forceUpdateKey = useMemo(() => {
activeRequest?.updatedBy === appWindow.label ? undefined : activeRequest?.updatedAt; if (activeRequest == null) return undefined;
if (activeRequest.updatedBy === appWindow.label) return appWindow.label;
return `${appWindow.label}::${activeRequest?.updatedAt}`;
}, [activeRequest]);
console.log('FORCE UPDATE KEY', forceUpdateKey);
return ( return (
<div <div

View File

@@ -1,5 +1,6 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api';
import { appWindow } from '@tauri-apps/api/window';
import type { HttpRequest } from '../lib/models'; import type { HttpRequest } from '../lib/models';
import { getRequest } from '../lib/store'; import { getRequest } from '../lib/store';
import { requestsQueryKey } from './useRequests'; import { requestsQueryKey } from './useRequests';
@@ -20,6 +21,9 @@ export function useUpdateRequest(id: string | null) {
const request = await getRequest(id); const request = await getRequest(id);
if (request === null) return; if (request === null) return;
// Sync updatedBy so that the UI doesn't think the update is coming from elsewhere
request.updatedBy = appWindow.label;
const newRequest = typeof v === 'function' ? v(request) : { ...request, ...v }; const newRequest = typeof v === 'function' ? v(request) : { ...request, ...v };
queryClient.setQueryData( queryClient.setQueryData(
requestsQueryKey(request?.workspaceId), requestsQueryKey(request?.workspaceId),

View File

@@ -2,7 +2,7 @@ export interface BaseModel {
readonly id: string; readonly id: string;
readonly createdAt: string; readonly createdAt: string;
readonly updatedAt: string; readonly updatedAt: string;
readonly updatedBy: string; updatedBy: string;
} }
export interface Workspace extends BaseModel { export interface Workspace extends BaseModel {