diff --git a/README.md b/README.md
index 44c097948e..26d85580e3 100644
--- a/README.md
+++ b/README.md
@@ -40,17 +40,19 @@ See https://github.com/all-?/all-contributors/issues/361#issuecomment-637166066
![affine_screen](https://user-images.githubusercontent.com/21084335/182552060-972cac0e-6258-4ccb-85bd-3bb466c30ccd.png)
-# Stay Up-to-Date
+# Stay Up-to-Date and Support Us
![952cd7a5-70fe-48ab-b74f-23981d94d2c5](https://user-images.githubusercontent.com/79301703/182365526-df074c64-cee4-45f6-b8e0-b912f17332c6.gif)
# How to use
-If you have experience in front-end development, please [refer to here](https://affine.gitbook.io/affine/basic-documentation/contribute-to-affine); if you want to experience our latest version, please wait a moment, we will launch a web version in the near future
+If you have experience in front-end development, please [refer to here](https://affine.gitbook.io/affine/basic-documentation/contribute-to-affine); if you want to experience our latest version, please wait a moment, we will launch a web version in the near future.
+And, thanks to Lee who [made a desktop build with Tauri](https://github.com/m1911star/affine-client) for you to try out.
+Please notice that AFFiNE is still under Alpha stage and is not ready for production use.
# Table of contents
-- [Stay Up-to-Date](#stay-up-to-date)
+- [Stay Up-to-Date and Support Us](#stay-up-to-date-and-support-us)
- [How to Use](#how-to-use)
- [Table of contents](#table-of-contents)
- [Shape your page](#shape-your-page)
@@ -89,7 +91,7 @@ Affine is fully built with web technologies so that consistency and accessibilit
# Documentation
-Please view the [documentation](https://affine.gitbook.io/affine/)
+AFFiNE is not yet ready for production use. To install, you may check how to build or depoly the AFFiNE in [quick-start](https://affine.gitbook.io/affine/basic-documentation/contribute-to-affine/quick-start). For the full documentation, please view it [here](https://affine.gitbook.io/affine/).
## Getting Started with development
@@ -121,7 +123,7 @@ It is all perfect... If there are not so many waste operations and redundant inf
That's why we are making AFFiNE. Some of the most important features are:
- Transformable
- - Every block can be transformed equally as a database
+ - Every block can be transformed equally well as a database
- e.g. you can now set up a to-do with MarkDown in text view and edit it in kanban view.
- Every doc can be turned into a whiteboard
- An always good-to-read, structured docs-form page is the best for your notes, but a boundless doodle surface is better for collaboration and creativity.
diff --git a/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx b/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx
index bdba3722fe..eb6c334803 100644
--- a/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx
+++ b/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx
@@ -33,30 +33,8 @@ export function Page(props: PageProps) {
const { page_id } = useParams();
const { showSpaceSidebar, fixedDisplay, setSpaceSidebarVisible } =
useShowSpaceSidebar();
- const { user } = useUserAndSpaces();
const dailyNotesFlag = useFlag('BooleanDailyNotes', false);
- useEffect(() => {
- if (!user?.id || !page_id) return;
- const updateRecentPages = async () => {
- // TODO: deal with it temporarily
- await services.api.editorBlock.getWorkspaceDbBlock(
- props.workspace,
- {
- userId: user.id,
- }
- );
-
- await services.api.userConfig.addRecentPage(
- props.workspace,
- user.id,
- page_id
- );
- await services.api.editorBlock.clearUndoRedo(props.workspace);
- };
- updateRecentPages();
- }, [user, props.workspace, page_id]);
-
return (
diff --git a/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardContext.tsx b/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardContext.tsx
index cb313d14ee..f7f05b37d4 100644
--- a/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardContext.tsx
+++ b/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardContext.tsx
@@ -25,7 +25,7 @@ const AddCard = ({ group }: { group: KanbanGroup }) => {
const { addCard } = useKanban();
const handleClick = useCallback(async () => {
await addCard(group);
- }, [addCard]);
+ }, [addCard, group]);
return +;
};
diff --git a/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardItem.tsx b/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardItem.tsx
index f26374e4c3..76220d7ff0 100644
--- a/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardItem.tsx
+++ b/libs/components/editor-blocks/src/blocks/group/scene-kanban/CardItem.tsx
@@ -1,6 +1,11 @@
import type { KanbanCard } from '@toeverything/components/editor-core';
-import { RenderBlock, useKanban } from '@toeverything/components/editor-core';
+import {
+ RenderBlock,
+ useKanban,
+ useRefPage,
+} from '@toeverything/components/editor-core';
import { styled } from '@toeverything/components/ui';
+import { useFlag } from '@toeverything/datasource/feature-flags';
const CardContent = styled('div')({
margin: '20px',
@@ -58,18 +63,24 @@ export const CardItem = ({
block: KanbanCard['block'];
}) => {
const { addSubItem } = useKanban();
+ const { openSubPage } = useRefPage();
+ const showKanbanRefPageFlag = useFlag('ShowKanbanRefPage', false);
const onAddItem = async () => {
await addSubItem(block);
};
+ const onClickCard = async () => {
+ showKanbanRefPageFlag && openSubPage(id);
+ };
+
return (
-
+
- Add item
+ Add a sub-block
);
diff --git a/libs/components/editor-blocks/src/blocks/image/ImageView.tsx b/libs/components/editor-blocks/src/blocks/image/ImageView.tsx
index dd07a1058a..369dceac87 100644
--- a/libs/components/editor-blocks/src/blocks/image/ImageView.tsx
+++ b/libs/components/editor-blocks/src/blocks/image/ImageView.tsx
@@ -143,13 +143,13 @@ export const ImageView: FC = ({ block, editor }) => {
type: 'link',
});
};
- const handle_click = (e: React.MouseEvent) => {
+ const handle_click = async (e: React.MouseEvent) => {
//TODO clear active selection
// document.getElementsByTagName('body')[0].click();
e.stopPropagation();
e.nativeEvent.stopPropagation();
- editor.selectionManager.setSelectedNodesIds([block.id]);
- editor.selectionManager.activeNodeByNodeId(block.id);
+ await editor.selectionManager.setSelectedNodesIds([block.id]);
+ await editor.selectionManager.activeNodeByNodeId(block.id, 'end');
};
const down_file = () => {
if (down_ref) {
diff --git a/libs/components/editor-blocks/src/blocks/text/TextView.tsx b/libs/components/editor-blocks/src/blocks/text/TextView.tsx
index 66c6360633..cb408cb189 100644
--- a/libs/components/editor-blocks/src/blocks/text/TextView.tsx
+++ b/libs/components/editor-blocks/src/blocks/text/TextView.tsx
@@ -99,7 +99,7 @@ export const TextView: FC = ({
if (!parentBlock) {
return false;
}
-
+ const preParent = await parentBlock.previousSibling();
if (Protocol.Block.Type.group === parentBlock.type) {
const children = await block.children();
const preNode = await block.physicallyPerviousSibling();
@@ -129,34 +129,19 @@ export const TextView: FC = ({
'start'
);
if (block.blockProvider.isEmpty()) {
- block.remove();
- }
- }
- return true;
- } else {
- // TODO remove timing problem
- const prevGroupBlock = await parentBlock.previousSibling();
-
- if (!prevGroupBlock) {
- const childrenBlock = await parentBlock.children();
- if (childrenBlock.length) {
- if (children.length) {
- await parentBlock.append(...children);
- }
await block.remove();
- return true;
+ const parentChild = await parentBlock.children();
+ if (
+ parentBlock.type ===
+ Protocol.Block.Type.group &&
+ !parentChild.length
+ ) {
+ await editor.selectionManager.setSelectedNodesIds(
+ [preParent?.id ?? editor.getRootBlockId()]
+ );
+ }
}
-
- parentBlock.remove();
- return true;
}
- if (prevGroupBlock.type !== Protocol.Block.Type.group) {
- unwrapGroup(parentBlock);
- return true;
- }
-
- mergeGroup(prevGroupBlock, parentBlock);
-
return true;
}
}
diff --git a/libs/components/editor-blocks/src/components/source-view/SourceView.tsx b/libs/components/editor-blocks/src/components/source-view/SourceView.tsx
index 3835199d3f..4dbb488850 100644
--- a/libs/components/editor-blocks/src/components/source-view/SourceView.tsx
+++ b/libs/components/editor-blocks/src/components/source-view/SourceView.tsx
@@ -1,6 +1,18 @@
-import type { AsyncBlock } from '@toeverything/components/editor-core';
+import {
+ AsyncBlock,
+ useCurrentView,
+ useLazyIframe,
+} from '@toeverything/components/editor-core';
import { styled } from '@toeverything/components/ui';
-import type { FC } from 'react';
+import {
+ FC,
+ ReactElement,
+ ReactNode,
+ useEffect,
+ useRef,
+ useState,
+} from 'react';
+import { SCENE_CONFIG } from '../../blocks/group/config';
import { BlockPreview } from './BlockView';
import { formatUrl } from './format-url';
@@ -15,7 +27,18 @@ export interface Props {
}
const getHost = (url: string) => new URL(url).host;
-
+const MouseMaskContainer = styled('div')({
+ position: 'absolute',
+ zIndex: 1,
+ top: '0px',
+ left: '0px',
+ right: '0px',
+ bottom: '0px',
+ backgroundColor: 'transparent',
+ '&:hover': {
+ pointerEvents: 'none',
+ },
+});
const LinkContainer = styled('div')<{
isSelected: boolean;
}>(({ theme, isSelected }) => {
@@ -38,12 +61,28 @@ const LinkContainer = styled('div')<{
},
};
});
-
+const _getLinkStyle = (scene: string) => {
+ switch (scene) {
+ case SCENE_CONFIG.PAGE:
+ return {
+ width: '420px',
+ height: '198px',
+ };
+ default:
+ return {
+ width: '252px',
+ height: '126px',
+ };
+ }
+};
const SourceViewContainer = styled('div')<{
isSelected: boolean;
-}>(({ theme, isSelected }) => {
+ scene: string;
+}>(({ theme, isSelected, scene }) => {
return {
+ ..._getLinkStyle(scene),
overflow: 'hidden',
+ position: 'relative',
borderRadius: theme.affine.shape.borderRadius,
background: isSelected ? 'rgba(152, 172, 189, 0.1)' : 'transparent',
padding: '8px',
@@ -52,32 +91,96 @@ const SourceViewContainer = styled('div')<{
height: '100%',
border: '1px solid #EAEEF2',
borderRadius: theme.affine.shape.borderRadius,
+ userSelect: 'none',
},
};
});
+const LazyIframe = ({
+ src,
+ delay = 3000,
+ fallback,
+}: {
+ src: string;
+ delay?: number;
+ fallback?: ReactNode;
+}) => {
+ const [show, setShow] = useState(false);
+ const timer = useRef();
+
+ useEffect(() => {
+ // Hide iframe when the src changed
+ setShow(false);
+ }, [src]);
+
+ const onLoad = () => {
+ clearTimeout(timer.current);
+ timer.current = window.setTimeout(() => {
+ // Prevent iframe scrolling parent container
+ // Remove the delay after the issue is resolved
+ // See W3C https://github.com/w3c/csswg-drafts/issues/7134
+ // See https://forum.figma.com/t/prevent-figmas-embed-code-from-automatically-scrolling-to-it-on-page-load/26029/6
+ setShow(true);
+ }, delay);
+ };
+
+ return (
+ <>
+ {
+ e.preventDefault();
+ e.stopPropagation();
+ }}
+ style={{ display: show ? 'block' : 'none', height: '100%' }}
+ >
+
+
+ {!show && fallback}
+ >
+ );
+};
+
+const Loading = styled('div')(() => {
+ return {
+ width: '100%',
+ height: '100%',
+ display: 'flex',
+ lineHeight: '100%',
+ alignItems: 'center',
+ justifyContent: 'center',
+ border: '1px solid #EAEEF2',
+ };
+});
+
+const LoadingContiner = () => {
+ return loading...;
+};
+
export const SourceView: FC = props => {
const { link, isSelected, block, editorElement } = props;
const src = formatUrl(link);
- const openTabOnBrowser = () => {
- window.open(link, '_blank');
- };
+ // let iframeShow = useLazyIframe(src, 3000, iframeContainer);
+ const [currentView] = useCurrentView();
+ const { type } = currentView;
if (src?.startsWith('http')) {
return (
- e.preventDefault()}
- onClick={openTabOnBrowser}
- >
- {getHost(src)}
- {src}
-
+
+
+
+
+
+
+
);
} else if (src?.startsWith('affine')) {
return (
JSX.Element;
@@ -14,6 +13,8 @@ export const RootContext = createContext<{
) as any
);
+export const EditorProvider = RootContext.Provider;
+
export const useEditor = () => {
return useContext(RootContext);
};
@@ -22,16 +23,3 @@ export const useEditor = () => {
* @deprecated
*/
export const BlockContext = createContext(null as any);
-
-/**
- * Context of column information
- *
- * @deprecated
- */
-export const ColumnsContext = createContext<{
- fromId: string;
- columns: Column[];
-}>({
- fromId: '',
- columns: [],
-});
diff --git a/libs/components/editor-core/src/RenderRoot.tsx b/libs/components/editor-core/src/RenderRoot.tsx
index aed9ebea50..e4534b813d 100644
--- a/libs/components/editor-core/src/RenderRoot.tsx
+++ b/libs/components/editor-core/src/RenderRoot.tsx
@@ -2,14 +2,14 @@ import type { BlockEditor } from './editor';
import { styled, usePatchNodes } from '@toeverything/components/ui';
import type { FC, PropsWithChildren } from 'react';
import React, { useEffect, useRef, useState, useCallback } from 'react';
-import { RootContext } from './contexts';
+import { EditorProvider } from './Contexts';
import { SelectionRect, SelectionRef } from './Selection';
import {
Protocol,
services,
type ReturnUnobserve,
} from '@toeverything/datasource/db-service';
-import { addNewGroup } from './recast-block';
+import { addNewGroup, appendNewGroup } from './recast-block';
import { useIsOnDrag } from './hooks';
interface RenderRootProps {
@@ -151,7 +151,7 @@ export const RenderRoot: FC> = ({
};
return (
-
+
{
@@ -183,7 +183,7 @@ export const RenderRoot: FC> = ({
{editor.isWhiteboard ? null : }
{patchedNodes}
-
+
);
};
@@ -199,24 +199,32 @@ function ScrollBlank({ editor }: { editor: BlockEditor }) {
mouseMoved.current = false;
return;
}
- const lastBlock = await editor.getRootLastChildrenBlock();
+ const rootBlock = await editor.getBlockById(
+ editor.getRootBlockId()
+ );
+ if (!rootBlock) {
+ throw new Error('root block is not found');
+ }
- const lastGroupBlock = await editor.getRootLastChildrenBlock();
+ const lastRootChildren = await rootBlock.lastChild();
// If last block is not a group
// create a group with a empty text
- if (lastGroupBlock.type !== 'group') {
- addNewGroup(editor, lastBlock, true);
+ if (lastRootChildren == null) {
+ appendNewGroup(editor, rootBlock, true);
return;
}
- if (lastGroupBlock.childrenIds.length > 1) {
- addNewGroup(editor, lastBlock, true);
+ if (
+ lastRootChildren.type !== Protocol.Block.Type.group ||
+ lastRootChildren.childrenIds.length > 1
+ ) {
+ addNewGroup(editor, lastRootChildren, true);
return;
}
// If the **only** block in the group is text and is empty
// active the text block
- const theGroupChildBlock = await lastGroupBlock.firstChild();
+ const theGroupChildBlock = await lastRootChildren.firstChild();
if (
theGroupChildBlock &&
@@ -229,7 +237,7 @@ function ScrollBlank({ editor }: { editor: BlockEditor }) {
return;
}
// else create a new group
- addNewGroup(editor, lastBlock, true);
+ addNewGroup(editor, lastRootChildren, true);
},
[editor]
);
diff --git a/libs/components/editor-core/src/editor/editor.ts b/libs/components/editor-core/src/editor/editor.ts
index 8750a566c7..208c4e9ef1 100644
--- a/libs/components/editor-core/src/editor/editor.ts
+++ b/libs/components/editor-core/src/editor/editor.ts
@@ -367,15 +367,6 @@ export class Editor implements Virgo {
return blockList;
}
- async getRootLastChildrenBlock(rootBlockId = this.getRootBlockId()) {
- const rootBlock = await this.getBlockById(rootBlockId);
- if (!rootBlock) {
- throw new Error('root block is not found');
- }
- const lastChildren = await rootBlock.lastChild();
- return lastChildren ?? rootBlock;
- }
-
async getLastBlock(rootBlockId = this.getRootBlockId()) {
const rootBlock = await this.getBlockById(rootBlockId);
if (!rootBlock) {
diff --git a/libs/components/editor-core/src/hooks.ts b/libs/components/editor-core/src/hooks.ts
index d7d1a00cef..f0af8a0f87 100644
--- a/libs/components/editor-core/src/hooks.ts
+++ b/libs/components/editor-core/src/hooks.ts
@@ -1,3 +1,6 @@
+import { noop, Point } from '@toeverything/utils';
+import { useCallback, useEffect, useRef, useState } from 'react';
+import { useEditor } from './Contexts';
import {
AsyncBlock,
BlockEditor,
@@ -5,9 +8,6 @@ import {
SelectionInfo,
SelectionSettingsMap,
} from './editor';
-import { noop, Point } from '@toeverything/utils';
-import { useCallback, useContext, useEffect, useRef, useState } from 'react';
-import { RootContext } from './contexts';
function useRequestReRender() {
const [, setUpdateCounter] = useState(0);
@@ -56,7 +56,7 @@ function useRequestReRender() {
export const useBlock = (blockId: string) => {
const [block, setBlock] = useState();
const requestReRender = useRequestReRender();
- const { editor } = useContext(RootContext);
+ const { editor } = useEditor();
useEffect(() => {
if (!blockId) {
return undefined;
@@ -95,7 +95,7 @@ export const useOnSelect = (
blockId: string,
cb: (isSelect: boolean) => void
) => {
- const { editor } = useContext(RootContext);
+ const { editor } = useEditor();
useEffect(() => {
editor.selectionManager.observe(blockId, SelectEventTypes.onSelect, cb);
return () => {
@@ -117,7 +117,7 @@ export const useOnSelectActive = (
blockId: string,
cb: (position: Point | undefined) => void
) => {
- const { editor } = useContext(RootContext);
+ const { editor } = useEditor();
useEffect(() => {
editor.selectionManager.observe(blockId, SelectEventTypes.active, cb);
return () => {
@@ -139,7 +139,7 @@ export const useOnSelectSetSelection = (
blockId: string,
cb: (args: SelectionSettingsMap[T]) => void
) => {
- const { editor } = useContext(RootContext);
+ const { editor } = useEditor();
useEffect(() => {
editor.selectionManager.observe(
blockId,
@@ -162,7 +162,7 @@ export const useOnSelectSetSelection = (
* @export
*/
export const useOnSelectChange = (cb: (info: SelectionInfo) => void) => {
- const { editor } = useContext(RootContext);
+ const { editor } = useEditor();
useEffect(() => {
editor.selectionManager.onSelectionChange(cb);
return () => {
@@ -177,7 +177,7 @@ export const useOnSelectChange = (cb: (info: SelectionInfo) => void) => {
* @export
*/
export const useOnSelectEnd = (cb: (info: SelectionInfo) => void) => {
- const { editor } = useContext(RootContext);
+ const { editor } = useEditor();
useEffect(() => {
editor.selectionManager.onSelectEnd(cb);
return () => {
@@ -195,7 +195,7 @@ export const useOnSelectStartWith = (
blockId: string,
cb: (args: MouseEvent) => void
) => {
- const { editor } = useContext(RootContext);
+ const { editor } = useEditor();
useEffect(() => {
editor.mouseManager.onSelectStartWith(blockId, cb);
return () => {
diff --git a/libs/components/editor-core/src/index.ts b/libs/components/editor-core/src/index.ts
index 6cdd358058..bea2fed3a0 100644
--- a/libs/components/editor-core/src/index.ts
+++ b/libs/components/editor-core/src/index.ts
@@ -1,4 +1,3 @@
-export { ColumnsContext, RootContext } from './contexts';
export { RenderRoot, MIN_PAGE_WIDTH } from './RenderRoot';
export * from './render-block';
export * from './hooks';
@@ -16,3 +15,5 @@ export * from './kanban/types';
export * from './utils';
export * from './editor';
+
+export { RefPageProvider, useRefPage } from './ref-page';
diff --git a/libs/components/editor-core/src/kanban/atom.ts b/libs/components/editor-core/src/kanban/atom.ts
index 1e8b10606e..86858a559e 100644
--- a/libs/components/editor-core/src/kanban/atom.ts
+++ b/libs/components/editor-core/src/kanban/atom.ts
@@ -57,18 +57,13 @@ const isValueBelongOption = (
option: KanbanGroup
) => {
switch (propertyValue.type) {
- case PropertyType.Select || PropertyType.Status: {
+ case PropertyType.Select:
+ case PropertyType.Status: {
return propertyValue.value === option.id;
}
case PropertyType.MultiSelect: {
return propertyValue.value.some(i => i === option.id);
}
- // case PropertyType.Status: {
- // return propertyValue.value === option.id;
- // }
- // case PropertyType.Text: {
- // TOTODO:DO support this type
- // }
default: {
console.error(propertyValue, option);
throw new Error('Not support group by type');
diff --git a/libs/components/editor-core/src/kanban/kanban.ts b/libs/components/editor-core/src/kanban/kanban.ts
index ff33b17f1d..218476ac44 100644
--- a/libs/components/editor-core/src/kanban/kanban.ts
+++ b/libs/components/editor-core/src/kanban/kanban.ts
@@ -1,6 +1,6 @@
import { Protocol } from '@toeverything/datasource/db-service';
import { useCallback, useContext, useEffect, useState } from 'react';
-import { useEditor } from '../contexts';
+import { useEditor } from '../Contexts';
import { AsyncBlock } from '../editor';
import { useRecastView } from '../recast-block';
import { useRecastBlock } from '../recast-block/Context';
diff --git a/libs/components/editor-core/src/recast-block/Context.tsx b/libs/components/editor-core/src/recast-block/Context.tsx
index 55d334039b..47ec6cfcdb 100644
--- a/libs/components/editor-core/src/recast-block/Context.tsx
+++ b/libs/components/editor-core/src/recast-block/Context.tsx
@@ -2,6 +2,7 @@ import { Protocol } from '@toeverything/datasource/db-service';
import { AsyncBlock } from '../editor';
import { ComponentType, createContext, ReactNode, useContext } from 'react';
import { RecastBlock } from './types';
+import { RefPageProvider } from '../ref-page';
/**
* Determine whether the block supports RecastBlock
@@ -47,7 +48,7 @@ export const RecastBlockProvider = ({
return (
- {children}
+ {children}
);
};
@@ -60,7 +61,7 @@ export const useRecastBlock = () => {
const recastBlock = useContext(RecastBlockContext);
if (!recastBlock) {
throw new Error(
- 'Failed to find recastBlock! Please use the hook under `RecastTableProvider`.'
+ 'Failed to find recastBlock! Please use the hook under `RecastBlockProvider`.'
);
}
return recastBlock;
diff --git a/libs/components/editor-core/src/recast-block/README.md b/libs/components/editor-core/src/recast-block/README.md
index 59aed91be7..489412eab3 100644
--- a/libs/components/editor-core/src/recast-block/README.md
+++ b/libs/components/editor-core/src/recast-block/README.md
@@ -49,22 +49,3 @@ const SomeBlock = () => {
return ...
;
};
```
-
-## Scene
-
-**Notice: The scene API will refactor at next version.**
-
-```tsx
-const SomeBlock = () => {
- const { scene, setScene, setPage, setTable, setKanban } =
- useRecastBlockScene();
-
- return (
- <>
- Scene: {scene}
-
-
- >
- );
-};
-```
diff --git a/libs/components/editor-core/src/recast-block/group.ts b/libs/components/editor-core/src/recast-block/group.ts
index b8b25cce01..9879ba43df 100644
--- a/libs/components/editor-core/src/recast-block/group.ts
+++ b/libs/components/editor-core/src/recast-block/group.ts
@@ -32,7 +32,7 @@ export const mergeGroup = async (...groups: AsyncBlock[]) => {
);
}
- await mergeGroupProperties(...(groups as RecastBlock[]));
+ await mergeGroupProperties(...(groups as unknown as RecastBlock[]));
const [headGroup, ...restGroups] = groups;
// Add all children to the head group
@@ -174,7 +174,7 @@ export const splitGroup = async (
}
splitGroupProperties(
- group as RecastBlock,
+ group as unknown as RecastBlock,
newGroupBlock as unknown as RecastBlock
);
await group.after(newGroupBlock);
@@ -185,6 +185,22 @@ export const splitGroup = async (
return newGroupBlock;
};
+export const appendNewGroup = async (
+ editor: BlockEditor,
+ parentBlock: AsyncBlock,
+ active = false
+) => {
+ const newGroupBlock = await createGroupWithEmptyText(editor);
+ await parentBlock.append(newGroupBlock);
+ if (active) {
+ // Active text block
+ await editor.selectionManager.activeNodeByNodeId(
+ newGroupBlock.childrenIds[0]
+ );
+ }
+ return newGroupBlock;
+};
+
export const addNewGroup = async (
editor: BlockEditor,
previousBlock: AsyncBlock,
diff --git a/libs/components/editor-core/src/recast-block/view.ts b/libs/components/editor-core/src/recast-block/view.ts
index c41d09809e..09e4644977 100644
--- a/libs/components/editor-core/src/recast-block/view.ts
+++ b/libs/components/editor-core/src/recast-block/view.ts
@@ -1,5 +1,5 @@
import { nanoid } from 'nanoid';
-import { useCallback } from 'react';
+import { MutableRefObject, useCallback, useEffect, useState } from 'react';
import { useRecastBlock } from './Context';
import {
KanbanView,
@@ -50,7 +50,33 @@ export const useCurrentView = () => {
);
return [currentView, setCurrentView] as const;
};
+export const useLazyIframe = (
+ link: string,
+ timers: number,
+ container: MutableRefObject
+) => {
+ const [iframeShow, setIframeShow] = useState(false);
+ useEffect(() => {
+ const iframe = document.createElement('iframe');
+ iframe.src = link;
+ iframe.onload = () => {
+ setTimeout(() => {
+ // Prevent iframe from scrolling parent container
+ // TODO W3C https://github.com/w3c/csswg-drafts/issues/7134
+ // https://forum.figma.com/t/prevent-figmas-embed-code-from-automatically-scrolling-to-it-on-page-load/26029/6
+ setIframeShow(true);
+ }, timers);
+ };
+ if (container?.current) {
+ container.current.appendChild(iframe);
+ }
+ return () => {
+ iframe.remove();
+ };
+ }, [link, container]);
+ return iframeShow;
+};
export const useRecastView = () => {
const recastBlock = useRecastBlock();
const recastViews =
diff --git a/libs/components/editor-core/src/ref-page/ModalPage.tsx b/libs/components/editor-core/src/ref-page/ModalPage.tsx
new file mode 100644
index 0000000000..276d5984d6
--- /dev/null
+++ b/libs/components/editor-core/src/ref-page/ModalPage.tsx
@@ -0,0 +1,90 @@
+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')({
+ flex: 1,
+ width: '880px',
+ margin: '72px auto',
+ background: '#fff',
+ boxShadow: '0px 1px 10px rgba(152, 172, 189, 0.6)',
+ borderRadius: '10px',
+ padding: '72px 120px',
+ overflow: 'scroll',
+});
+
+const Modal = ({ open, children }: { open: boolean; children?: ReactNode }) => {
+ const theme = useTheme();
+ const { closeSubPage } = useRefPage();
+
+ return createPortal(
+
+
+ ,
+
+ document.body
+ );
+};
+
+const ModalPage = ({ blockId }: { blockId: string | null }) => {
+ const { editor } = useEditor();
+
+ return (
+
+ {blockId && }
+
+ );
+};
+
+const RefPageContext = createContext<
+ ReturnType> | undefined
+>(undefined);
+
+export const RefPageProvider = ({ children }: { children: ReactNode }) => {
+ const state = useState();
+ const [blockId, setBlockId] = state;
+
+ return (
+
+ {children}
+
+
+ );
+};
+
+export const useRefPage = () => {
+ const context = useContext(RefPageContext);
+ if (!context) {
+ throw new Error(
+ 'Wrap your app inside of a `SubPageProvider` to have access to the hook context!'
+ );
+ }
+ const [blockId, setBlockId] = context;
+ const openSubPage = (blockId: string) => {
+ setBlockId(blockId);
+ };
+ const closeSubPage = () => {
+ setBlockId(null);
+ };
+
+ return { blockId, open: !!blockId, openSubPage, closeSubPage };
+};
+
+// export const openSubPage = () => {};
diff --git a/libs/components/editor-core/src/ref-page/index.ts b/libs/components/editor-core/src/ref-page/index.ts
new file mode 100644
index 0000000000..4b06310a5c
--- /dev/null
+++ b/libs/components/editor-core/src/ref-page/index.ts
@@ -0,0 +1 @@
+export { useRefPage, RefPageProvider } from './ModalPage';
diff --git a/libs/components/editor-core/src/render-block/RenderBlock.tsx b/libs/components/editor-core/src/render-block/RenderBlock.tsx
index 46f068af2b..74f6c659cf 100644
--- a/libs/components/editor-core/src/render-block/RenderBlock.tsx
+++ b/libs/components/editor-core/src/render-block/RenderBlock.tsx
@@ -1,8 +1,8 @@
-import { styled, Theme } from '@toeverything/components/ui';
-import { FC, useContext, useLayoutEffect, useMemo, useRef } from 'react';
+import { styled } from '@toeverything/components/ui';
+import { FC, useLayoutEffect, useMemo, useRef } from 'react';
// import { RenderChildren } from './RenderChildren';
-import { RootContext } from '../contexts';
+import { useEditor } from '../Contexts';
import { useBlock } from '../hooks';
interface RenderBlockProps {
@@ -14,7 +14,7 @@ export const RenderBlock: FC = ({
blockId,
hasContainer = true,
}) => {
- const { editor, editorElement } = useContext(RootContext);
+ const { editor, editorElement } = useEditor();
const { block } = useBlock(blockId);
const blockRef = useRef(null);
diff --git a/libs/components/editor-plugins/src/menu/command-menu/Menu.tsx b/libs/components/editor-plugins/src/menu/command-menu/Menu.tsx
index 11e8d665da..78b6ef5ddd 100644
--- a/libs/components/editor-plugins/src/menu/command-menu/Menu.tsx
+++ b/libs/components/editor-plugins/src/menu/command-menu/Menu.tsx
@@ -242,25 +242,29 @@ export const CommandMenu = ({ editor, hooks, style }: CommandMenuProps) => {
onKeyUpCapture={handleKeyup}
ref={commandMenuContentRef}
>
-
-
-
-
-
+ {show ? (
+
+
+
+
+
+ ) : (
+ <>>
+ )}
);
};
diff --git a/libs/components/layout/src/settings-sidebar/Settings/use-settings.ts b/libs/components/layout/src/settings-sidebar/Settings/use-settings.ts
index 250511822d..1ce5bcb55a 100644
--- a/libs/components/layout/src/settings-sidebar/Settings/use-settings.ts
+++ b/libs/components/layout/src/settings-sidebar/Settings/use-settings.ts
@@ -9,7 +9,7 @@ import {
importWorkspace,
exportWorkspace,
useWorkspaceAndPageId,
- useReadingMode,
+ // useReadingMode,
clearWorkspace,
} from './util';
@@ -63,20 +63,20 @@ export const useSettings = (): SettingItem[] => {
const { workspaceId, pageId } = useWorkspaceAndPageId();
const navigate = useNavigate();
const settingFlags = useSettingFlags();
- const { toggleReadingMode, readingMode } = useReadingMode();
+ // const { toggleReadingMode, readingMode } = useReadingMode();
const settings: SettingItem[] = [
- {
- type: 'switch',
- name: 'Reading Mode',
- value: readingMode,
- onChange: () => {
- toggleReadingMode();
- },
- },
- {
- type: 'separator',
- },
+ // {
+ // type: 'switch',
+ // name: 'Reading Mode',
+ // value: readingMode,
+ // onChange: () => {
+ // toggleReadingMode();
+ // },
+ // },
+ // {
+ // type: 'separator',
+ // },
{
type: 'button',
name: 'Duplicate Page',
diff --git a/libs/components/layout/src/workspace-sidebar/activities/activities.tsx b/libs/components/layout/src/workspace-sidebar/activities/activities.tsx
index 4e5a9de413..a532d9bd02 100644
--- a/libs/components/layout/src/workspace-sidebar/activities/activities.tsx
+++ b/libs/components/layout/src/workspace-sidebar/activities/activities.tsx
@@ -64,30 +64,32 @@ export const Activities = () => {
const [recentPages, setRecentPages] = useState([]);
const userId = user?.id;
- /* temporarily remove:show recently viewed documents */
- const fetchRecentPages = useCallback(async () => {
+ /* show recently edit documents */
+ const getRecentEditPages = useCallback(async () => {
if (!userId || !currentSpaceId) {
return;
}
- const recent_pages = await services.api.userConfig.getRecentPages(
- currentSpaceId,
- userId
- );
- setRecentPages(recent_pages);
- }, [userId, currentSpaceId]);
+
+ const recentEditPages =
+ (await services.api.userConfig.getRecentEditedPages(
+ currentSpaceId
+ )) || [];
+
+ setRecentPages(recentEditPages);
+ }, [currentSpaceId, userId]);
useEffect(() => {
(async () => {
- await fetchRecentPages();
+ await getRecentEditPages();
})();
- }, [fetchRecentPages]);
+ }, [getRecentEditPages]);
useEffect(() => {
let unobserve: () => void;
const observe = async () => {
unobserve = await services.api.userConfig.observe(
{ workspace: currentSpaceId },
- fetchRecentPages
+ getRecentEditPages
);
};
observe();
@@ -95,12 +97,13 @@ export const Activities = () => {
return () => {
unobserve?.();
};
- }, [currentSpaceId, fetchRecentPages]);
+ }, [currentSpaceId, getRecentEditPages]);
return (
- {recentPages.map(({ id, title, lastOpenTime }) => {
+ {recentPages.map(item => {
+ const { id, title, updated } = item;
return (
{
/>
diff --git a/libs/components/ui/src/mui.ts b/libs/components/ui/src/mui.ts
index b0658ad526..47588ce5e6 100644
--- a/libs/components/ui/src/mui.ts
+++ b/libs/components/ui/src/mui.ts
@@ -13,6 +13,7 @@ import type {
} from '@mui/material';
import {
Avatar,
+ Backdrop,
Box,
Button,
Checkbox,
@@ -243,3 +244,7 @@ export const MuiFade = Fade;
* @deprecated It is not recommended to use Mui directly, because the design will not refer to Mui's interaction logic.
*/
export const MuiRadio = Radio;
+/**
+ * @deprecated It is not recommended to use Mui directly, because the design will not refer to Mui's interaction logic.
+ */
+export const MuiBackdrop = Backdrop;
diff --git a/libs/datasource/db-service/src/services/workspace/user-config.ts b/libs/datasource/db-service/src/services/workspace/user-config.ts
index 001eaca18b..887bb1ec2a 100644
--- a/libs/datasource/db-service/src/services/workspace/user-config.ts
+++ b/libs/datasource/db-service/src/services/workspace/user-config.ts
@@ -3,6 +3,7 @@ import { ServiceBaseClass } from '../base';
import { ObserveCallback, ReturnUnobserve } from '../database';
import { PageTree } from './page-tree';
import { PageConfigItem } from './types';
+import type { QueryIndexMetadata } from '@toeverything/datasource/jwt';
/** Operate the user configuration at the workspace level */
export class UserConfig extends ServiceBaseClass {
@@ -122,4 +123,20 @@ export class UserConfig extends ServiceBaseClass {
const workspaceDbBlock = await this.getWorkspaceDbBlock(workspace);
workspaceDbBlock.setDecoration(WORKSPACE_CONFIG, workspaceName);
}
+
+ async getRecentEditedPages(workspace: string) {
+ const db = await this.database.getDatabase(workspace);
+ const recentEditedPages =
+ (await db.queryBlocks({
+ $sort: 'lastUpdated',
+ $desc: false /* sort rule: true(default)(ASC), or false(DESC) */,
+ $limit: 4,
+ flavor: 'page',
+ } as QueryIndexMetadata)) || [];
+
+ return recentEditedPages.map(item => {
+ item['title'] = item.content || 'Untitled';
+ return item;
+ });
+ }
}
diff --git a/libs/datasource/feature-flags/README.md b/libs/datasource/feature-flags/README.md
index f5c59f4e13..7a04209c5d 100644
--- a/libs/datasource/feature-flags/README.md
+++ b/libs/datasource/feature-flags/README.md
@@ -2,7 +2,15 @@
## Usage
-- set provider
+- Set token at environment variable
+ - The key can be obtained from the [Feature Flag Portal](https://portal.featureflag.co/account-settings/projects)
+
+```shell
+# .env.local
+AFFINE_FEATURE_FLAG_TOKEN=XXXXXXX
+```
+
+- Set provider
```tsx
import { FeatureFlagsProvider } from '@toeverything/datasource/feature-flags';
@@ -42,7 +50,8 @@ const App = () => {
**When entering development mode feature flag will NOT be updated in real time**
-- `activateFfcDevMode()` play with feature flags locally
+- `activateFfcDevMode(PASSWORD)` play with feature flags locally
+ - The `devModePassword` can be obtained from `src/config.ts`
- `quitFfcDevMode()` quit dev mode
## Running unit tests
diff --git a/libs/datasource/feature-flags/src/config.ts b/libs/datasource/feature-flags/src/config.ts
index 7f3360d6db..5295dae995 100644
--- a/libs/datasource/feature-flags/src/config.ts
+++ b/libs/datasource/feature-flags/src/config.ts
@@ -8,4 +8,18 @@ export const config: IOption = {
// id: 'the user's unique identifier'
// }
devModePassword: '-',
+ enableDataSync: !!process.env['AFFINE_FEATURE_FLAG_TOKEN'],
+ // bootstrap: [
+ // {
+ // // the feature flag key
+ // id: 'flag',
+ // // the feature flag value
+ // variation: false,
+ // // the variation data type, string is used if not provided
+ // variationType: VariationDataType.boolean,
+ // variationOptions: [],
+ // timestamp: 0,
+ // sendToExperiment: false,
+ // },
+ // ],
};
diff --git a/libs/datasource/jwt/src/adapter/yjs/binary.ts b/libs/datasource/jwt/src/adapter/yjs/binary.ts
index 5c677a4f51..468710ac4a 100644
--- a/libs/datasource/jwt/src/adapter/yjs/binary.ts
+++ b/libs/datasource/jwt/src/adapter/yjs/binary.ts
@@ -3,8 +3,8 @@ import { Array as YArray, Map as YMap } from 'yjs';
import { RemoteKvService } from '@toeverything/datasource/remote-kv';
export class YjsRemoteBinaries {
- readonly _binaries: YMap>; // binary instance
- readonly _remoteStorage?: RemoteKvService;
+ private readonly _binaries: YMap>; // binary instance
+ private readonly _remoteStorage?: RemoteKvService;
constructor(binaries: YMap>, remote_token?: string) {
this._binaries = binaries;
diff --git a/libs/datasource/jwt/src/adapter/yjs/block.ts b/libs/datasource/jwt/src/adapter/yjs/block.ts
index ad60aa31e0..1f49ad0ed1 100644
--- a/libs/datasource/jwt/src/adapter/yjs/block.ts
+++ b/libs/datasource/jwt/src/adapter/yjs/block.ts
@@ -32,19 +32,21 @@ type YjsBlockInstanceProps = {
};
export class YjsBlockInstance implements BlockInstance {
- readonly _id: string;
- readonly _block: YMap;
- readonly _binary?: YArray;
- readonly _children: YArray;
- readonly _setBlock: (
+ private readonly _id: string;
+ private readonly _block: YMap;
+ private readonly _binary?: YArray;
+ private readonly _children: YArray;
+ private readonly _setBlock: (
id: string,
block: BlockItem
) => Promise;
- readonly _getUpdated: (id: string) => number | undefined;
- readonly _getCreator: (id: string) => string | undefined;
- readonly _getBlockInstance: (id: string) => YjsBlockInstance | undefined;
- readonly _childrenListeners: Map;
- readonly _contentListeners: Map;
+ private readonly _getUpdated: (id: string) => number | undefined;
+ private readonly _getCreator: (id: string) => string | undefined;
+ private readonly _getBlockInstance: (
+ id: string
+ ) => YjsBlockInstance | undefined;
+ private readonly _childrenListeners: Map;
+ private readonly _contentListeners: Map;
// eslint-disable-next-line @typescript-eslint/naming-convention
_childrenMap: Map;
diff --git a/libs/datasource/jwt/src/adapter/yjs/gatekeeper.ts b/libs/datasource/jwt/src/adapter/yjs/gatekeeper.ts
index 1ee3e93ca3..7e02c5a09e 100644
--- a/libs/datasource/jwt/src/adapter/yjs/gatekeeper.ts
+++ b/libs/datasource/jwt/src/adapter/yjs/gatekeeper.ts
@@ -1,10 +1,9 @@
import { Map as YMap } from 'yjs';
export class GateKeeper {
- // eslint-disable-next-line @typescript-eslint/naming-convention
- _userId: string;
- _creators: YMap;
- _common: YMap;
+ private readonly _userId: string;
+ private readonly _creators: YMap;
+ private readonly _common: YMap;
constructor(userId: string, creators: YMap, common: YMap) {
this._userId = userId;
diff --git a/libs/datasource/jwt/src/adapter/yjs/history.ts b/libs/datasource/jwt/src/adapter/yjs/history.ts
index 34884a1150..6739cf9a50 100644
--- a/libs/datasource/jwt/src/adapter/yjs/history.ts
+++ b/libs/datasource/jwt/src/adapter/yjs/history.ts
@@ -5,10 +5,10 @@ import { HistoryCallback, HistoryManager } from '../../adapter';
type StackItem = UndoManager['undoStack'][0];
export class YjsHistoryManager implements HistoryManager {
- readonly _blocks: YMap;
- readonly _historyManager: UndoManager;
- readonly _pushListeners: Map>;
- readonly _popListeners: Map>;
+ private readonly _blocks: YMap;
+ private readonly _historyManager: UndoManager;
+ private readonly _pushListeners: Map>;
+ private readonly _popListeners: Map>;
constructor(scope: YMap, tracker?: any[]) {
this._blocks = scope;
diff --git a/libs/datasource/jwt/src/adapter/yjs/index.ts b/libs/datasource/jwt/src/adapter/yjs/index.ts
index 1a0a637859..eb886afae5 100644
--- a/libs/datasource/jwt/src/adapter/yjs/index.ts
+++ b/libs/datasource/jwt/src/adapter/yjs/index.ts
@@ -178,22 +178,22 @@ export type YjsInitOptions = {
};
export class YjsAdapter implements AsyncDatabaseAdapter {
- readonly _provider: YjsProviders;
- readonly _doc: Doc; // doc instance
- readonly _awareness: Awareness; // lightweight state synchronization
- readonly _gatekeeper: GateKeeper; // Simple access control
- readonly _history: YjsHistoryManager;
+ private readonly _provider: YjsProviders;
+ private readonly _doc: Doc; // doc instance
+ private readonly _awareness: Awareness; // lightweight state synchronization
+ private readonly _gatekeeper: GateKeeper; // Simple access control
+ private readonly _history: YjsHistoryManager;
// Block Collection
// key is a randomly generated global id
- readonly _blocks: YMap>;
- readonly _blockUpdated: YMap;
+ private readonly _blocks: YMap>;
+ private readonly _blockUpdated: YMap;
// Maximum cache Block 1024, ttl 10 minutes
- readonly _blockCaches: LRUCache;
+ private readonly _blockCaches: LRUCache;
- readonly _binaries: YjsRemoteBinaries;
+ private readonly _binaries: YjsRemoteBinaries;
- readonly _listener: Map>;
+ private readonly _listener: Map>;
static async init(
workspace: string,
diff --git a/libs/datasource/jwt/src/adapter/yjs/operation.ts b/libs/datasource/jwt/src/adapter/yjs/operation.ts
index e4b2da50dd..a8dfdaffa4 100644
--- a/libs/datasource/jwt/src/adapter/yjs/operation.ts
+++ b/libs/datasource/jwt/src/adapter/yjs/operation.ts
@@ -52,7 +52,7 @@ function auto_set(root: ContentOperation, key: string, data: BaseTypes): void {
}
export class YjsContentOperation implements ContentOperation {
- readonly _content: YAbstractType;
+ private readonly _content: YAbstractType;
constructor(content: YAbstractType) {
this._content = content;
@@ -197,7 +197,7 @@ export class YjsContentOperation implements ContentOperation {
}
class YjsTextOperation extends YjsContentOperation implements TextOperation {
- readonly _textContent: YText;
+ private readonly _textContent: YText;
constructor(content: YText) {
super(content);
@@ -241,8 +241,8 @@ class YjsArrayOperation
extends YjsContentOperation
implements ArrayOperation
{
- readonly _arrayContent: YArray;
- readonly _listeners: Map;
+ private readonly _arrayContent: YArray;
+ private readonly _listeners: Map;
constructor(content: YArray) {
super(content);
@@ -344,8 +344,8 @@ class YjsMapOperation
extends YjsContentOperation
implements MapOperation
{
- readonly _mapContent: YMap;
- readonly _listeners: Map;
+ private readonly _mapContent: YMap;
+ private readonly _listeners: Map;
constructor(content: YMap) {
super(content);
diff --git a/libs/datasource/jwt/src/block/abstract.ts b/libs/datasource/jwt/src/block/abstract.ts
index 9d675ee803..29ee655dc2 100644
--- a/libs/datasource/jwt/src/block/abstract.ts
+++ b/libs/datasource/jwt/src/block/abstract.ts
@@ -26,11 +26,11 @@ export class AbstractBlock<
B extends BlockInstance,
C extends ContentOperation
> {
- readonly _id: string;
+ private readonly _id: string;
readonly #block: BlockInstance;
- readonly _history: HistoryManager;
- readonly _root?: AbstractBlock;
- readonly _parentListener: Map;
+ private readonly _history: HistoryManager;
+ private readonly _root?: AbstractBlock;
+ private readonly _parentListener: Map;
_parent?: AbstractBlock;
diff --git a/libs/datasource/jwt/src/block/base.ts b/libs/datasource/jwt/src/block/base.ts
index cf79c08ea7..72183187b1 100644
--- a/libs/datasource/jwt/src/block/base.ts
+++ b/libs/datasource/jwt/src/block/base.ts
@@ -51,19 +51,19 @@ export class BaseBlock<
B extends BlockInstance,
C extends ContentOperation
> extends AbstractBlock {
- readonly _exporters?: Exporters;
- readonly _contentExportersGetter: () => Map<
+ private readonly _exporters?: Exporters;
+ private readonly _contentExportersGetter: () => Map<
string,
ReadableContentExporter
>;
- readonly _metadataExportersGetter: () => Map<
+ private readonly _metadataExportersGetter: () => Map<
string,
ReadableContentExporter<
Array<[string, number | string | string[]]>,
any
>
>;
- readonly _tagExportersGetter: () => Map<
+ private readonly _tagExportersGetter: () => Map<
string,
ReadableContentExporter
>;
diff --git a/libs/datasource/jwt/src/block/indexer.ts b/libs/datasource/jwt/src/block/indexer.ts
index 39dd52c4e0..d9ecde1658 100644
--- a/libs/datasource/jwt/src/block/indexer.ts
+++ b/libs/datasource/jwt/src/block/indexer.ts
@@ -107,18 +107,18 @@ export class BlockIndexer<
B extends BlockInstance,
C extends ContentOperation
> {
- readonly _adapter: A;
- readonly _idb: BlockIdbInstance;
+ private readonly _adapter: A;
+ private readonly _idb: BlockIdbInstance;
- readonly _blockIndexer: DocumentIndexer;
- readonly _blockMetadata: LRUCache;
- readonly _eventBus: BlockEventBus;
+ private readonly _blockIndexer: DocumentIndexer;
+ private readonly _blockMetadata: LRUCache;
+ private readonly _eventBus: BlockEventBus;
- readonly _blockBuilder: (
+ private readonly _blockBuilder: (
block: BlockInstance
) => Promise>;
- readonly _delayIndex: { documents: Map> };
+ private readonly _delayIndex: { documents: Map> };
constructor(
adapter: A,
diff --git a/libs/datasource/jwt/src/index.ts b/libs/datasource/jwt/src/index.ts
index 343f1f79ad..6ced321c2c 100644
--- a/libs/datasource/jwt/src/index.ts
+++ b/libs/datasource/jwt/src/index.ts
@@ -69,14 +69,14 @@ export class BlockClient<
B extends BlockInstance,
C extends ContentOperation
> {
- readonly _adapter: A;
- readonly _workspace: string;
+ private readonly _adapter: A;
+ private readonly _workspace: string;
// Maximum cache Block 8192, ttl 30 minutes
- readonly _blockCaches: LRUCache>;
- readonly _blockIndexer: BlockIndexer;
+ private readonly _blockCaches: LRUCache>;
+ private readonly _blockIndexer: BlockIndexer;
- readonly _exporters: {
+ private readonly _exporters: {
readonly content: BlockExporters;
readonly metadata: BlockExporters<
Array<[string, number | string | string[]]>
@@ -84,12 +84,12 @@ export class BlockClient<
readonly tag: BlockExporters;
};
- readonly _eventBus: BlockEventBus;
+ private readonly _eventBus: BlockEventBus;
- readonly _parentMapping: Map;
- readonly _pageMapping: Map;
+ private readonly _parentMapping: Map;
+ private readonly _pageMapping: Map;
- readonly _root: { node?: BaseBlock };
+ private readonly _root: { node?: BaseBlock };
private constructor(
adapter: A,
diff --git a/libs/datasource/jwt/src/utils/event-bus.ts b/libs/datasource/jwt/src/utils/event-bus.ts
index 9d128049e7..50f5363390 100644
--- a/libs/datasource/jwt/src/utils/event-bus.ts
+++ b/libs/datasource/jwt/src/utils/event-bus.ts
@@ -7,9 +7,9 @@ declare const JWT_DEV: boolean;
const logger = getLogger('BlockDB:event_bus');
export class BlockEventBus {
- readonly _eventBus: EventTarget;
- readonly _eventCallbackCache: Map;
- readonly _scopedCache: Map>;
+ private readonly _eventBus: EventTarget;
+ private readonly _eventCallbackCache: Map;
+ private readonly _scopedCache: Map>;
constructor(event_bus?: EventTarget) {
this._eventBus = event_bus || new EventTarget();
@@ -68,7 +68,7 @@ type ListenerOptions = {
};
class BlockScopedEventBus extends BlockEventBus {
- readonly _topic: string;
+ private readonly _topic: string;
constructor(topic: string, event_bus?: EventTarget) {
super(event_bus);