fix: drag workspace (#3513)

This commit is contained in:
Alex Yang
2023-08-01 16:29:17 -07:00
committed by GitHub
parent 1b17743ed3
commit 03b98b433b
3 changed files with 27 additions and 36 deletions
+1 -1
View File
@@ -127,7 +127,7 @@ await rootStore
const result = createFirst(); const result = createFirst();
console.info('create first workspace', result); console.info('create first workspace', result);
localStorage.setItem('is-first-open', 'false'); localStorage.setItem('is-first-open', 'false');
rootStore.set(rootWorkspacesMetadataAtom, result).catch(console.error); rootStore.set(rootWorkspacesMetadataAtom, result);
} }
}) })
.catch(console.error); .catch(console.error);
+5 -11
View File
@@ -8,13 +8,7 @@ import {
} from '@toeverything/plugin-infra/atom'; } from '@toeverything/plugin-infra/atom';
import { useAtom, useAtomValue, useSetAtom } from 'jotai'; import { useAtom, useAtomValue, useSetAtom } from 'jotai';
import type { FC, ReactElement } from 'react'; import type { FC, ReactElement } from 'react';
import { import { lazy, Suspense, useCallback, useTransition } from 'react';
lazy,
startTransition,
Suspense,
useCallback,
useTransition,
} from 'react';
import type { SettingAtom } from '../atoms'; import type { SettingAtom } from '../atoms';
import { import {
@@ -130,7 +124,7 @@ export const AllWorkspaceModals = (): ReactElement => {
currentWorkspaceIdAtom currentWorkspaceIdAtom
); );
const setCurrentPageId = useSetAtom(currentPageIdAtom); const setCurrentPageId = useSetAtom(currentPageIdAtom);
const [transitioning, transition] = useTransition(); const [isPending, startTransition] = useTransition();
const [, setOpenSettingModalAtom] = useAtom(openSettingModalAtom); const [, setOpenSettingModalAtom] = useAtom(openSettingModalAtom);
const handleOpenSettingModal = useCallback( const handleOpenSettingModal = useCallback(
@@ -149,7 +143,7 @@ export const AllWorkspaceModals = (): ReactElement => {
<> <>
<Suspense> <Suspense>
<WorkspaceListModal <WorkspaceListModal
disabled={transitioning} disabled={isPending}
workspaces={workspaces} workspaces={workspaces}
currentWorkspaceId={currentWorkspaceId} currentWorkspaceId={currentWorkspaceId}
open={ open={
@@ -163,10 +157,10 @@ export const AllWorkspaceModals = (): ReactElement => {
(activeId, overId) => { (activeId, overId) => {
const oldIndex = workspaces.findIndex(w => w.id === activeId); const oldIndex = workspaces.findIndex(w => w.id === activeId);
const newIndex = workspaces.findIndex(w => w.id === overId); const newIndex = workspaces.findIndex(w => w.id === overId);
transition(() => { startTransition(() => {
setWorkspaces(workspaces => setWorkspaces(workspaces =>
arrayMove(workspaces, oldIndex, newIndex) arrayMove(workspaces, oldIndex, newIndex)
).catch(console.error); );
}); });
}, },
[setWorkspaces, workspaces] [setWorkspaces, workspaces]
+21 -24
View File
@@ -60,9 +60,9 @@ export const workspaceAdaptersAtom = atom<
* which is `id` and `flavor`, that is enough to load the real workspace data * which is `id` and `flavor`, that is enough to load the real workspace data
*/ */
const METADATA_STORAGE_KEY = 'jotai-workspaces'; const METADATA_STORAGE_KEY = 'jotai-workspaces';
const rootWorkspacesMetadataPrimitiveAtom = atom< const rootWorkspacesMetadataPrimitiveAtom = atom<Promise<
RootWorkspaceMetadata[] | null RootWorkspaceMetadata[]
>(null); > | null>(null);
const rootWorkspacesMetadataPromiseAtom = atom< const rootWorkspacesMetadataPromiseAtom = atom<
Promise<RootWorkspaceMetadata[]> Promise<RootWorkspaceMetadata[]>
>(async (get, { signal }) => { >(async (get, { signal }) => {
@@ -168,7 +168,7 @@ type SetStateAction<Value> = Value | ((prev: Value) => Value);
export const rootWorkspacesMetadataAtom = atom< export const rootWorkspacesMetadataAtom = atom<
Promise<RootWorkspaceMetadata[]>, Promise<RootWorkspaceMetadata[]>,
[SetStateAction<RootWorkspaceMetadata[]>], [SetStateAction<RootWorkspaceMetadata[]>],
Promise<RootWorkspaceMetadata[]> void
>( >(
async get => { async get => {
const maybeMetadata = get(rootWorkspacesMetadataPrimitiveAtom); const maybeMetadata = get(rootWorkspacesMetadataPrimitiveAtom);
@@ -178,29 +178,26 @@ export const rootWorkspacesMetadataAtom = atom<
return get(rootWorkspacesMetadataPromiseAtom); return get(rootWorkspacesMetadataPromiseAtom);
}, },
async (get, set, action) => { async (get, set, action) => {
const metadataPromise = get(rootWorkspacesMetadataPromiseAtom);
// get metadata // get metadata
let metadata: RootWorkspaceMetadata[]; set(rootWorkspacesMetadataPrimitiveAtom, async maybeMetadataPromise => {
const maybeMetadata = get(rootWorkspacesMetadataPrimitiveAtom); let metadata: RootWorkspaceMetadata[] =
if (maybeMetadata !== null) { (await maybeMetadataPromise) ?? (await metadataPromise);
metadata = maybeMetadata;
} else {
metadata = await get(rootWorkspacesMetadataPromiseAtom);
}
// update metadata // update metadata
if (typeof action === 'function') { if (typeof action === 'function') {
metadata = action(metadata); metadata = action(metadata);
} else { } else {
metadata = action; metadata = action;
} }
const metadataMap = new Map(metadata.map(x => [x.id, x])); const metadataMap = new Map(metadata.map(x => [x.id, x]));
metadata = Array.from(metadataMap.values()); metadata = Array.from(metadataMap.values());
// write back to localStorage // write back to localStorage
rootWorkspaceMetadataArraySchema.parse(metadata); rootWorkspaceMetadataArraySchema.parse(metadata);
localStorage.setItem(METADATA_STORAGE_KEY, JSON.stringify(metadata)); localStorage.setItem(METADATA_STORAGE_KEY, JSON.stringify(metadata));
set(rootWorkspacesMetadataPrimitiveAtom, metadata); return metadata;
return metadata; });
} }
); );