feat: improve experience of setting and load name

This commit is contained in:
MingLiang Wang
2022-12-23 11:24:40 +08:00
parent db09447535
commit 262c62a50e
6 changed files with 59 additions and 64 deletions
@@ -18,13 +18,18 @@ import { Workspace as StoreWorkspaces } from '@blocksuite/store';
export const GeneralPage = ({
workspace,
owner,
workspaces,
}: {
workspace: Workspace;
owner: WorkspaceDetails[string]['owner'];
workspaces: Record<string, StoreWorkspaces | null>;
}) => {
const { user, currentWorkspace, workspacesMeta } = useAppState();
const {
user,
currentWorkspace,
workspacesMeta,
workspaces,
refreshWorkspacesMeta,
} = useAppState();
const [showDelete, setShowDelete] = useState<boolean>(false);
const [workspaceName, setWorkspaceName] = useState<string>(
workspaces[workspace.id]?.meta.name ||
@@ -37,6 +42,7 @@ export const GeneralPage = ({
setWorkspaceName(newName);
currentWorkspace?.meta.setName(newName);
workspaces[workspace.id]?.meta.setName(newName);
refreshWorkspacesMeta();
};
const currentWorkspaceIndex = workspacesMeta.findIndex(
meta => meta.id === workspace.id
@@ -66,7 +72,7 @@ export const GeneralPage = ({
alt="workspace avatar"
src={workspaces[workspace.id]?.meta.avatar || ''}
>
W
{workspaces[workspace.id]?.meta.name[0]}
</StyledSettingAvatar>
{/* TODO: add upload logic */}
{/* {isOwner ? (
@@ -68,7 +68,6 @@ type WorkspaceSettingProps = {
onClose?: () => void;
workspace: Workspace;
owner: WorkspaceDetails[string]['owner'];
workspaces: Record<string, StoreWorkspaces | null>;
};
const WorkspaceSettingTab = ({ activeTab, onTabChange }: SettingTabProps) => {
@@ -116,9 +115,8 @@ export const WorkspaceSetting = ({
onClose,
workspace,
owner,
workspaces,
}: WorkspaceSettingProps) => {
const { user } = useAppState();
const { user, workspaces } = useAppState();
const [activeTab, setActiveTab] = useState<ActiveTab>(ActiveTab.general);
const handleTabChange = (tab: ActiveTab) => {
setActiveTab(tab);
@@ -12,12 +12,7 @@ import {
} from './WorkspaceItem';
import { WorkspaceSetting } from '@/components/workspace-setting';
import { useCallback, useEffect, useState } from 'react';
import {
downloadWorkspace,
getWorkspaceDetail,
WorkspaceType,
} from '@pathfinder/data-services';
import { Workspace } from '@blocksuite/store';
import { getWorkspaceDetail, WorkspaceType } from '@pathfinder/data-services';
export type WorkspaceDetails = Record<
string,
@@ -31,16 +26,15 @@ type SelectorPopperContentProps = {
export const SelectorPopperContent = ({
isShow,
}: SelectorPopperContentProps) => {
const { user, workspacesMeta } = useAppState();
const { user, workspacesMeta, workspaces, refreshWorkspacesMeta } =
useAppState();
const [settingWorkspaceId, setSettingWorkspaceId] = useState<string | null>(
null
);
const [workSpaceDetails, setWorkSpaceDetails] = useState<WorkspaceDetails>(
{}
);
const [workspaces, setWorkspaces] = useState<
Record<string, Workspace | null>
>({});
const handleClickSettingWorkspace = (workspaceId: string) => {
setSettingWorkspaceId(workspaceId);
};
@@ -81,38 +75,13 @@ export const SelectorPopperContent = ({
setWorkSpaceDetails(workSpaceDetails);
}, [user, workspacesMeta]);
// TODO: add to context
const refreshWorkspaces = useCallback(async () => {
const workspacesList = await Promise.all(
workspacesMeta.map(async ({ id }) => {
const workspace = new Workspace({
room: id,
providers: [],
});
const updates = await downloadWorkspace({ workspaceId: id });
updates &&
Workspace.Y.applyUpdate(workspace.doc, new Uint8Array(updates));
// if after update, the space:meta is empty, then we need to get map with doc
workspace.doc.getMap('space:meta');
return { id, workspace };
})
);
const workspaces: Record<string, Workspace | null> = {};
workspacesList.forEach(({ id, workspace }) => {
workspaces[id] = workspace;
});
setWorkspaces(workspaces);
}, [workspacesMeta]);
useEffect(() => {
if (isShow) {
setSettingWorkspaceId(null);
refreshWorkspacesMeta();
refreshDetails();
refreshWorkspaces();
}
}, [isShow, refreshDetails]);
}, [isShow]);
return !user ? (
<SelectorPopperContainer placement="bottom-start">
@@ -142,7 +111,7 @@ export const SelectorPopperContent = ({
workspaces[workspace.id]?.meta.name ||
(workspace.type === WorkspaceType.Private
? user.name
: `loading...`) // workspace-${workspace.id}
: `loading...`)
}
memberCount={workSpaceDetails[workspace.id]?.memberCount || 1}
/>
@@ -162,7 +131,6 @@ export const SelectorPopperContent = ({
name: user.name,
}
}
workspaces={workspaces}
/>
) : null}
<StyledDivider />
@@ -12,7 +12,6 @@ export const WorkspaceSelector = () => {
const workspaceMeta = workspacesMeta.find(
meta => String(meta.id) === String(currentWorkspaceId)
);
console.log('currentWorkspace', currentWorkspace, workspaceMeta);
return (
<Popper
content={<SelectorPopperContent isShow={isShow} />}
@@ -21,6 +21,8 @@ export interface AppStateValue {
currentPage: StorePage | null;
workspaces: Record<string, StoreWorkspace | null>;
editor: EditorContainer | null;
synced: boolean;
refreshWorkspacesMeta: () => void;
@@ -57,6 +59,7 @@ export const AppState = createContext<AppStateContext>({
createPage: () => Promise.resolve(null),
synced: false,
refreshWorkspacesMeta: () => {},
workspaces: {},
});
export const useAppState = () => {
@@ -5,6 +5,7 @@ import {
token,
AccessTokenMessage,
getWorkspaces,
downloadWorkspace,
} from '@pathfinder/data-services';
import { AppState, AppStateContext } from './context';
import type {
@@ -12,19 +13,19 @@ import type {
CreateEditorHandler,
LoadWorkspaceHandler,
} from './context';
import type { Page, Workspace } from '@blocksuite/store';
import { Page, Workspace } from '@blocksuite/store';
import { EditorContainer } from '@blocksuite/editor';
const DynamicBlocksuite = dynamic(() => import('./dynamic-blocksuite'), {
ssr: false,
});
export const AppStateProvider = ({ children }: { children?: ReactNode }) => {
const refreshWorkspacesMeta = useCallback(async () => {
const refreshWorkspacesMeta = async () => {
const workspacesMeta = await getWorkspaces().catch(() => {
return [];
});
setState(state => ({ ...state, workspacesMeta }));
}, []);
};
const [state, setState] = useState<AppStateValue>({
user: null,
@@ -37,8 +38,43 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => {
// So after Synced set to true, the other state is sure to be set.
synced: false,
refreshWorkspacesMeta,
workspaces: {},
});
const refreshWorkspacesInfo = async (
workspaces: AppStateValue['workspaces']
) => {
Object.entries(workspaces).forEach(async ([workspaceId, workspace]) => {
if (workspace) {
const updates = await downloadWorkspace({ workspaceId });
updates &&
Workspace.Y.applyUpdate(workspace.doc, new Uint8Array(updates));
// if after update, the space:meta is empty, then we need to get map with doc
workspace.doc.getMap('space:meta');
}
});
};
useEffect(() => {
(async () => {
const workspacesList = await Promise.all(
state.workspacesMeta.map(async ({ id }) => {
const workspace = (await loadWorkspaceHandler?.(id)) || null;
return { id, workspace };
})
);
const workspaces: Record<string, Workspace | null> = {};
workspacesList.forEach(({ id, workspace }) => {
workspaces[id] = workspace;
});
setState(state => ({
...state,
workspaces,
}));
refreshWorkspacesInfo(workspaces);
})();
}, [state.workspacesMeta]);
const [loadWorkspaceHandler, _setLoadWorkspaceHandler] =
useState<LoadWorkspaceHandler>();
const setLoadWorkspaceHandler = useCallback(
@@ -156,25 +192,10 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => {
})
: [];
const workspacesList = await Promise.all(
workspacesMeta.map(async ({ id }) => {
const workspace = (await loadWorkspaceHandler?.(id)) || null;
return { id, workspace };
})
);
const workspaces: Record<string, Workspace | null> = {};
workspacesList.forEach(({ id, workspace }) => {
workspaces[id] = workspace;
});
// TODO: add meta info to workspace meta
setState(state => ({
...state,
user: user,
workspacesMeta,
workspaces,
synced: true,
}));
};