refactor(store): extract workspace out of AppState (#1037)
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
import { Modal, ModalWrapper } from '@affine/component';
|
import { Modal, ModalWrapper } from '@affine/component';
|
||||||
import { IconButton } from '@affine/component';
|
import { IconButton } from '@affine/component';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import router from 'next/router';
|
import router from 'next/router';
|
||||||
import { toast } from '@affine/component';
|
import { toast } from '@affine/component';
|
||||||
@@ -22,7 +21,9 @@ export const EnableWorkspaceModal = ({
|
|||||||
const login = useGlobalState(store => store.login);
|
const login = useGlobalState(store => store.login);
|
||||||
const user = useGlobalState(store => store.user);
|
const user = useGlobalState(store => store.user);
|
||||||
const dataCenter = useGlobalState(store => store.dataCenter);
|
const dataCenter = useGlobalState(store => store.dataCenter);
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
return (
|
return (
|
||||||
<Modal open={open} onClose={onClose} data-testid="logout-modal">
|
<Modal open={open} onClose={onClose} data-testid="logout-modal">
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
"@affine/i18n": "workspace:*",
|
"@affine/i18n": "workspace:*",
|
||||||
"@blocksuite/blocks": "0.4.0-20230216011811-2776d93",
|
"@blocksuite/blocks": "0.4.0-20230216011811-2776d93",
|
||||||
"@blocksuite/editor": "0.4.0-20230216011811-2776d93",
|
"@blocksuite/editor": "0.4.0-20230216011811-2776d93",
|
||||||
|
"@blocksuite/global": "0.4.0-20230216011811-2776d93",
|
||||||
"@blocksuite/icons": "^2.0.14",
|
"@blocksuite/icons": "^2.0.14",
|
||||||
"@blocksuite/store": "0.4.0-20230216011811-2776d93",
|
"@blocksuite/store": "0.4.0-20230216011811-2776d93",
|
||||||
"@emotion/css": "^11.10.5",
|
"@emotion/css": "^11.10.5",
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import { IconButton, Modal, ModalWrapper, toast } from '@affine/component';
|
import { IconButton, Modal, ModalWrapper, toast } from '@affine/component';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
import { CloseIcon } from '@blocksuite/icons';
|
import { CloseIcon } from '@blocksuite/icons';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { Content, ContentTitle, Header, StyleButton, StyleTips } from './style';
|
import { Content, ContentTitle, Header, StyleButton, StyleTips } from './style';
|
||||||
import { useGlobalState } from '@/store/app';
|
import { useGlobalState } from '@/store/app';
|
||||||
|
|
||||||
@@ -20,7 +19,9 @@ export const EnableWorkspaceModal = ({
|
|||||||
const login = useGlobalState(store => store.login);
|
const login = useGlobalState(store => store.login);
|
||||||
const user = useGlobalState(store => store.user);
|
const user = useGlobalState(store => store.user);
|
||||||
const dataCenter = useGlobalState(store => store.dataCenter);
|
const dataCenter = useGlobalState(store => store.dataCenter);
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { LocalWorkspaceIcon, CloudWorkspaceIcon } from '@blocksuite/icons';
|
import { LocalWorkspaceIcon, CloudWorkspaceIcon } from '@blocksuite/icons';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import { displayFlex, styled, Tooltip, IconButton } from '@affine/component';
|
import { displayFlex, styled, Tooltip, IconButton } from '@affine/component';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
import { useModal } from '@/store/globalModal';
|
import { useModal } from '@/store/globalModal';
|
||||||
import { useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { WorkspaceUnit } from '@affine/datacenter';
|
import { WorkspaceUnit } from '@affine/datacenter';
|
||||||
|
import { useGlobalState } from '@/store/app';
|
||||||
|
|
||||||
const NoNetWorkIcon = () => {
|
const NoNetWorkIcon = () => {
|
||||||
return (
|
return (
|
||||||
@@ -43,7 +43,9 @@ const getStatus = (workspace: WorkspaceUnit | null) => {
|
|||||||
return 'cloud';
|
return 'cloud';
|
||||||
};
|
};
|
||||||
export const SyncUser = () => {
|
export const SyncUser = () => {
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
const { triggerEnableWorkspaceModal } = useModal();
|
const { triggerEnableWorkspaceModal } = useModal();
|
||||||
|
|
||||||
const [status, setStatus] = useState<'offline' | 'local' | 'cloud'>(
|
const [status, setStatus] = useState<'offline' | 'local' | 'cloud'>(
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
import { Button } from '@affine/component';
|
import { Button } from '@affine/component';
|
||||||
import { usePageHelper } from '@/hooks/use-page-helper';
|
import { usePageHelper } from '@/hooks/use-page-helper';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import { useConfirm } from '@/providers/ConfirmProvider';
|
import { useConfirm } from '@/providers/ConfirmProvider';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import useCurrentPageMeta from '@/hooks/use-current-page-meta';
|
import useCurrentPageMeta from '@/hooks/use-current-page-meta';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
import { useGlobalState } from '@/store/app';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
export const TrashButtonGroup = () => {
|
export const TrashButtonGroup = () => {
|
||||||
const { permanentlyDeletePage } = usePageHelper();
|
const { permanentlyDeletePage } = usePageHelper();
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
const { toggleDeletePage } = usePageHelper();
|
const { toggleDeletePage } = usePageHelper();
|
||||||
const confirm = useConfirm(store => store.confirm);
|
const confirm = useConfirm(store => store.confirm);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import { Button } from '@affine/component';
|
|||||||
import { Content, FlexWrapper } from '@affine/component';
|
import { Content, FlexWrapper } from '@affine/component';
|
||||||
import Loading from '@/components/loading';
|
import Loading from '@/components/loading';
|
||||||
import { usePageHelper } from '@/hooks/use-page-helper';
|
import { usePageHelper } from '@/hooks/use-page-helper';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
import { useGlobalState } from '@/store/app';
|
||||||
// import { Tooltip } from '@affine/component';
|
// import { Tooltip } from '@affine/component';
|
||||||
type ImportModalProps = {
|
type ImportModalProps = {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@@ -19,7 +19,9 @@ type Template = {
|
|||||||
export const ImportModal = ({ open, onClose }: ImportModalProps) => {
|
export const ImportModal = ({ open, onClose }: ImportModalProps) => {
|
||||||
const [status, setStatus] = useState<'unImported' | 'importing'>('importing');
|
const [status, setStatus] = useState<'unImported' | 'importing'>('importing');
|
||||||
const { openPage, createPage } = usePageHelper();
|
const { openPage, createPage } = usePageHelper();
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const _applyTemplate = function (pageId: string, template: Template) {
|
const _applyTemplate = function (pageId: string, template: Template) {
|
||||||
const page = currentWorkspace?.blocksuiteWorkspace?.getPage(pageId);
|
const page = currentWorkspace?.blocksuiteWorkspace?.getPage(pageId);
|
||||||
|
|||||||
@@ -21,16 +21,16 @@ import {
|
|||||||
import { OperationCell, TrashOperationCell } from './OperationCell';
|
import { OperationCell, TrashOperationCell } from './OperationCell';
|
||||||
import Empty from './Empty';
|
import Empty from './Empty';
|
||||||
import { Content } from '@affine/component';
|
import { Content } from '@affine/component';
|
||||||
import React from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import DateCell from '@/components/page-list/DateCell';
|
import DateCell from '@/components/page-list/DateCell';
|
||||||
import { IconButton } from '@affine/component';
|
import { IconButton } from '@affine/component';
|
||||||
import { Tooltip } from '@affine/component';
|
import { Tooltip } from '@affine/component';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import { toast } from '@affine/component';
|
import { toast } from '@affine/component';
|
||||||
import { usePageHelper } from '@/hooks/use-page-helper';
|
import { usePageHelper } from '@/hooks/use-page-helper';
|
||||||
import { useTheme } from '@/providers/ThemeProvider';
|
import { useTheme } from '@/providers/ThemeProvider';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
import { useGlobalState } from '@/store/app';
|
||||||
const FavoriteTag = ({
|
const FavoriteTag = ({
|
||||||
pageMeta: { favorite, id },
|
pageMeta: { favorite, id },
|
||||||
}: {
|
}: {
|
||||||
@@ -83,7 +83,9 @@ export const PageList = ({
|
|||||||
listType?: 'all' | 'trash' | 'favorite';
|
listType?: 'all' | 'trash' | 'favorite';
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
if (pageList.length === 0) {
|
if (pageList.length === 0) {
|
||||||
return <Empty listType={listType} />;
|
return <Empty listType={listType} />;
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
import { Command } from 'cmdk';
|
import { Command } from 'cmdk';
|
||||||
import { StyledListItem, StyledNotFound } from './style';
|
import { StyledListItem, StyledNotFound } from './style';
|
||||||
import { PaperIcon, EdgelessIcon } from '@blocksuite/icons';
|
import { PaperIcon, EdgelessIcon } from '@blocksuite/icons';
|
||||||
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
|
import {
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
Dispatch,
|
||||||
|
SetStateAction,
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useState,
|
||||||
|
} from 'react';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useSwitchToConfig } from './config';
|
import { useSwitchToConfig } from './config';
|
||||||
import { NoResultSVG } from './NoResultSVG';
|
import { NoResultSVG } from './NoResultSVG';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
import usePageHelper from '@/hooks/use-page-helper';
|
import usePageHelper from '@/hooks/use-page-helper';
|
||||||
|
import { useGlobalState } from '@/store/app';
|
||||||
export const Results = (props: {
|
export const Results = (props: {
|
||||||
query: string;
|
query: string;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
@@ -18,7 +24,12 @@ export const Results = (props: {
|
|||||||
const { query, loading, setLoading, setShowCreatePage, onClose } = props;
|
const { query, loading, setLoading, setShowCreatePage, onClose } = props;
|
||||||
const { openPage } = usePageHelper();
|
const { openPage } = usePageHelper();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { currentWorkspace, pageList } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
|
const pageList = useGlobalState(
|
||||||
|
useCallback(store => store.dataCenterPageList, [])
|
||||||
|
);
|
||||||
const { search } = usePageHelper();
|
const { search } = usePageHelper();
|
||||||
const List = useSwitchToConfig(currentWorkspace?.id);
|
const List = useSwitchToConfig(currentWorkspace?.id);
|
||||||
const [results, setResults] = useState(new Map<string, string | undefined>());
|
const [results, setResults] = useState(new Map<string, string | undefined>());
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import {
|
|||||||
PublishIcon,
|
PublishIcon,
|
||||||
} from '@/components/icons';
|
} from '@/components/icons';
|
||||||
import { WorkspaceUnit } from '@affine/datacenter';
|
import { WorkspaceUnit } from '@affine/datacenter';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import { StyleWorkspaceInfo, StyleWorkspaceTitle, StyledCard } from './styles';
|
import { StyleWorkspaceInfo, StyleWorkspaceTitle, StyledCard } from './styles';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
import { useGlobalState } from '@/store/app';
|
import { useGlobalState } from '@/store/app';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
const WorkspaceType = ({ workspaceData }: { workspaceData: WorkspaceUnit }) => {
|
const WorkspaceType = ({ workspaceData }: { workspaceData: WorkspaceUnit }) => {
|
||||||
const user = useGlobalState(store => store.user);
|
const user = useGlobalState(store => store.user);
|
||||||
@@ -46,7 +46,9 @@ export const WorkspaceCard = ({
|
|||||||
workspaceData: WorkspaceUnit;
|
workspaceData: WorkspaceUnit;
|
||||||
onClick: (data: WorkspaceUnit) => void;
|
onClick: (data: WorkspaceUnit) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<StyledCard
|
<StyledCard
|
||||||
|
|||||||
@@ -7,9 +7,8 @@ import {
|
|||||||
import { StyledSettingKey, StyledRow } from '../style';
|
import { StyledSettingKey, StyledRow } from '../style';
|
||||||
import { FlexWrapper } from '@affine/component';
|
import { FlexWrapper } from '@affine/component';
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { Button } from '@affine/component';
|
import { Button } from '@affine/component';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import { WorkspaceDelete } from './delete';
|
import { WorkspaceDelete } from './delete';
|
||||||
import { WorkspaceLeave } from './leave';
|
import { WorkspaceLeave } from './leave';
|
||||||
import {
|
import {
|
||||||
@@ -31,7 +30,9 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
|||||||
const [workspaceName, setWorkspaceName] = useState<string>(workspace?.name);
|
const [workspaceName, setWorkspaceName] = useState<string>(workspace?.name);
|
||||||
const [showEditInput, setShowEditInput] = useState(false);
|
const [showEditInput, setShowEditInput] = useState(false);
|
||||||
const isOwner = useGlobalState(store => store.isOwner);
|
const isOwner = useGlobalState(store => store.isOwner);
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
const { updateWorkspace } = useWorkspaceHelper();
|
const { updateWorkspace } = useWorkspaceHelper();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
import { WorkspaceName, SelectorWrapper } from './styles';
|
import { WorkspaceName, SelectorWrapper } from './styles';
|
||||||
import { useEffect, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { WorkspaceModal } from '@/components/workspace-modal';
|
import { WorkspaceModal } from '@/components/workspace-modal';
|
||||||
import { WorkspaceUnitAvatar } from '@/components/workspace-avatar';
|
import { WorkspaceUnitAvatar } from '@/components/workspace-avatar';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
import { useGlobalState } from '@/store/app';
|
||||||
|
|
||||||
export const WorkspaceSelector = () => {
|
export const WorkspaceSelector = () => {
|
||||||
const [workspaceListShow, setWorkspaceListShow] = useState(false);
|
const [workspaceListShow, setWorkspaceListShow] = useState(false);
|
||||||
const { currentWorkspace, workspaceList } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
|
const dataCenter = useGlobalState(useCallback(store => store.dataCenter, []));
|
||||||
|
|
||||||
useEffect(() => {
|
if (dataCenter.workspaces.length === 0) {
|
||||||
if (workspaceList.length === 0) {
|
setWorkspaceListShow(true);
|
||||||
setWorkspaceListShow(true);
|
}
|
||||||
}
|
|
||||||
}, [workspaceList]);
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SelectorWrapper
|
<SelectorWrapper
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useCallback, useState } from 'react';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import {
|
import {
|
||||||
StyledArrowButton,
|
StyledArrowButton,
|
||||||
@@ -24,16 +24,16 @@ import Link from 'next/link';
|
|||||||
import { MuiCollapse } from '@affine/component';
|
import { MuiCollapse } from '@affine/component';
|
||||||
import { Tooltip } from '@affine/component';
|
import { Tooltip } from '@affine/component';
|
||||||
import { useModal } from '@/store/globalModal';
|
import { useModal } from '@/store/globalModal';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import { IconButton } from '@affine/component';
|
import { IconButton } from '@affine/component';
|
||||||
import useLocalStorage from '@/hooks/use-local-storage';
|
import useLocalStorage from '@/hooks/use-local-storage';
|
||||||
import { usePageHelper } from '@/hooks/use-page-helper';
|
import { usePageHelper } from '@/hooks/use-page-helper';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
import { WorkspaceSelector } from './WorkspaceSelector/WorkspaceSelector';
|
import { WorkspaceSelector } from './WorkspaceSelector/WorkspaceSelector';
|
||||||
|
import { useGlobalState } from '@/store/app';
|
||||||
|
|
||||||
const FavoriteList = ({ showList }: { showList: boolean }) => {
|
const FavoriteList = ({ showList }: { showList: boolean }) => {
|
||||||
const { openPage } = usePageHelper();
|
const { openPage } = usePageHelper();
|
||||||
const { pageList } = useAppState();
|
const pageList = useGlobalState(store => store.dataCenterPageList);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const favoriteList = pageList.filter(p => p.favorite && !p.trash);
|
const favoriteList = pageList.filter(p => p.favorite && !p.trash);
|
||||||
@@ -66,7 +66,9 @@ const FavoriteList = ({ showList }: { showList: boolean }) => {
|
|||||||
export const WorkSpaceSliderBar = () => {
|
export const WorkSpaceSliderBar = () => {
|
||||||
const { triggerQuickSearchModal } = useModal();
|
const { triggerQuickSearchModal } = useModal();
|
||||||
const [showSubFavorite, setShowSubFavorite] = useState(true);
|
const [showSubFavorite, setShowSubFavorite] = useState(true);
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
const { openPage, createPage } = usePageHelper();
|
const { openPage, createPage } = usePageHelper();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useAppState, PageMeta } from '@/providers/app-state-provider';
|
import { PageMeta } from '@/providers/app-state-provider';
|
||||||
|
import { useGlobalState } from '@/store/app';
|
||||||
|
|
||||||
export type ChangePageMeta = (
|
export type ChangePageMeta = (
|
||||||
pageId: string,
|
pageId: string,
|
||||||
@@ -7,7 +8,9 @@ export type ChangePageMeta = (
|
|||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
export const useChangePageMeta = () => {
|
export const useChangePageMeta = () => {
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
|
|
||||||
return useCallback<ChangePageMeta>(
|
return useCallback<ChangePageMeta>(
|
||||||
(pageId, pageMeta) => {
|
(pageId, pageMeta) => {
|
||||||
|
|||||||
@@ -1,35 +1,42 @@
|
|||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useGlobalState } from '@/store/app';
|
import { useGlobalState } from '@/store/app';
|
||||||
|
import { assertEquals } from '@blocksuite/global/utils';
|
||||||
|
|
||||||
|
// todo: refactor with suspense mode
|
||||||
// It is a fully effective hook
|
// It is a fully effective hook
|
||||||
// Cause it not just ensure workspace loaded, but also have router change.
|
// Cause it not just ensure workspace loaded, but also have router change.
|
||||||
export const useEnsureWorkspace = () => {
|
export const useEnsureWorkspace = () => {
|
||||||
const [workspaceLoaded, setWorkspaceLoaded] = useState(false);
|
const dataCenter = useGlobalState(useCallback(store => store.dataCenter, []));
|
||||||
const dataCenter = useGlobalState(store => store.dataCenter);
|
const currentWorkspace = useGlobalState(
|
||||||
const { loadWorkspace } = useAppState();
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
|
const loadWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.loadWorkspace, [])
|
||||||
|
);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [activeWorkspaceId, setActiveWorkspaceId] = useState(
|
const [currentWorkspaceId, setCurrentWorkspaceId] = useState<string | null>(
|
||||||
router.query.workspaceId as string
|
typeof router.query.workspaceId === 'string'
|
||||||
|
? router.query.workspaceId
|
||||||
|
: null
|
||||||
);
|
);
|
||||||
|
|
||||||
// const defaultOutLineWorkspaceId = '99ce7eb7';
|
// const defaultOutLineWorkspaceId = '99ce7eb7';
|
||||||
// console.log(defaultOutLineWorkspaceId);
|
// console.log(defaultOutLineWorkspaceId);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setWorkspaceLoaded(false);
|
|
||||||
let aborted = false;
|
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
|
|
||||||
const workspaceList = dataCenter.workspaces;
|
|
||||||
const workspaceId =
|
const workspaceId =
|
||||||
(router.query.workspaceId as string) || workspaceList[0]?.id;
|
(router.query.workspaceId as string) || dataCenter.workspaces[0]?.id;
|
||||||
|
|
||||||
// If router.query.workspaceId is not in workspace list, jump to 404 page
|
// If router.query.workspaceId is not in workspace list, jump to 404 page
|
||||||
// If workspaceList is empty, we need to create a default workspace but not jump to 404
|
// If workspaceList is empty, we need to create a default workspace but not jump to 404
|
||||||
if (
|
if (
|
||||||
workspaceId &&
|
workspaceId &&
|
||||||
workspaceList.length &&
|
dataCenter.workspaces.length &&
|
||||||
workspaceList.findIndex(meta => meta.id.toString() === workspaceId) === -1
|
dataCenter.workspaces.findIndex(
|
||||||
|
meta => meta.id.toString() === workspaceId
|
||||||
|
) === -1
|
||||||
) {
|
) {
|
||||||
router.push('/404');
|
router.push('/404');
|
||||||
return;
|
return;
|
||||||
@@ -44,22 +51,21 @@ export const useEnsureWorkspace = () => {
|
|||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
loadWorkspace.current(workspaceId, abortController.signal).then(unit => {
|
loadWorkspace(workspaceId, abortController.signal).then(unit => {
|
||||||
if (!aborted && unit) {
|
if (!abortController.signal.aborted && unit) {
|
||||||
setWorkspaceLoaded(true);
|
setCurrentWorkspaceId(unit.id);
|
||||||
setActiveWorkspaceId(workspaceId);
|
assertEquals(unit.id, workspaceId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
aborted = true;
|
|
||||||
abortController.abort();
|
abortController.abort();
|
||||||
};
|
};
|
||||||
}, [dataCenter, loadWorkspace, router]);
|
}, [dataCenter, loadWorkspace, router]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
workspaceLoaded,
|
workspaceLoaded: currentWorkspace?.id === currentWorkspaceId,
|
||||||
activeWorkspaceId,
|
activeWorkspaceId: currentWorkspace?.id ?? router.query.workspaceId,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { Member } from '@affine/datacenter';
|
import { Member } from '@affine/datacenter';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import { useGlobalState } from '@/store/app';
|
import { useGlobalState } from '@/store/app';
|
||||||
export const useMembers = () => {
|
export const useMembers = () => {
|
||||||
const dataCenter = useGlobalState(store => store.dataCenter);
|
const dataCenter = useGlobalState(store => store.dataCenter);
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
const [members, setMembers] = useState<Member[]>([]);
|
const [members, setMembers] = useState<Member[]>([]);
|
||||||
const [loaded, setLoaded] = useState(false);
|
const [loaded, setLoaded] = useState(false);
|
||||||
const refreshMembers = useCallback(async () => {
|
const refreshMembers = useCallback(async () => {
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { uuidv4, Workspace } from '@blocksuite/store';
|
import { uuidv4, Workspace } from '@blocksuite/store';
|
||||||
import { QueryContent } from '@blocksuite/store/dist/workspace/search';
|
import { QueryContent } from '@blocksuite/store/dist/workspace/search';
|
||||||
import { PageMeta, useAppState } from '@/providers/app-state-provider';
|
import { PageMeta } from '@/providers/app-state-provider';
|
||||||
import { EditorContainer } from '@blocksuite/editor';
|
import { EditorContainer } from '@blocksuite/editor';
|
||||||
import { useChangePageMeta } from '@/hooks/use-change-page-meta';
|
import { useChangePageMeta } from '@/hooks/use-change-page-meta';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { WorkspaceUnit } from '@affine/datacenter';
|
import { WorkspaceUnit } from '@affine/datacenter';
|
||||||
import { useGlobalState } from '@/store/app';
|
import { useGlobalState } from '@/store/app';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
export type EditorHandlers = {
|
export type EditorHandlers = {
|
||||||
createPage: (params?: {
|
createPage: (params?: {
|
||||||
@@ -41,7 +42,9 @@ export const usePageHelper = (): EditorHandlers => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const changePageMeta = useChangePageMeta();
|
const changePageMeta = useChangePageMeta();
|
||||||
const editor = useGlobalState(store => store.editor);
|
const editor = useGlobalState(store => store.editor);
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
createPage: ({
|
createPage: ({
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import { WorkspaceUnit } from '@affine/datacenter';
|
import { WorkspaceUnit } from '@affine/datacenter';
|
||||||
import { useGlobalState } from '@/store/app';
|
import { useGlobalState } from '@/store/app';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
export const useWorkspaceHelper = () => {
|
export const useWorkspaceHelper = () => {
|
||||||
const dataCenter = useGlobalState(store => store.dataCenter);
|
const dataCenter = useGlobalState(store => store.dataCenter);
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
|
const loadWorkspace = useGlobalState(store => store.loadWorkspace);
|
||||||
const createWorkspace = async (name: string) => {
|
const createWorkspace = async (name: string) => {
|
||||||
const workspaceInfo = await dataCenter.createWorkspace({
|
const workspaceInfo = await dataCenter.createWorkspace({
|
||||||
name: name,
|
name: name,
|
||||||
});
|
});
|
||||||
if (workspaceInfo && workspaceInfo.id) {
|
if (workspaceInfo && workspaceInfo.id) {
|
||||||
return await dataCenter.loadWorkspace(workspaceInfo.id);
|
return loadWorkspace(workspaceInfo.id);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ import Head from 'next/head';
|
|||||||
import '@affine/i18n';
|
import '@affine/i18n';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { DataCenterLoader, GlobalAppProvider } from '@/store/app';
|
import { GlobalAppProvider } from '@/store/app';
|
||||||
|
import { DataCenterLoader } from '@/store/app/datacenter';
|
||||||
|
|
||||||
const ThemeProvider = dynamic(() => import('@/providers/ThemeProvider'), {
|
const ThemeProvider = dynamic(() => import('@/providers/ThemeProvider'), {
|
||||||
ssr: false,
|
ssr: false,
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
import { PropsWithChildren, ReactElement, useEffect, useState } from 'react';
|
import {
|
||||||
|
PropsWithChildren,
|
||||||
|
ReactElement,
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useState,
|
||||||
|
} from 'react';
|
||||||
import { EditorHeader } from '@/components/header';
|
import { EditorHeader } from '@/components/header';
|
||||||
import MobileModal from '@/components/mobile-modal';
|
import MobileModal from '@/components/mobile-modal';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import type { NextPageWithLayout } from '../..//_app';
|
import type { NextPageWithLayout } from '../..//_app';
|
||||||
import WorkspaceLayout from '@/components/workspace-layout';
|
import WorkspaceLayout from '@/components/workspace-layout';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
@@ -53,7 +58,9 @@ const BlockHubAppender = () => {
|
|||||||
const Page: NextPageWithLayout = () => {
|
const Page: NextPageWithLayout = () => {
|
||||||
const currentPage = useGlobalState(store => store.currentPage);
|
const currentPage = useGlobalState(store => store.currentPage);
|
||||||
const setEditor = useGlobalState(store => store.setEditor);
|
const setEditor = useGlobalState(store => store.setEditor);
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@@ -95,7 +102,9 @@ const PageDefender = ({ children }: PropsWithChildren) => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [pageLoaded, setPageLoaded] = useState(false);
|
const [pageLoaded, setPageLoaded] = useState(false);
|
||||||
const loadPage = useGlobalState(store => store.loadPage);
|
const loadPage = useGlobalState(store => store.loadPage);
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
const { createPage } = usePageHelper();
|
const { createPage } = usePageHelper();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
import { PageList } from '@/components/page-list';
|
import { PageList } from '@/components/page-list';
|
||||||
import { AllPagesIcon } from '@blocksuite/icons';
|
import { AllPagesIcon } from '@blocksuite/icons';
|
||||||
import { PageListHeader } from '@/components/header';
|
import { PageListHeader } from '@/components/header';
|
||||||
import { ReactElement } from 'react';
|
import { ReactElement, useCallback } from 'react';
|
||||||
import WorkspaceLayout from '@/components/workspace-layout';
|
import WorkspaceLayout from '@/components/workspace-layout';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
import { PageMeta, useAppState } from '@/providers/app-state-provider';
|
import { PageMeta } from '@/providers/app-state-provider';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
|
import { useGlobalState } from '@/store/app';
|
||||||
|
|
||||||
const All = () => {
|
const All = () => {
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
const pageList = (currentWorkspace?.blocksuiteWorkspace?.meta.pageMetas ||
|
const pageList = (currentWorkspace?.blocksuiteWorkspace?.meta.pageMetas ||
|
||||||
[]) as PageMeta[];
|
[]) as PageMeta[];
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ import { FavouritesIcon } from '@blocksuite/icons';
|
|||||||
import { ReactElement } from 'react';
|
import { ReactElement } from 'react';
|
||||||
import WorkspaceLayout from '@/components/workspace-layout';
|
import WorkspaceLayout from '@/components/workspace-layout';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
|
import { useGlobalState } from '@/store/app';
|
||||||
|
|
||||||
export const Favorite = () => {
|
export const Favorite = () => {
|
||||||
const { pageList } = useAppState();
|
const pageList = useGlobalState(store => store.dataCenterPageList);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
import { useEffect } from 'react';
|
import { useCallback, useEffect } from 'react';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import useEnsureWorkspace from '@/hooks/use-ensure-workspace';
|
import useEnsureWorkspace from '@/hooks/use-ensure-workspace';
|
||||||
import { PageLoading } from '@/components/loading';
|
import { PageLoading } from '@/components/loading';
|
||||||
import usePageHelper from '@/hooks/use-page-helper';
|
import usePageHelper from '@/hooks/use-page-helper';
|
||||||
|
import { useGlobalState } from '@/store/app';
|
||||||
|
|
||||||
const WorkspaceIndex = () => {
|
const WorkspaceIndex = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
const { createPage } = usePageHelper();
|
const { createPage } = usePageHelper();
|
||||||
const { workspaceLoaded, activeWorkspaceId } = useEnsureWorkspace();
|
const { workspaceLoaded, activeWorkspaceId } = useEnsureWorkspace();
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
CSSProperties,
|
CSSProperties,
|
||||||
useEffect,
|
useEffect,
|
||||||
startTransition,
|
startTransition,
|
||||||
|
useCallback,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import {
|
import {
|
||||||
GeneralPage,
|
GeneralPage,
|
||||||
@@ -18,7 +19,6 @@ import {
|
|||||||
ExportPage,
|
ExportPage,
|
||||||
} from '@/components/workspace-setting';
|
} from '@/components/workspace-setting';
|
||||||
import { SettingsIcon } from '@blocksuite/icons';
|
import { SettingsIcon } from '@blocksuite/icons';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import WorkspaceLayout from '@/components/workspace-layout';
|
import WorkspaceLayout from '@/components/workspace-layout';
|
||||||
import { WorkspaceUnit } from '@affine/datacenter';
|
import { WorkspaceUnit } from '@affine/datacenter';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
@@ -98,7 +98,9 @@ const StyledTabButtonWrapper = styled.div(() => {
|
|||||||
});
|
});
|
||||||
const WorkspaceSetting = () => {
|
const WorkspaceSetting = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
const { activeTabPanelRender, tableArr, handleTabChange, activeTab } =
|
const { activeTabPanelRender, tableArr, handleTabChange, activeTab } =
|
||||||
useTabMap();
|
useTabMap();
|
||||||
const [indicatorState, setIndicatorState] = useState<
|
const [indicatorState, setIndicatorState] = useState<
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import { TrashIcon } from '@blocksuite/icons';
|
|||||||
import { ReactElement } from 'react';
|
import { ReactElement } from 'react';
|
||||||
import WorkspaceLayout from '@/components/workspace-layout';
|
import WorkspaceLayout from '@/components/workspace-layout';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
|
import { useGlobalState } from '@/store/app';
|
||||||
export const Trash = () => {
|
export const Trash = () => {
|
||||||
const { pageList } = useAppState();
|
const pageList = useGlobalState(store => store.dataCenterPageList);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import { useEffect } from 'react';
|
import { useCallback, useEffect } from 'react';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
|
||||||
import useEnsureWorkspace from '@/hooks/use-ensure-workspace';
|
import useEnsureWorkspace from '@/hooks/use-ensure-workspace';
|
||||||
import { PageLoading } from '@/components/loading';
|
import { PageLoading } from '@/components/loading';
|
||||||
|
import { useGlobalState } from '@/store/app';
|
||||||
|
|
||||||
export const WorkspaceIndex = () => {
|
export const WorkspaceIndex = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { currentWorkspace } = useAppState();
|
const currentWorkspace = useGlobalState(
|
||||||
|
useCallback(store => store.currentDataCenterWorkspace, [])
|
||||||
|
);
|
||||||
const { workspaceLoaded } = useEnsureWorkspace();
|
const { workspaceLoaded } = useEnsureWorkspace();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -1,16 +1,8 @@
|
|||||||
import { createContext, useContext, useEffect, useState, useRef } from 'react';
|
import { createContext, useContext, useEffect, useState } from 'react';
|
||||||
import type { PropsWithChildren } from 'react';
|
import type { PropsWithChildren } from 'react';
|
||||||
import {
|
import { AppStateContext } from './interface';
|
||||||
AppStateContext,
|
import type { Disposable } from '@blocksuite/global/utils';
|
||||||
AppStateFunction,
|
import { useGlobalState } from '@/store/app';
|
||||||
AppStateValue,
|
|
||||||
PageMeta,
|
|
||||||
} from './interface';
|
|
||||||
import { useGlobalState, useGlobalStateApi } from '@/store/app';
|
|
||||||
|
|
||||||
export interface Disposable {
|
|
||||||
dispose(): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
type AppStateContextProps = PropsWithChildren<Record<string, unknown>>;
|
type AppStateContextProps = PropsWithChildren<Record<string, unknown>>;
|
||||||
|
|
||||||
@@ -20,113 +12,14 @@ export const useAppState = () => useContext(AppState);
|
|||||||
export const AppStateProvider = ({
|
export const AppStateProvider = ({
|
||||||
children,
|
children,
|
||||||
}: PropsWithChildren<AppStateContextProps>) => {
|
}: PropsWithChildren<AppStateContextProps>) => {
|
||||||
const globalStateApi = useGlobalStateApi();
|
const currentDataCenterWorkspace = useGlobalState(
|
||||||
const [appState, setAppState] = useState<AppStateValue>({} as AppStateValue);
|
store => store.currentDataCenterWorkspace
|
||||||
|
);
|
||||||
const [blobState, setBlobState] = useState(false);
|
const [blobState, setBlobState] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!appState?.currentWorkspace?.blocksuiteWorkspace) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const currentWorkspace = appState.currentWorkspace;
|
|
||||||
const dispose = currentWorkspace?.blocksuiteWorkspace?.meta.pagesUpdated.on(
|
|
||||||
() => {
|
|
||||||
setAppState({
|
|
||||||
...appState,
|
|
||||||
pageList: currentWorkspace.blocksuiteWorkspace?.meta
|
|
||||||
.pageMetas as PageMeta[],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
).dispose;
|
|
||||||
return () => {
|
|
||||||
dispose && dispose();
|
|
||||||
};
|
|
||||||
}, [appState]);
|
|
||||||
|
|
||||||
const onceRef = useRef(true);
|
|
||||||
const dataCenter = useGlobalState(store => store.dataCenter);
|
|
||||||
if (onceRef.current && dataCenter) {
|
|
||||||
setAppState({
|
|
||||||
workspaceList: dataCenter.workspaces,
|
|
||||||
currentWorkspace: null,
|
|
||||||
pageList: [],
|
|
||||||
});
|
|
||||||
onceRef.current = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// FIXME: onWorkspacesChange should have dispose function
|
|
||||||
return dataCenter?.onWorkspacesChange(
|
|
||||||
() => {
|
|
||||||
setAppState(_appState => ({
|
|
||||||
..._appState,
|
|
||||||
workspaceList: dataCenter.workspaces,
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
{ immediate: false }
|
|
||||||
);
|
|
||||||
}, [dataCenter]);
|
|
||||||
|
|
||||||
const loadWorkspace: AppStateFunction['loadWorkspace'] =
|
|
||||||
useRef() as AppStateFunction['loadWorkspace'];
|
|
||||||
loadWorkspace.current = async (workspaceId, abort) => {
|
|
||||||
const { dataCenter } = globalStateApi.getState();
|
|
||||||
const { workspaceList, currentWorkspace } = appState;
|
|
||||||
if (!workspaceList.find(v => v.id.toString() === workspaceId)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (workspaceId === currentWorkspace?.id) {
|
|
||||||
return currentWorkspace;
|
|
||||||
}
|
|
||||||
|
|
||||||
let aborted = false;
|
|
||||||
|
|
||||||
const onAbort = () => {
|
|
||||||
aborted = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
abort?.addEventListener('abort', onAbort);
|
|
||||||
|
|
||||||
const workspace = (await dataCenter.loadWorkspace(workspaceId)) ?? null;
|
|
||||||
|
|
||||||
if (aborted) {
|
|
||||||
// do not update state if aborted
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let isOwner;
|
|
||||||
if (workspace?.provider === 'local') {
|
|
||||||
// isOwner is useful only in the cloud
|
|
||||||
isOwner = true;
|
|
||||||
} else {
|
|
||||||
const userInfo = globalStateApi.getState().user;
|
|
||||||
// We must ensure workspace.owner exists, then ensure id same.
|
|
||||||
isOwner = workspace?.owner && userInfo?.id === workspace.owner.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
const pageList =
|
|
||||||
(workspace?.blocksuiteWorkspace?.meta.pageMetas as PageMeta[]) ?? [];
|
|
||||||
if (workspace?.blocksuiteWorkspace) {
|
|
||||||
globalStateApi.getState().setWorkspace(workspace.blocksuiteWorkspace);
|
|
||||||
}
|
|
||||||
globalStateApi.setState({
|
|
||||||
isOwner,
|
|
||||||
});
|
|
||||||
|
|
||||||
setAppState({
|
|
||||||
...appState,
|
|
||||||
currentWorkspace: workspace,
|
|
||||||
pageList: pageList,
|
|
||||||
});
|
|
||||||
|
|
||||||
abort?.removeEventListener('abort', onAbort);
|
|
||||||
|
|
||||||
return workspace;
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let syncChangeDisposable: Disposable | undefined;
|
let syncChangeDisposable: Disposable | undefined;
|
||||||
const currentWorkspace = appState.currentWorkspace;
|
const currentWorkspace = currentDataCenterWorkspace;
|
||||||
if (!currentWorkspace) {
|
if (!currentWorkspace) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -142,13 +35,11 @@ export const AppStateProvider = ({
|
|||||||
return () => {
|
return () => {
|
||||||
syncChangeDisposable?.dispose();
|
syncChangeDisposable?.dispose();
|
||||||
};
|
};
|
||||||
}, [appState.currentWorkspace]);
|
}, [currentDataCenterWorkspace]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppState.Provider
|
<AppState.Provider
|
||||||
value={{
|
value={{
|
||||||
...appState,
|
|
||||||
loadWorkspace: loadWorkspace,
|
|
||||||
blobDataSynced: blobState,
|
blobDataSynced: blobState,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { WorkspaceUnit } from '@affine/datacenter';
|
|
||||||
import type { EditorContainer } from '@blocksuite/editor';
|
import type { EditorContainer } from '@blocksuite/editor';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
Page as StorePage,
|
Page as StorePage,
|
||||||
PageMeta as StorePageMeta,
|
PageMeta as StorePageMeta,
|
||||||
} from '@blocksuite/store';
|
} from '@blocksuite/store';
|
||||||
import { MutableRefObject } from 'react';
|
|
||||||
export interface PageMeta extends StorePageMeta {
|
export interface PageMeta extends StorePageMeta {
|
||||||
favorite: boolean;
|
favorite: boolean;
|
||||||
trash: boolean;
|
trash: boolean;
|
||||||
@@ -15,16 +14,14 @@ export interface PageMeta extends StorePageMeta {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type AppStateValue = {
|
export type AppStateValue = {
|
||||||
workspaceList: WorkspaceUnit[];
|
blobDataSynced: boolean;
|
||||||
currentWorkspace: WorkspaceUnit | null;
|
|
||||||
pageList: PageMeta[];
|
|
||||||
blobDataSynced?: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
export type AppStateFunction = {
|
export type AppStateFunction = {
|
||||||
loadWorkspace: MutableRefObject<
|
// todo: remove this in the future
|
||||||
(workspaceId: string, abort?: AbortSignal) => Promise<WorkspaceUnit | null>
|
|
||||||
>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AppStateContext = AppStateValue & AppStateFunction;
|
export type AppStateContext = AppStateValue & AppStateFunction;
|
||||||
|
|||||||
139
apps/web/src/store/app/datacenter/index.ts
Normal file
139
apps/web/src/store/app/datacenter/index.ts
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
import {
|
||||||
|
GlobalActionsCreator,
|
||||||
|
useGlobalState,
|
||||||
|
useGlobalStateApi,
|
||||||
|
} from '@/store/app';
|
||||||
|
import type { DataCenter } from '@affine/datacenter';
|
||||||
|
import { PageMeta } from '@/providers/app-state-provider';
|
||||||
|
import { getDataCenter, WorkspaceUnit } from '@affine/datacenter';
|
||||||
|
import { createDefaultWorkspace } from '@/providers/app-state-provider/utils';
|
||||||
|
import { useCallback, useEffect } from 'react';
|
||||||
|
import { DisposableGroup } from '@blocksuite/global/utils';
|
||||||
|
|
||||||
|
export type DataCenterState = {
|
||||||
|
readonly dataCenter: DataCenter;
|
||||||
|
readonly dataCenterPromise: Promise<DataCenter>;
|
||||||
|
currentDataCenterWorkspace: WorkspaceUnit | null;
|
||||||
|
dataCenterPageList: PageMeta[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DataCenterActions = {
|
||||||
|
loadWorkspace: (
|
||||||
|
workspaceId: string,
|
||||||
|
signal?: AbortSignal
|
||||||
|
) => Promise<WorkspaceUnit | null>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createDataCenterState = (): DataCenterState => ({
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
dataCenter: null!,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
dataCenterPromise: null!,
|
||||||
|
currentDataCenterWorkspace: null,
|
||||||
|
dataCenterPageList: [],
|
||||||
|
});
|
||||||
|
export const createDataCenterActions: GlobalActionsCreator<
|
||||||
|
DataCenterActions
|
||||||
|
> = (set, get) => ({
|
||||||
|
loadWorkspace: async (workspaceId, signal) => {
|
||||||
|
const { dataCenter, currentDataCenterWorkspace } = get();
|
||||||
|
if (!dataCenter.workspaces.find(v => v.id.toString() === workspaceId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (workspaceId === currentDataCenterWorkspace?.id) {
|
||||||
|
return currentDataCenterWorkspace;
|
||||||
|
}
|
||||||
|
const workspace = (await dataCenter.loadWorkspace(workspaceId)) ?? null;
|
||||||
|
|
||||||
|
if (signal?.aborted) {
|
||||||
|
// do not update state if aborted
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let isOwner;
|
||||||
|
if (workspace?.provider === 'local') {
|
||||||
|
// isOwner is useful only in the cloud
|
||||||
|
isOwner = true;
|
||||||
|
} else {
|
||||||
|
const userInfo = get().user;
|
||||||
|
// We must ensure workspace.owner exists, then ensure id same.
|
||||||
|
isOwner = workspace?.owner && userInfo?.id === workspace.owner.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageList =
|
||||||
|
(workspace?.blocksuiteWorkspace?.meta.pageMetas as PageMeta[]) ?? [];
|
||||||
|
if (workspace?.blocksuiteWorkspace) {
|
||||||
|
set({
|
||||||
|
currentWorkspace: workspace.blocksuiteWorkspace,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set({
|
||||||
|
isOwner,
|
||||||
|
});
|
||||||
|
|
||||||
|
set({
|
||||||
|
currentDataCenterWorkspace: workspace,
|
||||||
|
dataCenterPageList: pageList,
|
||||||
|
});
|
||||||
|
|
||||||
|
return workspace;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export function DataCenterLoader() {
|
||||||
|
const dataCenter = useGlobalState(useCallback(store => store.dataCenter, []));
|
||||||
|
const dataCenterPromise = useGlobalState(
|
||||||
|
useCallback(store => store.dataCenterPromise, [])
|
||||||
|
);
|
||||||
|
const api = useGlobalStateApi();
|
||||||
|
//# region effect for updating workspace page list
|
||||||
|
useEffect(() => {
|
||||||
|
return api.subscribe(
|
||||||
|
store => store.currentDataCenterWorkspace,
|
||||||
|
currentWorkspace => {
|
||||||
|
const disposableGroup = new DisposableGroup();
|
||||||
|
disposableGroup.add(
|
||||||
|
currentWorkspace?.blocksuiteWorkspace?.meta.pagesUpdated.on(() => {
|
||||||
|
if (
|
||||||
|
Array.isArray(
|
||||||
|
currentWorkspace.blocksuiteWorkspace?.meta.pageMetas
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
api.setState({
|
||||||
|
dataCenterPageList: currentWorkspace.blocksuiteWorkspace?.meta
|
||||||
|
.pageMetas as PageMeta[],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return () => {
|
||||||
|
disposableGroup.dispose();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, [api]);
|
||||||
|
//# endregion
|
||||||
|
|
||||||
|
if (!dataCenter && !dataCenterPromise) {
|
||||||
|
const promise = getDataCenter();
|
||||||
|
api.setState({ dataCenterPromise: promise });
|
||||||
|
promise.then(async dataCenter => {
|
||||||
|
// Ensure datacenter has at least one workspace
|
||||||
|
if (dataCenter.workspaces.length === 0) {
|
||||||
|
await createDefaultWorkspace(dataCenter);
|
||||||
|
}
|
||||||
|
// set initial state
|
||||||
|
api.setState({
|
||||||
|
dataCenter,
|
||||||
|
currentWorkspace: null,
|
||||||
|
currentDataCenterWorkspace: null,
|
||||||
|
dataCenterPageList: [],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
throw promise;
|
||||||
|
}
|
||||||
|
if (!dataCenter) {
|
||||||
|
throw dataCenterPromise;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
@@ -15,8 +15,12 @@ import {
|
|||||||
UserActions,
|
UserActions,
|
||||||
UserState,
|
UserState,
|
||||||
} from '@/store/app/user';
|
} from '@/store/app/user';
|
||||||
import { DataCenter, getDataCenter } from '@affine/datacenter';
|
import {
|
||||||
import { createDefaultWorkspace } from '@/providers/app-state-provider/utils';
|
createDataCenterActions,
|
||||||
|
createDataCenterState,
|
||||||
|
DataCenterActions,
|
||||||
|
DataCenterState,
|
||||||
|
} from '@/store/app/datacenter';
|
||||||
|
|
||||||
export type GlobalActionsCreator<Actions, Store = GlobalState> = StateCreator<
|
export type GlobalActionsCreator<Actions, Store = GlobalState> = StateCreator<
|
||||||
Store,
|
Store,
|
||||||
@@ -25,12 +29,15 @@ export type GlobalActionsCreator<Actions, Store = GlobalState> = StateCreator<
|
|||||||
Actions
|
Actions
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export interface GlobalState extends BlockSuiteState, UserState {
|
export interface GlobalState
|
||||||
readonly dataCenter: DataCenter;
|
extends BlockSuiteState,
|
||||||
readonly dataCenterPromise: Promise<DataCenter>;
|
UserState,
|
||||||
}
|
DataCenterState {}
|
||||||
|
|
||||||
export interface GlobalActions extends BlockSuiteActions, UserActions {}
|
export interface GlobalActions
|
||||||
|
extends BlockSuiteActions,
|
||||||
|
UserActions,
|
||||||
|
DataCenterActions {}
|
||||||
|
|
||||||
const create = () =>
|
const create = () =>
|
||||||
createStore(
|
createStore(
|
||||||
@@ -39,15 +46,13 @@ const create = () =>
|
|||||||
{
|
{
|
||||||
...createBlockSuiteState(),
|
...createBlockSuiteState(),
|
||||||
...createUserState(),
|
...createUserState(),
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
...createDataCenterState(),
|
||||||
dataCenter: null!,
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
||||||
dataCenterPromise: null!,
|
|
||||||
},
|
},
|
||||||
/* deepscan-disable TOO_MANY_ARGS */
|
/* deepscan-disable TOO_MANY_ARGS */
|
||||||
(set, get, api) => ({
|
(set, get, api) => ({
|
||||||
...createBlockSuiteActions(set, get, api),
|
...createBlockSuiteActions(set, get, api),
|
||||||
...createUserActions(set, get, api),
|
...createUserActions(set, get, api),
|
||||||
|
...createDataCenterActions(set, get, api),
|
||||||
})
|
})
|
||||||
/* deepscan-enable TOO_MANY_ARGS */
|
/* deepscan-enable TOO_MANY_ARGS */
|
||||||
)
|
)
|
||||||
@@ -74,28 +79,6 @@ export const useGlobalState: UseBoundStore<Store> = ((
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
}) as any;
|
}) as any;
|
||||||
|
|
||||||
export function DataCenterLoader() {
|
|
||||||
const dataCenter = useGlobalState(store => store.dataCenter);
|
|
||||||
const dataCenterPromise = useGlobalState(store => store.dataCenterPromise);
|
|
||||||
const api = useGlobalStateApi();
|
|
||||||
if (!dataCenter && !dataCenterPromise) {
|
|
||||||
const promise = getDataCenter();
|
|
||||||
api.setState({ dataCenterPromise: promise });
|
|
||||||
promise.then(async dataCenter => {
|
|
||||||
// Ensure datacenter has at least one workspace
|
|
||||||
if (dataCenter.workspaces.length === 0) {
|
|
||||||
await createDefaultWorkspace(dataCenter);
|
|
||||||
}
|
|
||||||
api.setState({ dataCenter });
|
|
||||||
});
|
|
||||||
throw promise;
|
|
||||||
}
|
|
||||||
if (!dataCenter) {
|
|
||||||
throw dataCenterPromise;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const GlobalAppProvider: React.FC<React.PropsWithChildren> =
|
export const GlobalAppProvider: React.FC<React.PropsWithChildren> =
|
||||||
function ModelProvider({ children }) {
|
function ModelProvider({ children }) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
2
pnpm-lock.yaml
generated
2
pnpm-lock.yaml
generated
@@ -164,6 +164,7 @@ importers:
|
|||||||
'@affine/i18n': workspace:*
|
'@affine/i18n': workspace:*
|
||||||
'@blocksuite/blocks': 0.4.0-20230216011811-2776d93
|
'@blocksuite/blocks': 0.4.0-20230216011811-2776d93
|
||||||
'@blocksuite/editor': 0.4.0-20230216011811-2776d93
|
'@blocksuite/editor': 0.4.0-20230216011811-2776d93
|
||||||
|
'@blocksuite/global': 0.4.0-20230216011811-2776d93
|
||||||
'@blocksuite/icons': ^2.0.14
|
'@blocksuite/icons': ^2.0.14
|
||||||
'@blocksuite/store': 0.4.0-20230216011811-2776d93
|
'@blocksuite/store': 0.4.0-20230216011811-2776d93
|
||||||
'@emotion/css': ^11.10.5
|
'@emotion/css': ^11.10.5
|
||||||
@@ -207,6 +208,7 @@ importers:
|
|||||||
'@affine/i18n': link:../../packages/i18n
|
'@affine/i18n': link:../../packages/i18n
|
||||||
'@blocksuite/blocks': 0.4.0-20230216011811-2776d93_trq6tjva7swiv4fhloorah5nty
|
'@blocksuite/blocks': 0.4.0-20230216011811-2776d93_trq6tjva7swiv4fhloorah5nty
|
||||||
'@blocksuite/editor': 0.4.0-20230216011811-2776d93_6yfgczikbxxddpvfspgrnx2z2q
|
'@blocksuite/editor': 0.4.0-20230216011811-2776d93_6yfgczikbxxddpvfspgrnx2z2q
|
||||||
|
'@blocksuite/global': 0.4.0-20230216011811-2776d93_lit@2.6.1
|
||||||
'@blocksuite/icons': 2.0.14_w5j4k42lgipnm43s3brx6h3c34
|
'@blocksuite/icons': 2.0.14_w5j4k42lgipnm43s3brx6h3c34
|
||||||
'@blocksuite/store': 0.4.0-20230216011811-2776d93_lit@2.6.1+yjs@13.5.45
|
'@blocksuite/store': 0.4.0-20230216011811-2776d93_lit@2.6.1+yjs@13.5.45
|
||||||
'@emotion/css': 11.10.5
|
'@emotion/css': 11.10.5
|
||||||
|
|||||||
Reference in New Issue
Block a user