mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-22 01:19:13 +01:00
Remove updated_by, remember last location
This commit is contained in:
@@ -14,6 +14,7 @@ import { keyValueQueryKey } from '../hooks/useKeyValue';
|
||||
import { requestsQueryKey } from '../hooks/useRequests';
|
||||
import { responsesQueryKey } from '../hooks/useResponses';
|
||||
import { routePaths } from '../hooks/useRoutes';
|
||||
import { UPDATE_DEBOUNCE_MILLIS } from '../hooks/useTauriListeners';
|
||||
import { workspacesQueryKey } from '../hooks/useWorkspaces';
|
||||
import { DEFAULT_FONT_SIZE } from '../lib/constants';
|
||||
import { debounce } from '../lib/debounce';
|
||||
@@ -22,8 +23,6 @@ import type { HttpRequest, HttpResponse, KeyValue, Workspace } from '../lib/mode
|
||||
import { AppRouter } from './AppRouter';
|
||||
import { DialogProvider } from './DialogContext';
|
||||
|
||||
const UPDATE_DEBOUNCE_MILLIS = 500;
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
@@ -145,7 +144,6 @@ await listen('zoom', ({ payload: zoomDelta }: { payload: number }) => {
|
||||
});
|
||||
|
||||
export function App() {
|
||||
console.log('STARTING APP');
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<MotionConfig transition={{ duration: 0.1 }}>
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
import { createBrowserRouter, Navigate, RouterProvider } from 'react-router-dom';
|
||||
import { useEffect } from 'react';
|
||||
import {
|
||||
createBrowserRouter,
|
||||
Navigate,
|
||||
Outlet,
|
||||
RouterProvider,
|
||||
useLocation,
|
||||
} from 'react-router-dom';
|
||||
import { routePaths } from '../hooks/useRoutes';
|
||||
import { useTauriListeners } from '../hooks/useTauriListeners';
|
||||
import { setLastLocation } from '../lib/lastLocation';
|
||||
import RouteError from './RouteError';
|
||||
import Workspace from './Workspace';
|
||||
import Workspaces from './Workspaces';
|
||||
@@ -9,6 +17,7 @@ const router = createBrowserRouter([
|
||||
{
|
||||
path: '/',
|
||||
errorElement: <RouteError />,
|
||||
element: <RouterRoot />,
|
||||
children: [
|
||||
{
|
||||
path: '/',
|
||||
@@ -34,8 +43,14 @@ const router = createBrowserRouter([
|
||||
]);
|
||||
|
||||
export function AppRouter() {
|
||||
console.log('AppRouter');
|
||||
useTauriListeners();
|
||||
console.log('AppRouter 2');
|
||||
return <RouterProvider router={router} />;
|
||||
}
|
||||
|
||||
function RouterRoot() {
|
||||
const { pathname } = useLocation();
|
||||
useEffect(() => {
|
||||
setLastLocation(pathname).catch(console.error);
|
||||
}, [pathname]);
|
||||
return <Outlet />;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { Navigate } from 'react-router-dom';
|
||||
import { useKeyValue } from '../hooks/useKeyValue';
|
||||
import { useRoutes } from '../hooks/useRoutes';
|
||||
import { useWorkspaces } from '../hooks/useWorkspaces';
|
||||
import { Button } from './core/Button';
|
||||
import { Heading } from './core/Heading';
|
||||
import { VStack } from './core/Stacks';
|
||||
|
||||
export default function Workspaces() {
|
||||
const lastWorkspace = useKeyValue<string | null>({ key: 'last_workspace', defaultValue: null });
|
||||
const routes = useRoutes();
|
||||
const workspaces = useWorkspaces();
|
||||
return (
|
||||
<VStack as="ul" className="p-12" space={1}>
|
||||
<Heading>Workspaces</Heading>
|
||||
{workspaces.map((w) => (
|
||||
<Button key={w.id} color="gray" to={`/workspaces/${w.id}`}>
|
||||
{w.name}
|
||||
</Button>
|
||||
))}
|
||||
</VStack>
|
||||
);
|
||||
const workspace = workspaces[0];
|
||||
|
||||
if (workspace === undefined) {
|
||||
return <Heading>There are no workspaces</Heading>;
|
||||
}
|
||||
|
||||
return <Navigate to={routes.paths.workspace({ workspaceId: workspace.id })} />;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ export function keyValueQueryKey({
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export function useKeyValue<T extends Object>({
|
||||
export function useKeyValue<T extends Object | null>({
|
||||
namespace = DEFAULT_NAMESPACE,
|
||||
key,
|
||||
defaultValue,
|
||||
@@ -30,12 +30,10 @@ export function useKeyValue<T extends Object>({
|
||||
queryFn: async () => getKeyValue({ namespace, key, fallback: defaultValue }),
|
||||
});
|
||||
|
||||
const mutate = useMutation<T, unknown, T>({
|
||||
const mutate = useMutation<void, unknown, T>({
|
||||
mutationFn: (value) => setKeyValue<T>({ namespace, key, value }),
|
||||
onMutate: (value) => {
|
||||
// k/v should be as fast as possible, so optimistically update the cache
|
||||
queryClient.setQueryData(keyValueQueryKey({ namespace, key }), value);
|
||||
},
|
||||
// k/v should be as fast as possible, so optimistically update the cache
|
||||
onMutate: (value) => queryClient.setQueryData(keyValueQueryKey({ namespace, key }), value),
|
||||
});
|
||||
|
||||
const set = useCallback(
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useRequestUpdateKey } from './useRequestUpdateKey';
|
||||
import { useSidebarDisplay } from './useSidebarDisplay';
|
||||
|
||||
const unsubFns: (() => void)[] = [];
|
||||
const UPDATE_DEBOUNCE_MILLIS = 500;
|
||||
export const UPDATE_DEBOUNCE_MILLIS = 1000;
|
||||
|
||||
export function useTauriListeners() {
|
||||
const sidebarDisplay = useSidebarDisplay();
|
||||
|
||||
@@ -11,13 +11,12 @@ export async function setKeyValue<T>({
|
||||
namespace?: string;
|
||||
key: string | string[];
|
||||
value: T;
|
||||
}): Promise<T> {
|
||||
}): Promise<void> {
|
||||
await invoke('set_key_value', {
|
||||
namespace,
|
||||
key: buildKeyValueKey(key),
|
||||
value: JSON.stringify(value),
|
||||
});
|
||||
return value;
|
||||
}
|
||||
|
||||
export async function getKeyValue<T>({
|
||||
|
||||
17
src-web/lib/lastLocation.ts
Normal file
17
src-web/lib/lastLocation.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { getKeyValue, setKeyValue } from './keyValueStore';
|
||||
|
||||
export async function getLastLocation(): Promise<string> {
|
||||
return getKeyValue({ key: 'last_location', fallback: '/' });
|
||||
}
|
||||
|
||||
export async function setLastLocation(pathname: string): Promise<void> {
|
||||
return setKeyValue({ key: 'last_location', value: pathname });
|
||||
}
|
||||
|
||||
export async function syncLastLocation(): Promise<void> {
|
||||
const lastPathname = await getLastLocation();
|
||||
if (lastPathname !== window.location.pathname) {
|
||||
console.log(`Redirecting to last location: ${lastPathname}`);
|
||||
window.location.assign(lastPathname);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
console.log('FIRST 0');
|
||||
import { StrictMode } from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import { App } from './components/App';
|
||||
import { getKeyValue } from './lib/keyValueStore';
|
||||
import { syncLastLocation } from './lib/lastLocation';
|
||||
import { getPreferredAppearance, setAppearance } from './lib/theme/window';
|
||||
import './main.css';
|
||||
|
||||
console.log('FIRST');
|
||||
setAppearance(await getKeyValue({ key: 'appearance', fallback: getPreferredAppearance() }));
|
||||
console.log('SECOND');
|
||||
await syncLastLocation();
|
||||
|
||||
// root holds our app's root DOM Element:
|
||||
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
||||
|
||||
Reference in New Issue
Block a user