import { useQueryClient } from '@tanstack/react-query'; import { appWindow } from '@tauri-apps/api/window'; import { keyValueQueryKey } from '../hooks/useKeyValue'; import { requestsQueryKey } from '../hooks/useRequests'; import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey'; import { responsesQueryKey } from '../hooks/useResponses'; import { useListenToTauriEvent } from '../hooks/useListenToTauriEvent'; import { workspacesQueryKey } from '../hooks/useWorkspaces'; import { DEFAULT_FONT_SIZE } from '../lib/constants'; import { NAMESPACE_NO_SYNC } from '../lib/keyValueStore'; import type { HttpRequest, HttpResponse, Model, Workspace } from '../lib/models'; import { modelsEq } from '../lib/models'; import { useRecentRequests } from '../hooks/useRecentRequests'; import { useRecentWorkspaces } from '../hooks/useRecentWorkspaces'; import { useRecentEnvironments } from '../hooks/useRecentEnvironments'; import { useLocation } from 'react-router-dom'; import { useEffect } from 'react'; import { setPathname } from '../lib/persistPathname'; export function GlobalHooks() { // Include here so they always update, even // if no component references them useRecentWorkspaces(); useRecentEnvironments(); useRecentRequests(); const queryClient = useQueryClient(); const { wasUpdatedExternally } = useRequestUpdateKey(null); // Listen for location changes and update the pathname const location = useLocation(); useEffect(() => { setPathname(location.pathname); }, [location.pathname]); useListenToTauriEvent('created_model', ({ payload, windowLabel }) => { if (shouldIgnoreEvent(payload, windowLabel)) return; const queryKey = payload.model === 'http_request' ? requestsQueryKey(payload) : payload.model === 'http_response' ? responsesQueryKey(payload) : payload.model === 'workspace' ? workspacesQueryKey(payload) : payload.model === 'key_value' ? keyValueQueryKey(payload) : null; if (queryKey === null) { console.log('Unrecognized created model:', payload); return; } if (!shouldIgnoreModel(payload)) { // Order newest first queryClient.setQueryData(queryKey, (values) => [payload, ...(values ?? [])]); } }); useListenToTauriEvent('updated_model', ({ payload, windowLabel }) => { if (shouldIgnoreEvent(payload, windowLabel)) return; const queryKey = payload.model === 'http_request' ? requestsQueryKey(payload) : payload.model === 'http_response' ? responsesQueryKey(payload) : payload.model === 'workspace' ? workspacesQueryKey(payload) : payload.model === 'key_value' ? keyValueQueryKey(payload) : null; if (queryKey === null) { console.log('Unrecognized updated model:', payload); return; } if (payload.model === 'http_request') { wasUpdatedExternally(payload.id); } if (!shouldIgnoreModel(payload)) { queryClient.setQueryData( queryKey, (values) => values?.map((v) => (modelsEq(v, payload) ? payload : v)), ); } }); useListenToTauriEvent('deleted_model', ({ payload, windowLabel }) => { if (shouldIgnoreEvent(payload, windowLabel)) return; if (shouldIgnoreModel(payload)) return; if (payload.model === 'workspace') { queryClient.setQueryData(workspacesQueryKey(), removeById(payload)); } else if (payload.model === 'http_request') { queryClient.setQueryData(requestsQueryKey(payload), removeById(payload)); } else if (payload.model === 'http_response') { queryClient.setQueryData(responsesQueryKey(payload), removeById(payload)); } else if (payload.model === 'key_value') { queryClient.setQueryData(keyValueQueryKey(payload), undefined); } }); useListenToTauriEvent('zoom', ({ payload: zoomDelta, windowLabel }) => { if (windowLabel !== appWindow.label) return; const fontSize = parseFloat(window.getComputedStyle(document.documentElement).fontSize); let newFontSize; if (zoomDelta === 0) { newFontSize = DEFAULT_FONT_SIZE; } else if (zoomDelta > 0) { newFontSize = Math.min(fontSize * 1.1, DEFAULT_FONT_SIZE * 5); } else if (zoomDelta < 0) { newFontSize = Math.max(fontSize * 0.9, DEFAULT_FONT_SIZE * 0.4); } document.documentElement.style.fontSize = `${newFontSize}px`; }); return null; } function removeById(model: T) { return (entries: T[] | undefined) => entries?.filter((e) => e.id !== model.id); } const shouldIgnoreEvent = (payload: Model, windowLabel: string) => windowLabel === appWindow.label && payload.model !== 'http_response'; const shouldIgnoreModel = (payload: Model) => { if (payload.model === 'key_value') { return payload.namespace === NAMESPACE_NO_SYNC; } return false; };