mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-22 20:46:38 +08:00
Feat/land page (#391)
* feat: update landing page * feat: update landing page * fix: react warning * feat(route): rename variables * feat(route): better refresh * fix: update logo and i18n * feat(code): remove unused comment * refactor(workspace): rename workspaceId * refactor(page): rename pageId * feat(edit): more robust editing experience * fix: landing page mobile * fix: landing page mobile Co-authored-by: tzhangchi <terry.zhangchi@outlook.com> Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
This commit is contained in:
@@ -2,8 +2,8 @@ import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { Descendant } from 'slate';
|
||||
|
||||
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
|
||||
import { BlockSearchItem } from '@toeverything/datasource/jwt';
|
||||
import { styled } from '@toeverything/components/ui';
|
||||
import { BlockSearchItem } from '@toeverything/datasource/jwt';
|
||||
|
||||
import { BlockPreview } from '../../block-preview';
|
||||
|
||||
@@ -26,14 +26,14 @@ type InlineRefLinkProps = {
|
||||
};
|
||||
|
||||
export const InlineRefLink = ({ block, pageId }: InlineRefLinkProps) => {
|
||||
const { workspace_id } = useParams();
|
||||
const { workspaceId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
if (block) {
|
||||
return (
|
||||
<BlockPreviewContainer
|
||||
block={block}
|
||||
onClick={() => navigate(`/${workspace_id}/${pageId}`)}
|
||||
onClick={() => navigate(`/${workspaceId}/${pageId}`)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -164,9 +164,6 @@ export const CodeView = ({ block, editor }: CreateCodeView) => {
|
||||
};
|
||||
useEffect(() => {
|
||||
handleLangChange(langType ? langType : DEFAULT_LANG);
|
||||
// setTimeout(() => {
|
||||
// focusCode();
|
||||
// }, 100);
|
||||
}, []);
|
||||
|
||||
const copyCode = () => {
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
} from '../../components/text-manage';
|
||||
|
||||
export const PageView = ({ block, editor }: CreateView) => {
|
||||
const { workspace_id } = useParams();
|
||||
const { workspaceId } = useParams();
|
||||
const textRef = useRef<ExtendedTextUtils>(null);
|
||||
const [backLinks, setBackLinks] =
|
||||
useState<Awaited<ReturnType<typeof editor.search>>>();
|
||||
@@ -100,7 +100,7 @@ export const PageView = ({ block, editor }: CreateView) => {
|
||||
className={style9(styles.content)}
|
||||
suppressContentEditableWarning
|
||||
> */}
|
||||
<BackLink blocks={backLinks} workspaceId={workspace_id} />
|
||||
<BackLink blocks={backLinks} workspaceId={workspaceId} />
|
||||
{/*{block.childrenIds.map(childId => (*/}
|
||||
{/* <RenderBlock key={childId} blockId={childId} />*/}
|
||||
{/*))}*/}
|
||||
|
||||
@@ -6,16 +6,16 @@ import { CreateView } from '@toeverything/framework/virgo';
|
||||
type RefLinkView = CreateView;
|
||||
|
||||
export const RefLinkView = ({ block, editor }: RefLinkView) => {
|
||||
const page_id = useMemo(() => block.getProperty('reference'), [block]);
|
||||
const pageId = useMemo(() => block.getProperty('reference'), [block]);
|
||||
|
||||
const [block_content, set_block] =
|
||||
useState<Awaited<ReturnType<typeof editor.search>>[number]>();
|
||||
|
||||
useEffect(() => {
|
||||
editor
|
||||
.search({ tag: `id:${page_id}` })
|
||||
.search({ tag: `id:${pageId}` })
|
||||
.then(block => set_block(block[0]));
|
||||
}, [editor, page_id]);
|
||||
}, [editor, pageId]);
|
||||
|
||||
return <InlineRefLink block={block_content} pageId={page_id} />;
|
||||
return <InlineRefLink block={block_content} pageId={pageId} />;
|
||||
};
|
||||
|
||||
@@ -90,7 +90,9 @@ export const TextView = ({
|
||||
await block.removeChildren();
|
||||
await block.after(nextBlock);
|
||||
|
||||
editor.selectionManager.activeNodeByNodeId(nextBlock.id);
|
||||
setTimeout(() => {
|
||||
editor.selectionManager.activeNodeByNodeId(nextBlock.id, 'start');
|
||||
});
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { services } from '@toeverything/datasource/db-service';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { WithEditorSelectionType } from '../menu/inline-menu/types';
|
||||
|
||||
export const useAddComment = ({
|
||||
@@ -8,7 +8,7 @@ export const useAddComment = ({
|
||||
selectionInfo,
|
||||
setShow,
|
||||
}: WithEditorSelectionType) => {
|
||||
const { workspace_id: workspaceId, page_id: pageId } = useParams();
|
||||
const { workspaceId, pageId } = useParams();
|
||||
const [currentComment, setCurrentComment] = useState('');
|
||||
|
||||
const createComment = useCallback(async (): Promise<{
|
||||
|
||||
@@ -44,7 +44,7 @@ export const DoubleLinkMenu = ({
|
||||
hooks,
|
||||
style,
|
||||
}: DoubleLinkMenuProps) => {
|
||||
const { page_id: curPageId } = useParams();
|
||||
const { pageId: curPageId } = useParams();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
const dialogRef = useRef<HTMLDivElement>();
|
||||
|
||||
@@ -42,7 +42,7 @@ const normalizeUrl = (url: string) => {
|
||||
};
|
||||
|
||||
export const LinkMenu = ({ editor, hooks }: LinkMenuProps) => {
|
||||
const { page_id: curPageId } = useParams();
|
||||
const { pageId: curPageId } = useParams();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
const dialogRef = useRef<HTMLDivElement>();
|
||||
|
||||
@@ -47,7 +47,7 @@ type SearchProps = {
|
||||
};
|
||||
|
||||
export const Search = (props: SearchProps) => {
|
||||
const { workspace_id: workspaceId } = useParams();
|
||||
const { workspaceId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
@@ -16,7 +16,7 @@ export const Switcher = () => {
|
||||
if (targetViewMode === pageViewMode) {
|
||||
return;
|
||||
}
|
||||
const workspaceId = params['workspace_id'];
|
||||
const workspaceId = params['workspaceId'];
|
||||
/**
|
||||
* There are two possible modes:
|
||||
* Page mode: /{workspaceId}/{pageId}
|
||||
|
||||
@@ -46,7 +46,7 @@ export const AffineHeader = () => {
|
||||
useUserAndSpaces();
|
||||
|
||||
const showCenterTab =
|
||||
(params['workspace_id'] || pathname.includes('/space/')) && params['*'];
|
||||
(params['workspaceId'] || pathname.includes('/space/')) && params['*'];
|
||||
|
||||
if (hideAffineHeader(pathname)) {
|
||||
return null;
|
||||
@@ -82,7 +82,7 @@ export const AffineHeader = () => {
|
||||
isEdgelessView
|
||||
? navigate(
|
||||
`/${
|
||||
params['workspace_id'] ||
|
||||
params['workspaceId'] ||
|
||||
'space'
|
||||
}/${params['*'].slice(0, -11)}`
|
||||
)
|
||||
@@ -108,7 +108,7 @@ export const AffineHeader = () => {
|
||||
? null
|
||||
: navigate(
|
||||
`/${
|
||||
params['workspace_id'] ||
|
||||
params['workspaceId'] ||
|
||||
'space'
|
||||
}/${params['*']}` + '/edgeless'
|
||||
)
|
||||
|
||||
@@ -50,7 +50,7 @@ const MESSAGES = {
|
||||
|
||||
function PageSettingPortal() {
|
||||
const [alertOpen, setAlertOpen] = useState(false);
|
||||
const { workspace_id } = useParams();
|
||||
const { workspaceId } = useParams();
|
||||
const [pageBlock, setPageBlock] = useState<PageBlock>();
|
||||
|
||||
const params = useParams();
|
||||
@@ -64,7 +64,7 @@ function PageSettingPortal() {
|
||||
|
||||
const fetchPageBlock = useCallback(async () => {
|
||||
const dbPageBlock = await services.api.editorBlock.getBlock(
|
||||
workspace_id,
|
||||
workspaceId,
|
||||
pageId
|
||||
);
|
||||
if (!dbPageBlock) return;
|
||||
@@ -78,11 +78,11 @@ function PageSettingPortal() {
|
||||
//@ts-ignore
|
||||
text.value[0].text,
|
||||
});
|
||||
}, [workspace_id, pageId]);
|
||||
}, [workspaceId, pageId]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchPageBlock();
|
||||
}, [workspace_id, pageId, fetchPageBlock]);
|
||||
}, [workspaceId, pageId, fetchPageBlock]);
|
||||
const redirectToPage = (newWorkspaceId: string, newPageId: string) => {
|
||||
navigate('/' + newWorkspaceId + '/' + newPageId);
|
||||
};
|
||||
@@ -90,23 +90,23 @@ function PageSettingPortal() {
|
||||
const handleDuplicatePage = async () => {
|
||||
//create page
|
||||
const newPage = await services.api.editorBlock.create({
|
||||
workspace: workspace_id,
|
||||
workspace: workspaceId,
|
||||
type: 'page' as const,
|
||||
});
|
||||
//add page to tree
|
||||
await services.api.pageTree.addNextPageToWorkspace(
|
||||
workspace_id,
|
||||
workspaceId,
|
||||
pageId,
|
||||
newPage.id
|
||||
);
|
||||
//copy source page to new page
|
||||
await services.api.editorBlock.copyPage(
|
||||
workspace_id,
|
||||
workspaceId,
|
||||
pageId,
|
||||
newPage.id
|
||||
);
|
||||
|
||||
redirectToPage(workspace_id, newPage.id);
|
||||
redirectToPage(workspaceId, newPage.id);
|
||||
};
|
||||
|
||||
const handleCopy = () => {
|
||||
@@ -128,7 +128,7 @@ function PageSettingPortal() {
|
||||
.inspector()
|
||||
.load()
|
||||
.then(() => {
|
||||
window.location.href = `/${workspace_id}/`;
|
||||
window.location.href = `/${workspaceId}/`;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -145,7 +145,7 @@ function PageSettingPortal() {
|
||||
fullWidthChecked: checked,
|
||||
},
|
||||
id: pageId,
|
||||
workspace: workspace_id,
|
||||
workspace: workspaceId,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import { useUserAndSpaces } from '@toeverything/datasource/state';
|
||||
export const CurrentPageTitle = () => {
|
||||
const { user } = useUserAndSpaces();
|
||||
const params = useParams();
|
||||
const { workspace_id } = params;
|
||||
const { workspaceId } = params;
|
||||
const [pageId, setPageId] = useState<string>('');
|
||||
const [pageTitle, setPageTitle] = useState<string | undefined>();
|
||||
/* card.7 */
|
||||
@@ -25,9 +25,9 @@ export const CurrentPageTitle = () => {
|
||||
}, [params]);
|
||||
|
||||
const fetchPageTitle = useCallback(async () => {
|
||||
if (!workspace_id || !pageId) return;
|
||||
if (!workspaceId || !pageId) return;
|
||||
const [pageEditorBlock] = await services.api.editorBlock.get({
|
||||
workspace: workspace_id,
|
||||
workspace: workspaceId,
|
||||
ids: [pageId],
|
||||
});
|
||||
/* card.7 */
|
||||
@@ -39,21 +39,21 @@ export const CurrentPageTitle = () => {
|
||||
?.map(v => v.text)
|
||||
.join('') ?? 'Untitled'
|
||||
);
|
||||
}, [pageId, workspace_id]);
|
||||
}, [pageId, workspaceId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (user) fetchPageTitle();
|
||||
}, [fetchPageTitle, user]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!user || !workspace_id || !pageId || pageTitle === undefined)
|
||||
if (!user || !workspaceId || !pageId || pageTitle === undefined)
|
||||
return () => {};
|
||||
|
||||
let unobserve: () => void;
|
||||
const auto_update_title = async () => {
|
||||
// console.log(';; title registration auto update');
|
||||
unobserve = await services.api.editorBlock.observe(
|
||||
{ workspace: workspace_id, id: pageId },
|
||||
{ workspace: workspaceId, id: pageId },
|
||||
businessBlock => {
|
||||
// console.log(';; auto_update_title', businessBlock);
|
||||
fetchPageTitle();
|
||||
@@ -65,7 +65,7 @@ export const CurrentPageTitle = () => {
|
||||
return () => {
|
||||
// unobserve?.();
|
||||
};
|
||||
}, [fetchPageTitle, pageId, pageTitle, user, workspace_id]);
|
||||
}, [fetchPageTitle, pageId, pageTitle, user, workspaceId]);
|
||||
|
||||
useEffect(() => {
|
||||
document.title = pageTitle || '';
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useParams } from 'react-router-dom';
|
||||
import type { CommentInfo } from './type';
|
||||
|
||||
export const useComments = () => {
|
||||
const { workspace_id: workspaceId, page_id: pageId } = useParams();
|
||||
const { workspaceId, pageId } = useParams();
|
||||
|
||||
const [comments, setComments] = useState<CommentInfo[]>([]);
|
||||
const [observeIds, setObserveIds] = useState<string[]>([]);
|
||||
@@ -71,7 +71,7 @@ export const useComments = () => {
|
||||
};
|
||||
|
||||
export const useActiveComment = () => {
|
||||
const { workspace_id: workspaceId, page_id: pageId } = useParams();
|
||||
const { workspaceId, pageId } = useParams();
|
||||
const { currentEditors } = useCurrentEditors();
|
||||
const editor = useMemo(() => {
|
||||
return currentEditors[pageId] as Virgo;
|
||||
|
||||
@@ -7,7 +7,7 @@ interface UseWorkspaceAndPageIdReturn {
|
||||
|
||||
export const useWorkspaceAndPageId = (): UseWorkspaceAndPageIdReturn => {
|
||||
const params = useParams();
|
||||
const workspaceId = params['workspace_id'];
|
||||
const workspaceId = params['workspaceId'];
|
||||
const pageId = params['*'].split('/')[0];
|
||||
return {
|
||||
workspaceId,
|
||||
|
||||
@@ -47,8 +47,8 @@ export async function fetchActivitiesHeatmap(
|
||||
// const pages = await db.getByType('page');
|
||||
const pages_with_ids = (await Promise.all(
|
||||
flattenedItems.map(async (page_item: any) => {
|
||||
const page_id = page_item.id;
|
||||
return [page_id, await db.get(page_id as 'page')];
|
||||
const pageId = page_item.id;
|
||||
return [pageId, await db.get(pageId as 'page')];
|
||||
})
|
||||
)) as [string, BlockImplInstance][];
|
||||
const pages = new Map(pages_with_ids);
|
||||
|
||||
@@ -57,7 +57,9 @@ export const TreeItem = forwardRef<HTMLDivElement, TreeItemProps>(
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const { workspace_id, page_id } = useParams();
|
||||
const params = useParams();
|
||||
const workspaceId = params['workspaceId'];
|
||||
const curPageId = params['pageId'];
|
||||
const BooleanPageTreeItemMoreActions = useFlag(
|
||||
'BooleanPageTreeItemMoreActions',
|
||||
true
|
||||
@@ -71,7 +73,7 @@ export const TreeItem = forwardRef<HTMLDivElement, TreeItemProps>(
|
||||
disableSelection={disableSelection}
|
||||
disableInteraction={disableInteraction}
|
||||
spacing={`${indentationWidth * depth + 12}px`}
|
||||
active={pageId === page_id}
|
||||
active={pageId === curPageId}
|
||||
{...props}
|
||||
>
|
||||
{childCount !== 0 ? (
|
||||
@@ -89,12 +91,12 @@ export const TreeItem = forwardRef<HTMLDivElement, TreeItemProps>(
|
||||
)}
|
||||
|
||||
<TreeItemContent {...handleProps}>
|
||||
<TextLink to={`/${workspace_id}/${pageId}`}>
|
||||
<TextLink to={`/${workspaceId}/${pageId}`}>
|
||||
{value}
|
||||
</TextLink>
|
||||
{BooleanPageTreeItemMoreActions && (
|
||||
<MoreActions
|
||||
workspaceId={workspace_id}
|
||||
workspaceId={workspaceId}
|
||||
pageId={pageId}
|
||||
onRemove={onRemove}
|
||||
/>
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
const page_tree_atom = atom<TreeItems | undefined>([]);
|
||||
|
||||
export const usePageTree = ({ indentationWidth = 16 }: DndTreeProps = {}) => {
|
||||
const { workspace_id, page_id } = useParams();
|
||||
const { workspaceId, pageId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const [items] = useAtom(page_tree_atom);
|
||||
const [activeId, setActiveId] = useState<string | undefined>(undefined);
|
||||
@@ -56,11 +56,11 @@ export const usePageTree = ({ indentationWidth = 16 }: DndTreeProps = {}) => {
|
||||
const savePageTreeData = useCallback(
|
||||
async (treeData?: TreeItem[]) => {
|
||||
await services.api.pageTree.setPageTree<TreeItem>(
|
||||
workspace_id,
|
||||
workspaceId,
|
||||
treeData || []
|
||||
);
|
||||
},
|
||||
[workspace_id]
|
||||
[workspaceId]
|
||||
);
|
||||
|
||||
const resetState = useCallback(() => {
|
||||
@@ -129,19 +129,19 @@ export const usePageTree = ({ indentationWidth = 16 }: DndTreeProps = {}) => {
|
||||
const handleRemove = useCallback(
|
||||
async (id: string) => {
|
||||
await savePageTreeData(removeItem(items, id));
|
||||
await services.api.userConfig.removePage(workspace_id, id);
|
||||
await services.api.userConfig.removePage(workspaceId, id);
|
||||
//remove page from jwst
|
||||
await services.api.pageTree.removePage(workspace_id, id);
|
||||
if (id === page_id) {
|
||||
navigate(`/${workspace_id}`);
|
||||
await services.api.pageTree.removePage(workspaceId, id);
|
||||
if (id === pageId) {
|
||||
navigate(`/${workspaceId}`);
|
||||
}
|
||||
},
|
||||
[items, savePageTreeData, workspace_id]
|
||||
[items, savePageTreeData, workspaceId]
|
||||
);
|
||||
|
||||
const handleAddPage = useCallback(
|
||||
async (page_id?: string) => {
|
||||
await savePageTreeData([{ id: page_id, children: [] }, ...items]);
|
||||
async (pageId?: string) => {
|
||||
await savePageTreeData([{ id: pageId, children: [] }, ...items]);
|
||||
},
|
||||
[items, savePageTreeData]
|
||||
);
|
||||
@@ -177,25 +177,25 @@ export const usePageTree = ({ indentationWidth = 16 }: DndTreeProps = {}) => {
|
||||
|
||||
export const useDndTreeAutoUpdate = () => {
|
||||
const [, set_items] = useAtom(page_tree_atom);
|
||||
const { workspace_id, page_id } = useParams();
|
||||
const { workspaceId, pageId } = useParams();
|
||||
|
||||
const fetch_page_tree_data = useCallback(async () => {
|
||||
const pages = await services.api.pageTree.getPageTree<TreeItem>(
|
||||
workspace_id
|
||||
workspaceId
|
||||
);
|
||||
set_items(pages);
|
||||
}, [set_items, workspace_id]);
|
||||
}, [set_items, workspaceId]);
|
||||
|
||||
useEffect(() => {
|
||||
fetch_page_tree_data();
|
||||
}, [fetch_page_tree_data]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!page_id) return () => {};
|
||||
if (!pageId) return () => {};
|
||||
let unobserve: () => void;
|
||||
const auto_update_page_tree = async () => {
|
||||
unobserve = await services.api.pageTree.observe(
|
||||
{ workspace: workspace_id, page: page_id },
|
||||
{ workspace: workspaceId, page: pageId },
|
||||
() => {
|
||||
fetch_page_tree_data();
|
||||
}
|
||||
@@ -206,5 +206,5 @@ export const useDndTreeAutoUpdate = () => {
|
||||
return () => {
|
||||
unobserve?.();
|
||||
};
|
||||
}, [fetch_page_tree_data, page_id, workspace_id]);
|
||||
}, [fetch_page_tree_data, pageId, workspaceId]);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user