Merge branch 'master' into develop

This commit is contained in:
DarkSky
2022-08-07 22:33:30 +08:00
committed by GitHub
21 changed files with 230 additions and 219 deletions
+26 -1
View File
@@ -18,6 +18,12 @@ interface AffineEditorProps {
scrollBlank?: boolean;
isWhiteboard?: boolean;
scrollContainer?: HTMLElement;
scrollController?: {
lockScroll: () => void;
unLockScroll: () => void;
};
}
function _useConstantWithDispose(
@@ -53,13 +59,32 @@ function _useConstantWithDispose(
}
export const AffineEditor = forwardRef<BlockEditor, AffineEditorProps>(
({ workspace, rootBlockId, scrollBlank = true, isWhiteboard }, ref) => {
(
{
workspace,
rootBlockId,
scrollBlank = true,
isWhiteboard,
scrollController,
scrollContainer,
},
ref
) => {
const editor = _useConstantWithDispose(
workspace,
rootBlockId,
isWhiteboard
);
useEffect(() => {
if (scrollContainer) {
editor.scrollManager.scrollContainer = scrollContainer;
}
if (scrollController) {
editor.scrollManager.scrollController = scrollController;
}
}, [editor, scrollContainer, scrollController]);
useImperativeHandle(ref, () => editor);
return (
@@ -31,6 +31,7 @@
"@mui/system": "^5.8.6",
"code-example": "^3.3.6",
"codemirror": "6.0.1",
"codemirror-lang-elixir": "^3.0.0",
"keymap": "link:@codemirror/next/keymap",
"nanoid": "^4.0.0",
"react-resizable": "^3.0.4",
@@ -1,10 +1,9 @@
import { FC, useState, useMemo, useRef, useEffect } from 'react';
import { FC, useState, useRef, useEffect } from 'react';
import { StyleWithAtRules } from 'style9';
import { CreateView } from '@toeverything/framework/virgo';
import CodeMirror from './CodeMirror';
import CodeMirror, { ReactCodeMirrorRef } from './CodeMirror';
import { styled } from '@toeverything/components/ui';
import DeleteSweepOutlinedIcon from '@mui/icons-material/DeleteSweepOutlined';
import { javascript } from '@codemirror/lang-javascript';
import { html } from '@codemirror/lang-html';
@@ -32,6 +31,7 @@ import { powerShell } from '@codemirror/legacy-modes/mode/powershell';
import { brainfuck } from '@codemirror/legacy-modes/mode/brainfuck';
import { stylus } from '@codemirror/legacy-modes/mode/stylus';
import { erlang } from '@codemirror/legacy-modes/mode/erlang';
import { elixir } from 'codemirror-lang-elixir';
import { nginx } from '@codemirror/legacy-modes/mode/nginx';
import { perl } from '@codemirror/legacy-modes/mode/perl';
import { pascal } from '@codemirror/legacy-modes/mode/pascal';
@@ -45,7 +45,6 @@ import { dockerFile } from '@codemirror/legacy-modes/mode/dockerfile';
import { julia } from '@codemirror/legacy-modes/mode/julia';
import { r } from '@codemirror/legacy-modes/mode/r';
import { Extension } from '@codemirror/state';
// import { Select } from '../../components/select';
import { Option, Select } from '@toeverything/components/ui';
import {
@@ -87,6 +86,7 @@ const langs: Record<string, any> = {
brainfuck: () => StreamLanguage.define(brainfuck),
stylus: () => StreamLanguage.define(stylus),
erlang: () => StreamLanguage.define(erlang),
elixir: () => StreamLanguage.define(elixir),
nginx: () => StreamLanguage.define(nginx),
perl: () => StreamLanguage.define(perl),
ruby: () => StreamLanguage.define(ruby),
@@ -100,10 +100,8 @@ const langs: Record<string, any> = {
julia: () => StreamLanguage.define(julia),
dockerfile: () => StreamLanguage.define(dockerFile),
r: () => StreamLanguage.define(r),
// clike: () => StreamLanguage.define(clike),
// clike: () => clike({ }),
};
const DEFAULT_LANG = 'javascript';
const CodeBlock = styled('div')(({ theme }) => ({
backgroundColor: '#F2F5F9',
padding: '8px 24px',
@@ -118,7 +116,7 @@ const CodeBlock = styled('div')(({ theme }) => ({
flexWrap: 'wrap',
justifyContent: 'space-between',
},
'.delete-block': {
'.copy-block': {
padding: '6px 10px',
backgroundColor: '#fff',
borderRadius: theme.affine.shape.borderRadius,
@@ -130,29 +128,27 @@ const CodeBlock = styled('div')(({ theme }) => ({
}));
export const CodeView: FC<CreateCodeView> = ({ block, editor }) => {
const initValue: string = block.getProperty('text')?.value?.[0]?.text;
const langType: string = block.getProperty('lang')?.value?.[0]?.text;
const [mode, setMode] = useState('javascript');
const langType: string = block.getProperty('lang');
const [extensions, setExtensions] = useState<Extension[]>();
const codeMirror = useRef();
useOnSelect(block.id, (is_select: boolean) => {
const codeMirror = useRef<ReactCodeMirrorRef>();
useOnSelect(block.id, (_is_select: boolean) => {
if (codeMirror.current) {
//@ts-ignore
codeMirror?.current?.view?.focus();
}
});
const onChange = (value: any, codeEditor: any) => {
const onChange = (value: string) => {
block.setProperty('text', {
value: [{ text: value }],
});
};
useEffect(() => {
handleLangChange(langType ? langType : 'javascript');
}, []);
function handleLangChange(lang: string) {
const handleLangChange = (lang: string) => {
block.setProperty('lang', lang);
setMode(lang);
setExtensions([langs[lang]()]);
}
};
useEffect(() => {
handleLangChange(langType ? langType : DEFAULT_LANG);
}, []);
const copyCode = () => {
copyToClipboard(initValue);
};
@@ -171,19 +167,12 @@ export const CodeView: FC<CreateCodeView> = ({ block, editor }) => {
>
<div className="operation">
<div className="select">
{/* <Select
label="Lang"
options={Object.keys(langs)}
value={mode}
onChange={evn => handleLangChange(evn.target.value)}
/> */}
<Select
width={128}
placeholder="Search for a field type"
value={mode}
value={langType || DEFAULT_LANG}
listboxStyle={{ maxHeight: '400px' }}
onChange={(selectedValue: string) => {
// setSelectedOption(selectedValue);
handleLangChange(selectedValue);
}}
>
@@ -197,17 +186,8 @@ export const CodeView: FC<CreateCodeView> = ({ block, editor }) => {
</Select>
</div>
<div>
<div className="delete-block" onClick={copyCode}>
<div className="copy-block" onClick={copyCode}>
Copy
{/* <DeleteSweepOutlinedIcon
className="delete-icon"
fontSize="small"
sx={{
color: 'rgba(0,0,0,.5)',
cursor: 'pointer',
'&:hover': { color: 'rgba(0,0,0,.9)' },
}}
/> */}
</div>
</div>
</div>
@@ -1,7 +1,6 @@
import { MuiBackdrop, styled, useTheme } from '@toeverything/components/ui';
import { createContext, ReactNode, useContext, useState } from 'react';
import { createPortal } from 'react-dom';
import { useEditor } from '../Contexts';
import { RenderBlock } from '../render-block';
const Dialog = styled('div')({
@@ -44,8 +43,6 @@ const Modal = ({ open, children }: { open: boolean; children?: ReactNode }) => {
};
const ModalPage = ({ blockId }: { blockId: string | null }) => {
const { editor } = useEditor();
return (
<Modal open={!!blockId}>
{blockId && <RenderBlock blockId={blockId} />}
@@ -116,7 +116,7 @@ export const ReferenceMenu = ({ editor, hooks, style }: ReferenceMenuProps) => {
};
const handle_close = () => {
editor.blockHelper.removeSearchSlash(block_id);
block_id && editor.blockHelper.removeSearchSlash(block_id);
};
return (
@@ -1,5 +1,5 @@
import type { BlockClientInstance } from '@toeverything/datasource/jwt';
import { PAGE_TREE } from '../../utils';
import { PAGE_TREE as pageTreeName } from '../../utils';
import type { ReturnUnobserve } from '../database/observer';
import { ServiceBaseClass } from '../base';
import { TreeItem } from './types';
@@ -7,22 +7,22 @@ import { TreeItem } from './types';
export type ObserveCallback = () => void;
export class PageTree extends ServiceBaseClass {
private async fetch_page_tree<TreeItem>(workspace: string) {
const workspace_db_block = await this.getWorkspaceDbBlock(workspace);
const page_tree_config =
workspace_db_block.getDecoration<TreeItem[]>(PAGE_TREE);
return page_tree_config;
private async _fetchPageTree<TreeItem>(workspace: string) {
const workspaceDbBlock = await this.getWorkspaceDbBlock(workspace);
const pageTreeConfig =
workspaceDbBlock.getDecoration<TreeItem[]>(pageTreeName);
return pageTreeConfig;
}
async getPageTree<TreeItem>(workspace: string): Promise<TreeItem[]> {
try {
const page_tree = await this.fetch_page_tree(workspace);
if (page_tree && page_tree.length) {
const pageTree = await this._fetchPageTree(workspace);
if (pageTree && pageTree.length) {
const db = await this.database.getDatabase(workspace);
const pages = await update_tree_items_title(
const pages = await _updateTreeItemsTitle(
db,
page_tree as [],
pageTree as [],
{}
);
return pages;
@@ -36,8 +36,8 @@ export class PageTree extends ServiceBaseClass {
/** @deprecated should implement more fine-grained crud methods instead of replacing each time with a new array */
async setPageTree<TreeItem>(workspace: string, treeData: TreeItem[]) {
const workspace_db_block = await this.getWorkspaceDbBlock(workspace);
workspace_db_block.setDecoration(PAGE_TREE, treeData);
const workspaceDbBlock = await this.getWorkspaceDbBlock(workspace);
workspaceDbBlock.setDecoration(pageTreeName, treeData);
}
async addPage<TreeItem>(workspace: string, treeData: TreeItem[] | string) {
@@ -51,110 +51,107 @@ export class PageTree extends ServiceBaseClass {
await dbBlock?.remove();
}
async addPageToWorkspacee(
target_workspace_id: string,
new_page_id: string
) {
const items = await this.getPageTree<TreeItem>(target_workspace_id);
await this.setPageTree(target_workspace_id, [
{ id: new_page_id, children: [] },
async addPageToWorkspacee(targetWorkspaceId: string, newPageId: string) {
const items = await this.getPageTree<TreeItem>(targetWorkspaceId);
await this.setPageTree(targetWorkspaceId, [
{ id: newPageId, children: [] },
...items,
]);
}
async addChildPageToWorkspace(
target_workspace_id: string,
parent_page_id: string,
new_page_id: string
targetWorkspaceId: string,
parentPageId: string,
newPageId: string
) {
const pages = await this.getPageTree<TreeItem>(target_workspace_id);
this.build_items_for_child_page(parent_page_id, new_page_id, pages);
const pages = await this.getPageTree<TreeItem>(targetWorkspaceId);
this._buildItemsForChildPage(parentPageId, newPageId, pages);
await this.setPageTree<TreeItem>(target_workspace_id, [...pages]);
await this.setPageTree<TreeItem>(targetWorkspaceId, [...pages]);
}
async addPrevPageToWorkspace(
target_workspace_id: string,
parent_page_id: string,
new_page_id: string
targetWorkspaceId: string,
parentPageId: string,
newPageId: string
) {
const pages = await this.getPageTree<TreeItem>(target_workspace_id);
this.build_items_for_prev_page(parent_page_id, new_page_id, pages);
await this.setPageTree<TreeItem>(target_workspace_id, [...pages]);
const pages = await this.getPageTree<TreeItem>(targetWorkspaceId);
this._buildItemsForPrevPage(parentPageId, newPageId, pages);
await this.setPageTree<TreeItem>(targetWorkspaceId, [...pages]);
}
async addNextPageToWorkspace(
target_workspace_id: string,
parent_page_id: string,
new_page_id: string
targetWorkspaceId: string,
parentPageId: string,
newPageId: string
) {
const pages = await this.getPageTree<TreeItem>(target_workspace_id);
this.build_items_for_next_page(parent_page_id, new_page_id, pages);
await this.setPageTree<TreeItem>(target_workspace_id, [...pages]);
const pages = await this.getPageTree<TreeItem>(targetWorkspaceId);
this._buildItemsForNextPage(parentPageId, newPageId, pages);
await this.setPageTree<TreeItem>(targetWorkspaceId, [...pages]);
}
private build_items_for_next_page(
parent_page_id: string,
new_page_id: string,
private _buildItemsForNextPage(
parentPageId: string,
newPageId: string,
children: TreeItem[]
) {
for (let i = 0; i < children.length; i++) {
const child_page = children[i];
if (child_page.id === parent_page_id) {
const new_page = {
id: new_page_id,
const childPage = children[i];
if (childPage.id === parentPageId) {
const newPage = {
id: newPageId,
title: 'Untitled',
children: [] as TreeItem[],
};
children = children.splice(i + 1, 0, new_page);
} else if (child_page.children && child_page.children.length) {
this.build_items_for_next_page(
parent_page_id,
new_page_id,
child_page.children
children = children.splice(i + 1, 0, newPage);
} else if (childPage.children && childPage.children.length) {
this._buildItemsForNextPage(
parentPageId,
newPageId,
childPage.children
);
}
}
}
private build_items_for_prev_page(
parent_page_id: string,
new_page_id: string,
private _buildItemsForPrevPage(
parentPageId: string,
newPageId: string,
children: TreeItem[]
) {
for (let i = 0; i < children.length; i++) {
const child_page = children[i];
if (child_page.id === parent_page_id) {
const new_page = {
id: new_page_id,
const childPage = children[i];
if (childPage.id === parentPageId) {
const newPage = {
id: newPageId,
title: 'Untitled',
children: [] as TreeItem[],
};
children = children.splice(i - 1, 0, new_page);
} else if (child_page.children && child_page.children.length) {
this.build_items_for_prev_page(
parent_page_id,
new_page_id,
child_page.children
children = children.splice(i - 1, 0, newPage);
} else if (childPage.children && childPage.children.length) {
this._buildItemsForPrevPage(
parentPageId,
newPageId,
childPage.children
);
}
}
}
private build_items_for_child_page(
parent_page_id: string,
new_page_id: string,
private _buildItemsForChildPage(
parentPageId: string,
newPageId: string,
children: TreeItem[]
) {
for (let i = 0; i < children.length; i++) {
const child_page = children[i];
if (child_page.id === parent_page_id) {
child_page.children = child_page.children || [];
child_page.children.push({
id: new_page_id,
const childPage = children[i];
if (childPage.id === parentPageId) {
childPage.children = childPage.children || [];
childPage.children.push({
id: newPageId,
title: 'Untitled',
children: [],
});
} else if (child_page.children && child_page.children.length) {
this.build_items_for_child_page(
parent_page_id,
new_page_id,
child_page.children
} else if (childPage.children && childPage.children.length) {
this._buildItemsForChildPage(
parentPageId,
newPageId,
childPage.children
);
}
}
@@ -164,10 +161,10 @@ export class PageTree extends ServiceBaseClass {
{ workspace, page }: { workspace: string; page: string },
callback: ObserveCallback
): Promise<ReturnUnobserve> {
const workspace_db_block = await this.getWorkspaceDbBlock(workspace);
const workspaceDbBlock = await this.getWorkspaceDbBlock(workspace);
const unobserveWorkspace = await this._observe(
workspace,
workspace_db_block.id,
workspaceDbBlock.id,
(states, block) => {
callback();
}
@@ -187,12 +184,12 @@ export class PageTree extends ServiceBaseClass {
}
async unobserve({ workspace }: { workspace: string }) {
const workspace_db_block = await this.getWorkspaceDbBlock(workspace);
await this._unobserve(workspace, workspace_db_block.id);
const workspaceDbBlock = await this.getWorkspaceDbBlock(workspace);
await this._unobserve(workspace, workspaceDbBlock.id);
}
}
async function update_tree_items_title<
async function _updateTreeItemsTitle<
TreeItem extends { id: string; title: string; children: TreeItem[] }
>(
db: BlockClientInstance,
@@ -213,7 +210,7 @@ async function update_tree_items_title<
}
if (item.children.length) {
item.children = await update_tree_items_title(
item.children = await _updateTreeItemsTitle(
db,
item.children,
cache