Fix tauri event listener hook

This commit is contained in:
Gregory Schier
2025-01-04 07:01:31 -08:00
parent 36cecb2d29
commit 592c1228f1
12 changed files with 30 additions and 105 deletions

View File

@@ -39,7 +39,7 @@ export type SidebarModel = Folder | GrpcRequest | HttpRequest;
export function Sidebar({ className }: Props) {
const [hidden, setHidden] = useSidebarHidden();
const sidebarRef = useRef<HTMLLIElement>(null);
const sidebarRef = useRef<HTMLElement>(null);
const activeWorkspace = useActiveWorkspace();
const httpResponses = useHttpResponses();
const grpcConnections = useGrpcConnections();
@@ -326,7 +326,7 @@ export function Sidebar({ className }: Props) {
return (
<aside
aria-hidden={hidden}
aria-hidden={hidden ?? undefined}
ref={sidebarRef}
onFocus={handleFocus}
onBlur={handleBlur}

View File

@@ -87,9 +87,9 @@ export function Dialog({
)}
{description ? (
<p className="px-6 text-text-subtle" id={descriptionId}>
<div className="px-6 text-text-subtle" id={descriptionId}>
{description}
</p>
</div>
) : (
<span />
)}

View File

@@ -2,15 +2,11 @@ import { useNavigate } from '@tanstack/react-router';
import type { Folder, Workspace } from '@yaakapp-internal/models';
import { useMemo } from 'react';
import { trackEvent } from '../lib/analytics';
import { jotaiStore } from '../lib/jotai';
import { invokeCmd } from '../lib/tauri';
import { getActiveWorkspaceId } from './useActiveWorkspace';
import { createFastMutation } from './useFastMutation';
import { foldersAtom } from './useFolders';
import { usePrompt } from './usePrompt';
import { updateModelList } from './useSyncModelStores';
import { useToast } from './useToast';
import { workspacesAtom } from './useWorkspaces';
function makeCommands({
navigate,
@@ -25,9 +21,6 @@ function makeCommands({
mutationKey: ['create_workspace'],
mutationFn: (patch) => invokeCmd<Workspace>('cmd_update_workspace', { workspace: patch }),
onSuccess: async (workspace) => {
// Optimistic update
jotaiStore.set(workspacesAtom, updateModelList(workspace));
await navigate({
to: '/workspaces/$workspaceId',
params: { workspaceId: workspace.id },
@@ -65,12 +58,6 @@ function makeCommands({
patch.sortPriority = patch.sortPriority || -Date.now();
return invokeCmd<Folder>('cmd_update_folder', { folder: { workspaceId, ...patch } });
},
onSuccess: async (folder) => {
if (folder == null) return;
// Optimistic update
jotaiStore.set(foldersAtom, updateModelList(folder));
},
onSettled: () => trackEvent('folder', 'create'),
}),
} as const;

View File

@@ -1,16 +1,12 @@
import type { CookieJar } from '@yaakapp-internal/models';
import { useSetAtom } from 'jotai';
import { trackEvent } from '../lib/analytics';
import { invokeCmd } from '../lib/tauri';
import { getActiveWorkspaceId } from './useActiveWorkspace';
import { cookieJarsAtom } from './useCookieJars';
import { useFastMutation } from './useFastMutation';
import { usePrompt } from './usePrompt';
import { updateModelList } from './useSyncModelStores';
export function useCreateCookieJar() {
const prompt = usePrompt();
const setCookieJars = useSetAtom(cookieJarsAtom);
return useFastMutation<CookieJar | null>({
mutationKey: ['create_cookie_jar'],
@@ -31,12 +27,6 @@ export function useCreateCookieJar() {
return invokeCmd('cmd_create_cookie_jar', { workspaceId, name });
},
onSuccess: (cookieJar) => {
if (cookieJar == null) return;
// Optimistic update
setCookieJars(updateModelList(cookieJar));
},
onSettled: () => trackEvent('cookie_jar', 'create'),
});
}

View File

@@ -1,18 +1,14 @@
import type { Environment } from '@yaakapp-internal/models';
import { useSetAtom } from 'jotai';
import { trackEvent } from '../lib/analytics';
import { invokeCmd } from '../lib/tauri';
import { useActiveEnvironment } from './useActiveEnvironment';
import { getActiveWorkspaceId } from './useActiveWorkspace';
import { environmentsAtom } from './useEnvironments';
import { useFastMutation } from './useFastMutation';
import { usePrompt } from './usePrompt';
import { updateModelList } from './useSyncModelStores';
export function useCreateEnvironment() {
const [, setActiveEnvironmentId] = useActiveEnvironment();
const prompt = usePrompt();
const setEnvironments = useSetAtom(environmentsAtom);
return useFastMutation<Environment | null, unknown, Environment | null>({
mutationKey: ['create_environment'],
@@ -43,10 +39,6 @@ export function useCreateEnvironment() {
onSettled: () => trackEvent('environment', 'create'),
onSuccess: async (environment) => {
if (environment == null) return;
// Optimistic update
setEnvironments(updateModelList(environment));
await setActiveEnvironmentId(environment.id);
},
});

View File

@@ -1,17 +1,13 @@
import { useNavigate } from '@tanstack/react-router';
import type { GrpcRequest } from '@yaakapp-internal/models';
import { useSetAtom } from 'jotai';
import { trackEvent } from '../lib/analytics';
import { jotaiStore } from '../lib/jotai';
import { invokeCmd } from '../lib/tauri';
import { getActiveRequest } from './useActiveRequest';
import { activeWorkspaceAtom } from './useActiveWorkspace';
import { useFastMutation } from './useFastMutation';
import { grpcRequestsAtom } from './useGrpcRequests';
import { updateModelList } from './useSyncModelStores';
export function useCreateGrpcRequest() {
const setGrpcRequests = useSetAtom(grpcRequestsAtom);
const navigate = useNavigate();
return useFastMutation<
@@ -44,9 +40,6 @@ export function useCreateGrpcRequest() {
},
onSettled: () => trackEvent('grpc_request', 'create'),
onSuccess: async (request) => {
// Optimistic update
setGrpcRequests(updateModelList(request));
await navigate({
to: '/workspaces/$workspaceId/requests/$requestId',
params: {

View File

@@ -1,16 +1,12 @@
import { useNavigate } from '@tanstack/react-router';
import type { HttpRequest } from '@yaakapp-internal/models';
import { useSetAtom } from 'jotai/index';
import { trackEvent } from '../lib/analytics';
import { invokeCmd } from '../lib/tauri';
import { getActiveRequest } from './useActiveRequest';
import { getActiveWorkspaceId } from './useActiveWorkspace';
import { useFastMutation } from './useFastMutation';
import { httpRequestsAtom } from './useHttpRequests';
import { updateModelList } from './useSyncModelStores';
export function useCreateHttpRequest() {
const setHttpRequests = useSetAtom(httpRequestsAtom);
const navigate = useNavigate();
return useFastMutation<HttpRequest, unknown, Partial<HttpRequest>>({
@@ -38,9 +34,6 @@ export function useCreateHttpRequest() {
},
onSettled: () => trackEvent('http_request', 'create'),
onSuccess: async (request) => {
// Optimistic update
setHttpRequests(updateModelList(request));
await navigate({
to: '/workspaces/$workspaceId/requests/$requestId',
params: { workspaceId: request.workspaceId, requestId: request.id },

View File

@@ -1,18 +1,14 @@
import { useNavigate } from '@tanstack/react-router';
import type { Workspace } from '@yaakapp-internal/models';
import { useSetAtom } from 'jotai';
import { InlineCode } from '../components/core/InlineCode';
import { trackEvent } from '../lib/analytics';
import { invokeCmd } from '../lib/tauri';
import { getActiveWorkspace } from './useActiveWorkspace';
import { useConfirm } from './useConfirm';
import { useFastMutation } from './useFastMutation';
import { removeModelById } from './useSyncModelStores';
import { workspacesAtom } from './useWorkspaces';
export function useDeleteActiveWorkspace() {
const confirm = useConfirm();
const setWorkspaces = useSetAtom(workspacesAtom);
const navigate = useNavigate();
return useFastMutation<Workspace | null, string>({
@@ -35,10 +31,6 @@ export function useDeleteActiveWorkspace() {
onSettled: () => trackEvent('workspace', 'delete'),
onSuccess: async (workspace) => {
if (workspace === null) return;
// Optimistic update
setWorkspaces(removeModelById(workspace));
await navigate({ to: '/workspaces' });
},
});

View File

@@ -1,18 +1,14 @@
import { useFastMutation } from './useFastMutation';
import type { GrpcRequest } from '@yaakapp-internal/models';
import {useSetAtom} from "jotai";
import { InlineCode } from '../components/core/InlineCode';
import { trackEvent } from '../lib/analytics';
import { fallbackRequestName } from '../lib/fallbackRequestName';
import { getGrpcRequest } from '../lib/store';
import { invokeCmd } from '../lib/tauri';
import { useConfirm } from './useConfirm';
import {grpcRequestsAtom} from "./useGrpcRequests";
import {removeModelById} from "./useSyncModelStores";
import { useFastMutation } from './useFastMutation';
export function useDeleteAnyGrpcRequest() {
const confirm = useConfirm();
const setGrpcRequests = useSetAtom(grpcRequestsAtom);
return useFastMutation<GrpcRequest | null, string, string>({
mutationKey: ['delete_any_grpc_request'],
@@ -33,12 +29,6 @@ export function useDeleteAnyGrpcRequest() {
if (!confirmed) return null;
return invokeCmd('cmd_delete_grpc_request', { requestId: id });
},
onSuccess: (request) => {
if (request == null) return;
// Optimistic update
setGrpcRequests(removeModelById(request));
},
onSettled: () => trackEvent('grpc_request', 'delete'),
});
}

View File

@@ -1,18 +1,14 @@
import { useFastMutation } from './useFastMutation';
import type { HttpRequest } from '@yaakapp-internal/models';
import { useSetAtom } from 'jotai';
import { InlineCode } from '../components/core/InlineCode';
import { trackEvent } from '../lib/analytics';
import { fallbackRequestName } from '../lib/fallbackRequestName';
import { getHttpRequest } from '../lib/store';
import { invokeCmd } from '../lib/tauri';
import { useConfirm } from './useConfirm';
import { httpRequestsAtom } from './useHttpRequests';
import { removeModelById } from './useSyncModelStores';
import { useFastMutation } from './useFastMutation';
export function useDeleteAnyHttpRequest() {
const confirm = useConfirm();
const setHttpRequests = useSetAtom(httpRequestsAtom);
return useFastMutation<HttpRequest | null, string, string>({
mutationKey: ['delete_any_http_request'],
@@ -33,12 +29,6 @@ export function useDeleteAnyHttpRequest() {
if (!confirmed) return null;
return invokeCmd<HttpRequest>('cmd_delete_http_request', { requestId: id });
},
onSuccess: (request) => {
if (request == null) return;
// Optimistic update
setHttpRequests(removeModelById(request));
},
onSettled: () => trackEvent('http_request', 'delete'),
});
}

View File

@@ -1,35 +1,22 @@
import type { EventCallback, EventName } from '@tauri-apps/api/event';
import { listen } from '@tauri-apps/api/event';
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
import type { DependencyList } from 'react';
import { useEffect } from 'react';
import type {EventCallback, EventName} from '@tauri-apps/api/event';
import {listen} from '@tauri-apps/api/event';
import {getCurrentWebviewWindow} from '@tauri-apps/api/webviewWindow';
import {useEffect} from 'react';
/**
* React hook to listen to a Tauri event.
*/
export function useListenToTauriEvent<T>(
event: EventName,
fn: EventCallback<T>,
deps: DependencyList = [],
) {
export function useListenToTauriEvent<T>(event: EventName, fn: EventCallback<T>) {
useEffect(() => {
let unMounted = false;
let unsubFn: (() => void) | undefined = undefined;
listen(
const unlisten = listen(
event,
fn,
// Listen to `emit_all()` events or events specific to the current window
{ target: { label: getCurrentWebviewWindow().label, kind: 'Window' } },
).then((unsub) => {
if (unMounted) unsub();
else unsubFn = unsub;
});
);
return () => {
unMounted = true;
unsubFn?.();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [event, fn, ...deps]);
unlisten.then((fn) => fn());
}
}, [event, fn]);
}

View File

@@ -20,9 +20,20 @@ if (osType !== 'macos') {
}
window.addEventListener('keydown', (e) => {
// Hack to not go back in history on backspace. Check for document body
// or else it will prevent backspace in input fields.
if (e.key === 'Backspace' && e.target === document.body) e.preventDefault();
const rx = /input|select|textarea/i;
const target = e.target;
if (e.key !== 'Backspace') return;
if (!(target instanceof Element)) return;
if (target.getAttribute('contenteditable') !== null) return;
if (
!rx.test(target.tagName) ||
('disabled' in target && target.disabled) ||
('readOnly' in target && target.readOnly)
) {
e.preventDefault();
}
});
console.log('Creating React root');