diff --git a/.all-contributorsrc b/.all-contributorsrc
index 0340f41c92..3286d1be28 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -1,5 +1,5 @@
{
- "projectName": "Ligo-Virgo",
+ "projectName": "toeverything",
"projectOwner": "toeverything",
"repoType": "github",
"repoHost": "https://github.com",
@@ -25,7 +25,7 @@
"login": "tzhangchi",
"name": "Chi Zhang",
"avatar_url": "https://avatars.githubusercontent.com/u/5910926?v=4",
- "profile": "https://zhangchi.blog.csdn.net/",
+ "profile": "http://zhangchi.page/",
"contributions": [
"code",
"doc"
@@ -33,7 +33,7 @@
},
{
"login": "alt1o",
- "name": "alt1o",
+ "name": "wang xinglong",
"avatar_url": "https://avatars.githubusercontent.com/u/21084335?v=4",
"profile": "https://github.com/alt1o",
"contributions": [
@@ -43,7 +43,7 @@
},
{
"login": "DiamondThree",
- "name": "Diamond",
+ "name": "DiamondThree",
"avatar_url": "https://avatars.githubusercontent.com/u/24630517?v=4",
"profile": "https://github.com/DiamondThree",
"contributions": [
@@ -63,7 +63,7 @@
},
{
"login": "zuoxiaodong0815",
- "name": "zuoxiaodong0815",
+ "name": "xiaodong zuo",
"avatar_url": "https://avatars.githubusercontent.com/u/53252747?v=4",
"profile": "https://github.com/zuoxiaodong0815",
"contributions": [
@@ -73,7 +73,7 @@
},
{
"login": "SaikaSakura",
- "name": "SaikaSakura",
+ "name": "MingLIang Wang",
"avatar_url": "https://avatars.githubusercontent.com/u/11530942?v=4",
"profile": "https://github.com/SaikaSakura",
"contributions": [
@@ -92,10 +92,10 @@
]
},
{
- "login": "tuluffy",
- "name": "tuluffy",
- "avatar_url": "https://avatars.githubusercontent.com/u/26808339?v=4",
- "profile": "https://tuluffy.github.io/angular.github.io/",
+ "login": "mitsuhatu",
+ "name": "mitsuhatu",
+ "avatar_url": "https://avatars.githubusercontent.com/u/110213079?v=4",
+ "profile": "https://github.com/mitsuhatu",
"contributions": [
"code",
"doc"
diff --git a/README.md b/README.md
index 0fbcf5bf80..042802d1de 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ Planning, Sorting and Creating all Together. Open-source, Privacy-First, and Fre
@@ -38,7 +38,7 @@ See https://github.com/all-contributors/all-contributors/issues/361#issuecomment
Telegram
-
+
# Stay Up-to-Date
@@ -52,7 +52,8 @@ See https://github.com/all-contributors/all-contributors/issues/361#issuecomment
- [Plan your task](#plan-your-task)
- [Sort your knowledge](#sort-your-knowledge)
- [Create your story](#create-your-story)
-- [Getting Started with development](#getting-started-with-development)
+- [Documentation](#documentation)
+ - [Getting Started with development](#getting-started-with-development)
- [Roadmap](#roadmap)
- [Releases](#releases)
- [Feature requests](#feature-requests)
@@ -60,6 +61,7 @@ See https://github.com/all-contributors/all-contributors/issues/361#issuecomment
- [The Philosophy of AFFiNE](#the-philosophy-of-affine)
- [Community](#community)
- [Contributors](#contributors)
+- [Acknowledgments](#acknowledgments)
- [License](#license)
## Shape your page
@@ -80,9 +82,13 @@ We want your data always to be yours, and we don't want to make any sacrifice to
Collaboration isn't only necessary for teams -- you may take and insert pics on your phone, then edit them on your desktop, and share them with your collaborators.
Affine is fully built with web technologies so that consistency and accessibility are always guaranteed on Mac, Windows and Linux. The local file system support will be available when version 0.0.1beta is released.
-# Getting Started with development
+# Documentation
-Please view the [documentation](https://affine.gitbook.io/affine/) in Contribute-to-AFFiNE/Software-Contributions/Environment-setup.
+Please view the [documentation](https://affine.gitbook.io/affine/)
+
+## Getting Started with development
+
+Please view the path Contribute-to-AFFiNE/Software-Contributions/Quick-Start in documentation.
# Roadmap
@@ -134,9 +140,17 @@ We would like to give special thanks to the innovators and pioneers who greatly
We would also like to give thanks to open-source projects that make affine possible:
-- Yjs & Yrs
-- React
-- Rust
+- [Yjs](https://github.com/yjs/yjs) & [Yrs](https://github.com/y-crdt/y-crdt) -- Fundamental support of CRDTs for our implements on state management and data sync.
+- [React](https://github.com/facebook/react) -- View layer support and web GUI framework.
+- [Rust](https://github.com/rust-lang/rust) -- High performance language that extends the ability and availability of our real-time backend, JWST.
+- [Fossil](https://www2.fossil-scm.org/home/doc/trunk/www/index.wiki) -- Source code management tool made with CRDTs which inspired our design on block data structure.
+- [slatejs](https://github.com/ianstormtaylor/slate) -- Customizable rich-text editor.
+- [Jotai](https://github.com/pmndrs/jotai) -- Minimal state management tool for frontend.
+- [Tldraw](https://github.com/tldraw/tldraw) -- Excellent drawing board.
+- [MUI](https://github.com/mui/material-ui) -- Our most used graphic UI component library.
+- Other [dependancies](https://github.com/toeverything/AFFiNE/network/dependencies)
+
+Thanks a lot to the community for providing such powerful and simple libraries, so that we can focus more on the implementation of the product logic, and we hope that in the future our projects will also provide a more easy-to-use knowledge base for everyone.
# Community
@@ -152,16 +166,16 @@ For help, discussion about best practices, or any other conversation that would
DarkSky 💻 📖
- Chi Zhang 💻 📖
- alt1o 💻 📖
- Diamond 💻 📖
+ Chi Zhang 💻 📖
+ wang xinglong 💻 📖
+ DiamondThree 💻 📖
Whitewater 💻 📖
- zuoxiaodong0815 💻 📖
- SaikaSakura 💻 📖
+ xiaodong zuo 💻 📖
+ MingLIang Wang 💻 📖
Qi 💻 📖
- tuluffy 💻 📖
+ mitsuhatu 💻 📖
Austaras 💻 📖
Jin Yao 💻 📖
diff --git a/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx b/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx
index b2ebc5f7dc..556ca606a7 100644
--- a/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx
+++ b/apps/ligo-virgo/src/pages/workspace/docs/Page.tsx
@@ -31,7 +31,7 @@ import { WorkspaceName } from './workspace-name';
import { CollapsiblePageTree } from './collapsible-page-tree';
import { useFlag } from '@toeverything/datasource/feature-flags';
import { type BlockEditor } from '@toeverything/components/editor-core';
-
+import { Tabs } from './components/tabs';
type PageProps = {
workspace: string;
};
@@ -80,7 +80,9 @@ export function Page(props: PageProps) {
onMouseLeave={() => setSpaceSidebarVisible(false)}
>
-
+
+
+
{dailyNotesFlag && (
@@ -219,4 +221,5 @@ const WorkspaceSidebar = styled('div')(({ hidden }) => ({
const WorkspaceSidebarContent = styled('div')({
flex: 'auto',
overflow: 'hidden auto',
+ marginTop: '18px',
});
diff --git a/apps/ligo-virgo/src/pages/workspace/docs/components/logo/Logo.tsx b/apps/ligo-virgo/src/pages/workspace/docs/components/logo/Logo.tsx
new file mode 100644
index 0000000000..8b33a276c4
--- /dev/null
+++ b/apps/ligo-virgo/src/pages/workspace/docs/components/logo/Logo.tsx
@@ -0,0 +1,19 @@
+export const Logo = ({ color, style, ...props }) => {
+ return (
+
+
+
+
+ );
+};
diff --git a/apps/ligo-virgo/src/pages/workspace/docs/components/logo/index.ts b/apps/ligo-virgo/src/pages/workspace/docs/components/logo/index.ts
new file mode 100644
index 0000000000..33af505338
--- /dev/null
+++ b/apps/ligo-virgo/src/pages/workspace/docs/components/logo/index.ts
@@ -0,0 +1 @@
+export { Logo } from './Logo';
diff --git a/apps/ligo-virgo/src/pages/workspace/docs/components/tabs/Tabs.tsx b/apps/ligo-virgo/src/pages/workspace/docs/components/tabs/Tabs.tsx
new file mode 100644
index 0000000000..3722c5e162
--- /dev/null
+++ b/apps/ligo-virgo/src/pages/workspace/docs/components/tabs/Tabs.tsx
@@ -0,0 +1,61 @@
+import { useState } from 'react';
+import { MuiDivider as Divider, styled } from '@toeverything/components/ui';
+import type { ValueOf } from '@toeverything/utils';
+
+const StyledTabs = styled('div')({
+ width: '100%',
+ height: '12px',
+ marginTop: '12px',
+ display: 'flex',
+ alignItems: 'center',
+ cursor: 'pointer',
+});
+
+const StyledDivider = styled(Divider)<{ isActive?: boolean }>(
+ ({ isActive }) => {
+ return {
+ flex: 1,
+ backgroundColor: isActive ? '#3E6FDB' : '#ECF1FB',
+ borderWidth: '2px',
+ };
+ }
+);
+
+const TAB_TITLE = {
+ PAGES: 'pages',
+ GALLERY: 'gallery',
+ TOC: 'toc',
+} as const;
+
+const TabMap = new Map
([
+ ['PAGES', 'pages'],
+ ['GALLERY', 'gallery'],
+ ['TOC', 'toc'],
+]);
+
+type TabKey = keyof typeof TAB_TITLE;
+type TabValue = ValueOf;
+
+const Tabs = () => {
+ const [activeTab, setActiveTab] = useState(TAB_TITLE.PAGES);
+
+ const onClick = (v: TabValue) => {
+ setActiveTab(v);
+ };
+
+ return (
+
+ {[...TabMap.entries()].map(([k, v]) => {
+ return (
+ onClick(v)}
+ />
+ );
+ })}
+
+ );
+};
+
+export { Tabs };
diff --git a/apps/ligo-virgo/src/pages/workspace/docs/components/tabs/index.ts b/apps/ligo-virgo/src/pages/workspace/docs/components/tabs/index.ts
new file mode 100644
index 0000000000..941e6baba5
--- /dev/null
+++ b/apps/ligo-virgo/src/pages/workspace/docs/components/tabs/index.ts
@@ -0,0 +1 @@
+export { Tabs } from './Tabs';
diff --git a/apps/ligo-virgo/src/pages/workspace/docs/workspace-name.tsx b/apps/ligo-virgo/src/pages/workspace/docs/workspace-name.tsx
index 24d69b659a..cf6f3a0313 100644
--- a/apps/ligo-virgo/src/pages/workspace/docs/workspace-name.tsx
+++ b/apps/ligo-virgo/src/pages/workspace/docs/workspace-name.tsx
@@ -1,27 +1,28 @@
import {
- MuiButton as Button,
- Switch,
styled,
MuiOutlinedInput as OutlinedInput,
} from '@toeverything/components/ui';
-import { LogoIcon } from '@toeverything/components/icons';
+import { PinIcon } from '@toeverything/components/icons';
import {
useUserAndSpaces,
useShowSpaceSidebar,
} from '@toeverything/datasource/state';
-import { useCallback, useEffect, useRef, useState } from 'react';
+import React, { useCallback, useEffect, useState } from 'react';
import { services } from '@toeverything/datasource/db-service';
+import { Logo } from './components/logo/Logo';
const WorkspaceContainer = styled('div')({
display: 'flex',
- alignItems: 'center',
- minHeight: 60,
- padding: '12px 0px',
+ flexDirection: 'column',
+ paddingBottom: '12px',
color: '#566B7D',
});
const LeftContainer = styled('div')({
flex: 'auto',
display: 'flex',
+ height: '52px',
+ alignItems: 'center',
+ margin: '0 12px',
});
const LogoContainer = styled('div')({
@@ -32,20 +33,36 @@ const LogoContainer = styled('div')({
minWidth: 24,
});
-const StyledLogoIcon = styled(LogoIcon)(({ theme }) => {
- return {
- color: theme.affine.palette.primary,
- width: '16px !important',
- height: '16px !important',
- };
+const StyledPin = styled('div')({
+ display: 'flex',
+ justifyContent: 'end',
+ alignItems: 'center',
+});
+
+const StyledWorkspace = styled('div')({
+ height: '100%',
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'space-between',
+ marginLeft: '12px',
+ paddingLeft: '12px',
+});
+
+const StyledWorkspaceDesc = styled('div')({
+ fontSize: '12px',
+ color: '#98ACBD',
+ height: '18px',
+
+ display: 'flex',
+ alignItems: 'center',
});
const WorkspaceNameContainer = styled('div')({
display: 'flex',
alignItems: 'center',
flex: 'auto',
- width: '100px',
- marginRight: '10px',
+ width: '165px',
+ height: '34px',
input: {
padding: '5px 10px',
},
@@ -58,21 +75,15 @@ const WorkspaceNameContainer = styled('div')({
});
const WorkspaceReNameContainer = styled('div')({
- marginRight: '10px',
+ height: '34px',
+ display: 'flex',
+ alignItems: 'center',
+
input: {
padding: '5px 10px',
},
});
-const ToggleDisplayContainer = styled('div')({
- display: 'flex',
- alignItems: 'center',
- fontSize: 12,
- color: '#3E6FDB',
- padding: 6,
- minWidth: 64,
-});
-
export const WorkspaceName = () => {
const { currentSpaceId } = useUserAndSpaces();
const { fixedDisplay, toggleSpaceSidebar } = useShowSpaceSidebar();
@@ -139,35 +150,46 @@ export const WorkspaceName = () => {
return (
+
+
+
-
+
- {inRename ? (
-
- setInRename(false)}
- />
-
- ) : (
-
- setInRename(true)}>
- {workspaceName || workspaceId}
-
-
- )}
+
+ {inRename ? (
+
+ setInRename(false)}
+ />
+
+ ) : (
+
+ setInRename(true)}>
+ {workspaceName || workspaceId}
+
+
+ )}
+
+
+ To shape, Not to Adapt.
+
+
-
-
-
);
};
diff --git a/apps/venus/src/app/index.tsx b/apps/venus/src/app/index.tsx
index 8e17108f13..011c7b9245 100644
--- a/apps/venus/src/app/index.tsx
+++ b/apps/venus/src/app/index.tsx
@@ -20,12 +20,12 @@ const DiscordIcon = (props: any) => {
width="71"
height="55"
viewBox="0 0 71 55"
- fill="none"
+ fill="currentcolor"
>
@@ -515,10 +515,12 @@ export function App() {
justifyContent: 'left',
textAlign: 'left',
transition: 'all .5s',
- // boxShadow: '2px 2px 40px #08f2',
- // ':hover': {
- // boxShadow: '2px 2px 40px #08f4',
- // },
+ transform: 'scale(0.98)',
+ boxShadow: '2px 2px 40px #0002',
+ ':hover': {
+ transform: 'scale(1)',
+ boxShadow: '2px 2px 40px #0004',
+ },
}}
>
-
+ window.open(
+ 'https://github.com/toeverything/AFFiNE/'
+ )
+ }
>
GitHub
-
+
-
+ window.open('https://www.reddit.com/r/Affine/')
+ }
>
Reddit
-
+
-
+ window.open('https://t.me/affineworkos')
+ }
>
Telegram
-
+
-
+ window.open('https://discord.gg/yz6tGVsf5p')
+ }
>
@@ -883,12 +925,16 @@ export function App() {
}}
>
Discord
-
+
diff --git a/apps/venus/src/assets/collaboration.png b/apps/venus/src/assets/collaboration.png
index 5d56d61581..bad2daedde 100644
Binary files a/apps/venus/src/assets/collaboration.png and b/apps/venus/src/assets/collaboration.png differ
diff --git a/apps/venus/src/assets/discord.svg b/apps/venus/src/assets/discord.svg
deleted file mode 100644
index 9da6ee0330..0000000000
--- a/apps/venus/src/assets/discord.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/venus/src/assets/page.png b/apps/venus/src/assets/page.png
index 2236ce046d..d5f393262b 100644
Binary files a/apps/venus/src/assets/page.png and b/apps/venus/src/assets/page.png differ
diff --git a/apps/venus/src/assets/shape.png b/apps/venus/src/assets/shape.png
index 178d7ea6a1..0dc76b50fe 100644
Binary files a/apps/venus/src/assets/shape.png and b/apps/venus/src/assets/shape.png differ
diff --git a/apps/venus/src/assets/task.png b/apps/venus/src/assets/task.png
index 8ef6c95057..279d968cb5 100644
Binary files a/apps/venus/src/assets/task.png and b/apps/venus/src/assets/task.png differ
diff --git a/libs/components/editor-blocks/src/blocks/grid/GirdHandle.tsx b/libs/components/editor-blocks/src/blocks/grid/GirdHandle.tsx
index e6464860c5..687cc28735 100644
--- a/libs/components/editor-blocks/src/blocks/grid/GirdHandle.tsx
+++ b/libs/components/editor-blocks/src/blocks/grid/GirdHandle.tsx
@@ -12,6 +12,8 @@ type GridHandleProps = {
blockId: string;
enabledAddItem: boolean;
draggable: boolean;
+ alertHandleId: string;
+ onMouseEnter?: React.MouseEventHandler;
};
export const GridHandle: FC = function ({
@@ -21,6 +23,8 @@ export const GridHandle: FC = function ({
onDrag,
onMouseDown,
draggable,
+ alertHandleId,
+ onMouseEnter,
}) {
const [isMouseDown, setIsMouseDown] = useState(false);
const handleMouseDown: React.MouseEventHandler = e => {
@@ -44,16 +48,17 @@ export const GridHandle: FC = function ({
editor.selectionManager.setActivatedNodeId(textBlock.id);
}
};
+
+ const handleMouseEnter: React.MouseEventHandler = e => {
+ onMouseEnter && onMouseEnter(e);
+ };
+
return (
{enabledAddItem ? (
= function ({
);
};
-const GridHandleContainer = styled('div')(({ theme }) => ({
+const GridHandleContainer = styled('div')<{
+ isMouseDown: boolean;
+ isAlert: boolean;
+}>(({ theme, isMouseDown, isAlert }) => ({
position: 'relative',
width: '10px',
flexGrow: '0',
@@ -78,11 +86,15 @@ const GridHandleContainer = styled('div')(({ theme }) => ({
borderRadius: '1px',
backgroundClip: 'content-box',
' &:hover': {
- backgroundColor: theme.affine.palette.primary,
+ backgroundColor: isAlert ? 'red' : theme.affine.palette.primary,
[`.${GRID_ADD_HANDLE_NAME}`]: {
display: 'block',
},
},
+ ...(isMouseDown &&
+ (isAlert
+ ? { backgroundColor: 'red' }
+ : { backgroundColor: theme.affine.palette.primary })),
}));
const AddGridHandle = styled('div')(({ theme }) => ({
diff --git a/libs/components/editor-blocks/src/blocks/grid/Grid.tsx b/libs/components/editor-blocks/src/blocks/grid/Grid.tsx
index 77a83ff599..bc27ec4ac6 100644
--- a/libs/components/editor-blocks/src/blocks/grid/Grid.tsx
+++ b/libs/components/editor-blocks/src/blocks/grid/Grid.tsx
@@ -31,6 +31,7 @@ export const Grid: FC = function (props) {
const gridItemCountRef = useRef();
const originalLeftWidth = useRef(GRID_ITEM_MIN_WIDTH);
const originalRightWidth = useRef(GRID_ITEM_MIN_WIDTH);
+ const [alertHandleId, setAlertHandleId] = useState(null);
const getLeftRightGridItemDomByIndex = (index: number) => {
const gridItems = Array.from(gridContainerRef.current?.children).filter(
@@ -117,7 +118,7 @@ export const Grid: FC = function (props) {
itemDom.style.width = width;
};
- const handleDragGrid = (e: MouseEvent, index: number) => {
+ const handleDragGrid = async (e: MouseEvent, index: number) => {
setIsOnDrag(true);
window.getSelection().removeAllRanges();
if (!isSetMouseUp.current) {
@@ -165,39 +166,47 @@ export const Grid: FC = function (props) {
setItemWidth(leftGrid, newLeft);
setItemWidth(rightGrid, newRight);
updateDbWidth(leftBlockId, newLeft, rightBlockId, newRight);
+ [leftBlockId, rightBlockId].forEach(async blockId => {
+ if (await checkGridItemHasOverflow(blockId)) {
+ setAlertHandleId(leftBlockId);
+ } else {
+ setAlertHandleId(null);
+ }
+ });
}
}
};
- const children = (
- <>
- {block.childrenIds.map((id, i) => {
- return (
-
-
- handleDragGrid(event, i)}
- editor={editor}
- onMouseDown={event => handleMouseDown(event, i)}
- blockId={id}
- enabledAddItem={
- block.childrenIds.length < MAX_ITEM_COUNT
- }
- draggable={i !== block.childrenIds.length - 1}
- />
-
- );
- })}
- >
- );
+ const checkGridItemHasOverflow = async (blockId: string) => {
+ let isOverflow = false;
+ const block = await editor.getBlockById(blockId);
+ if (block) {
+ const blockDom = block.dom;
+ if (blockDom) {
+ block.dom.style.overflow = 'scroll';
+ if (block.dom.clientWidth !== block.dom.scrollWidth) {
+ isOverflow = true;
+ }
+ blockDom.style.overflow = 'visible';
+ }
+ }
+ return isOverflow;
+ };
+
+ const handleHandleMouseEnter = (
+ e: React.MouseEvent,
+ index: number
+ ) => {
+ const leftBlockId = block.childrenIds[index];
+ const rightBlockId = block.childrenIds[index + 1];
+ [leftBlockId, rightBlockId].forEach(async blockId => {
+ if (await checkGridItemHasOverflow(blockId)) {
+ setAlertHandleId(leftBlockId);
+ } else {
+ setAlertHandleId(null);
+ }
+ });
+ };
return (
<>
@@ -206,7 +215,35 @@ export const Grid: FC = function (props) {
ref={gridContainerRef}
isOnDrag={isOnDrag}
>
- {children}
+ {block.childrenIds.map((id, i) => {
+ return (
+
+
+ handleDragGrid(event, i)}
+ editor={editor}
+ onMouseDown={event => handleMouseDown(event, i)}
+ blockId={id}
+ enabledAddItem={
+ block.childrenIds.length < MAX_ITEM_COUNT
+ }
+ onMouseEnter={event =>
+ handleHandleMouseEnter(event, i)
+ }
+ alertHandleId={alertHandleId}
+ draggable={i !== block.childrenIds.length - 1}
+ />
+
+ );
+ })}
{isOnDrag
? ReactDOM.createPortal( , window.document.body)
diff --git a/libs/components/editor-blocks/src/blocks/group/GroupView.tsx b/libs/components/editor-blocks/src/blocks/group/GroupView.tsx
index 694fe7820f..1c2ef04605 100644
--- a/libs/components/editor-blocks/src/blocks/group/GroupView.tsx
+++ b/libs/components/editor-blocks/src/blocks/group/GroupView.tsx
@@ -60,7 +60,7 @@ const GroupContainer = styled('div')<{ isSelect?: boolean }>(
({ isSelect, theme }) => ({
background: theme.affine.palette.white,
border: '2px solid rgba(236,241,251,.5)',
- padding: '15px 12px',
+ padding: `15px 16px 0 16px`,
borderRadius: '10px',
...(isSelect
? {
diff --git a/libs/components/editor-core/src/block-content-wrapper/BlockContentWrapper.tsx b/libs/components/editor-core/src/block-content-wrapper/BlockContentWrapper.tsx
index 792b1a8455..e2d916cb8c 100644
--- a/libs/components/editor-core/src/block-content-wrapper/BlockContentWrapper.tsx
+++ b/libs/components/editor-core/src/block-content-wrapper/BlockContentWrapper.tsx
@@ -9,6 +9,7 @@ type BlockContentWrapperProps = {
children: ReactElement | null;
};
+// TODO: remove
export const WrapperWithPendantAndDragDrop: FC =
function ({ block, children, editor }) {
return (
diff --git a/libs/components/editor-core/src/block-pendant/BlockPendantProvider.tsx b/libs/components/editor-core/src/block-pendant/BlockPendantProvider.tsx
index 877c4e451a..66cf4001a0 100644
--- a/libs/components/editor-core/src/block-pendant/BlockPendantProvider.tsx
+++ b/libs/components/editor-core/src/block-pendant/BlockPendantProvider.tsx
@@ -1,5 +1,4 @@
import type { FC, PropsWithChildren } from 'react';
-import React, { useState } from 'react';
import { styled } from '@toeverything/components/ui';
import type { AsyncBlock } from '../editor';
import { PendantPopover } from './pendant-popover';
@@ -11,74 +10,68 @@ interface BlockTagProps {
block: AsyncBlock;
}
-/**
- * @deprecated Need to be refactored
- */
export const BlockPendantProvider: FC> = ({
block,
children,
}) => {
- const [container, setContainer] = useState(null);
- const [isHover, setIsHover] = useState(false);
return (
- setContainer(dom)}>
+
{children}
- {container && (
- {
- setIsHover(visible);
- }}
- >
-
-
- )}
+
+
+
+
+
);
};
-const Container = styled('div')({
+export const LINE_GAP = 16;
+const TAG_GAP = 4;
+
+const StyledTriggerLine = styled('div')({
+ padding: `${TAG_GAP}px 0`,
+ width: '100px',
+ cursor: 'default',
+ display: 'flex',
+ alignItems: 'flex-end',
position: 'relative',
- padding: '4px',
- '&:hover .triggerLine::before': {
- display: 'flex',
+
+ '::before': {
+ content: "''",
+ width: '100%',
+ height: '2px',
+ background: '#dadada',
+ display: 'none',
+ position: 'absolute',
+ left: '0',
+ top: '4px',
+ },
+ '::after': {
+ content: "''",
+ width: '0',
+ height: '2px',
+ background: '#aac4d5',
+ display: 'block',
+ position: 'absolute',
+ left: '0',
+ top: '4px',
+ transition: 'width .3s',
},
});
-const StyledTriggerLine = styled('div')<{ isHover: boolean }>(({ isHover }) => {
- return {
- padding: '4px 0',
- width: '100px',
- cursor: 'default',
- display: 'flex',
- alignItems: 'flex-end',
- position: 'relative',
-
- '::before': {
- content: "''",
- width: '100%',
- height: '2px',
- background: '#dadada',
- display: 'none',
- position: 'absolute',
- left: '0',
- top: '4px',
+const Container = styled('div')({
+ position: 'relative',
+ paddingBottom: `${LINE_GAP - TAG_GAP * 2}px`,
+ '&:hover': {
+ [StyledTriggerLine.toString()]: {
+ '&::before': {
+ display: 'flex',
+ },
+ '&::after': {
+ width: '100%',
+ },
},
- '::after': {
- content: "''",
- width: isHover ? '100%' : '0',
- height: '2px',
- background: '#aac4d5',
- display: 'block',
- position: 'absolute',
- left: '0',
- top: '4px',
- transition: 'width .3s',
- },
- };
+ },
});
diff --git a/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx b/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx
index cdc06c07d9..70cb5115c6 100644
--- a/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx
+++ b/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx
@@ -1,4 +1,4 @@
-import React, { FC, useRef } from 'react';
+import { FC, useRef } from 'react';
import { AsyncBlock } from '../../editor';
import { PendantHistoryPanel } from '../pendant-history-panel';
import {
@@ -21,8 +21,6 @@ export const PendantPopover: FC<
pointerEnterDelay={300}
pointerLeaveDelay={200}
placement="bottom-start"
- // visible={true}
- // trigger="click"
content={
block.type === 'grid');
+ // limit grid block floor counts
+ if (gridBlocks.length >= MAX_GRID_BLOCK_FLOOR) {
+ direction = BlockDropPlacement.none;
+ }
+ }
this._setBlockDragDirection(direction);
return direction;
}
diff --git a/libs/components/editor-core/src/editor/editor.ts b/libs/components/editor-core/src/editor/editor.ts
index 73e7f6f7d5..8750a566c7 100644
--- a/libs/components/editor-core/src/editor/editor.ts
+++ b/libs/components/editor-core/src/editor/editor.ts
@@ -340,7 +340,20 @@ export class Editor implements Virgo {
const rootBlockId = this.getRootBlockId();
const rootBlock = await this.getBlockById(rootBlockId);
const blockList: Array = rootBlock ? [rootBlock] : [];
- const children = (await rootBlock?.children()) || [];
+ return [...blockList, ...(await this.getOffspring(rootBlockId))];
+ }
+
+ /**
+ *
+ * get all offspring of block
+ * @param {string} id
+ * @return {*}
+ * @memberof Editor
+ */
+ async getOffspring(id: string) {
+ const block = await this.getBlockById(id);
+ const blockList: Array = [];
+ const children = (await block?.children()) || [];
for (const block of children) {
if (!block) {
continue;
@@ -379,6 +392,20 @@ export class Editor implements Virgo {
return lastBlock;
}
+ async getBlockPath(id: string) {
+ const block = await this.getBlockById(id);
+ if (!block) {
+ return [];
+ }
+ const path = [block];
+ let parent = await block.parent();
+ while (parent) {
+ path.unshift(parent);
+ parent = await parent.parent();
+ }
+ return path;
+ }
+
async getBlockByPoint(point: Point) {
const blockList = await this.getBlockList();
diff --git a/libs/components/editor-plugins/src/menu/group-menu/DragItem.tsx b/libs/components/editor-plugins/src/menu/group-menu/DragItem.tsx
index a323ca1961..73ab1fde1c 100644
--- a/libs/components/editor-plugins/src/menu/group-menu/DragItem.tsx
+++ b/libs/components/editor-plugins/src/menu/group-menu/DragItem.tsx
@@ -4,7 +4,7 @@ import { HandleParentIcon } from '@toeverything/components/icons';
import { styled } from '@toeverything/components/ui';
import { Point } from '@toeverything/utils';
-export const ICON_WIDTH = 24;
+export const ICON_WIDTH = 16;
type DragItemProps = {
isShow: boolean;
@@ -30,17 +30,21 @@ export const DragItem = function ({
);
};
-const StyledDiv = styled('div')({
+const StyledDiv = styled('div')(({ theme }) => ({
padding: '0',
- display: 'inlineFlex',
+ display: 'inline-flex',
width: `${ICON_WIDTH}px`,
- height: `${ICON_WIDTH}px`,
+ height: '20px',
cursor: 'grab',
+ '& svg': {
+ fontSize: '20px',
+ marginLeft: '-2px',
+ },
':hover': {
- backgroundColor: '#edeef0',
+ backgroundColor: '#F5F7F8',
borderRadius: '4px',
},
-});
+}));
const StyledButton = styled('div')({
padding: '0',
diff --git a/libs/components/editor-plugins/src/menu/left-menu/LeftMenuDraggable.tsx b/libs/components/editor-plugins/src/menu/left-menu/LeftMenuDraggable.tsx
index 602c08aacb..6c7e357b50 100644
--- a/libs/components/editor-plugins/src/menu/left-menu/LeftMenuDraggable.tsx
+++ b/libs/components/editor-plugins/src/menu/left-menu/LeftMenuDraggable.tsx
@@ -1,10 +1,19 @@
-import { useState, useEffect, FC } from 'react';
+import {
+ useState,
+ useEffect,
+ FC,
+ type MouseEvent,
+ type DragEvent,
+ type ReactNode,
+ type CSSProperties,
+} from 'react';
import {
Virgo,
BlockDomInfo,
PluginHooks,
BlockDropPlacement,
+ LINE_GAP,
} from '@toeverything/framework/virgo';
import { Button } from '@toeverything/components/common';
import { styled } from '@toeverything/components/ui';
@@ -14,7 +23,7 @@ import { distinctUntilChanged, Subject } from 'rxjs';
import { HandleChildIcon } from '@toeverything/components/icons';
import { MENU_WIDTH } from './menu-config';
-const MENU_BUTTON_OFFSET = 12;
+const MENU_BUTTON_OFFSET = 4;
export type LineInfoSubject = Subject<
| {
@@ -64,13 +73,13 @@ function Line(props: { lineInfo: LineInfo; rootRect: DOMRect }) {
};
const bottomLineStyle = {
...horizontalLineStyle,
- top: intersectionRect.bottom + 1 - rootRect.y,
+ top: intersectionRect.bottom + 1 - rootRect.y - LINE_GAP,
};
const verticalLineStyle = {
...lineStyle,
width: 2,
- height: intersectionRect.height,
+ height: intersectionRect.height - LINE_GAP,
top: intersectionRect.y - rootRect.y,
};
const leftLineStyle = {
@@ -93,10 +102,10 @@ function Line(props: { lineInfo: LineInfo; rootRect: DOMRect }) {
}
function DragComponent(props: {
- children: React.ReactNode;
- style: React.CSSProperties;
- onDragStart: (event: React.DragEvent) => void;
- onDragEnd: (event: React.DragEvent) => void;
+ children: ReactNode;
+ style: CSSProperties;
+ onDragStart: (event: DragEvent) => void;
+ onDragEnd: (event: DragEvent) => void;
}) {
const { style, children, onDragStart, onDragEnd } = props;
return (
@@ -122,7 +131,7 @@ export const LeftMenuDraggable: FC = props => {
const [block, setBlock] = useState();
const [line, setLine] = useState(undefined);
- const handleDragStart = async (event: React.DragEvent) => {
+ const handleDragStart = async (event: DragEvent) => {
event.stopPropagation();
setVisible(false);
@@ -138,12 +147,12 @@ export const LeftMenuDraggable: FC = props => {
}
};
- const handleDragEnd = (event: React.DragEvent) => {
+ const handleDragEnd = (event: DragEvent) => {
event.preventDefault();
setLine(undefined);
};
- const onClick = (event: React.MouseEvent) => {
+ const onClick = (event: MouseEvent) => {
if (block == null) return;
const currentTarget = event.currentTarget;
editor.selection.setSelectedNodesIds([block.blockId]);
@@ -200,11 +209,10 @@ export const LeftMenuDraggable: FC = props => {
style={{
position: 'absolute',
left:
- Math.min(
- block.rect.left -
- MENU_WIDTH -
- MENU_BUTTON_OFFSET
- ) - rootRect.left,
+ block.rect.left -
+ MENU_WIDTH -
+ MENU_BUTTON_OFFSET -
+ rootRect.left,
top: block.rect.top - rootRect.top,
opacity: visible ? 1 : 0,
zIndex: 1,
@@ -239,15 +247,19 @@ const Draggable = styled(Button)({
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'transparent',
- width: '24px',
- height: '24px',
+ width: '16px',
+ height: '22px',
+ '& svg': {
+ fontSize: '20px',
+ marginLeft: '-2px',
+ },
':hover': {
- backgroundColor: '#edeef0',
+ backgroundColor: '#F5F7F8',
borderRadius: '4px',
},
});
const LigoLeftMenu = styled('div')({
backgroundColor: 'transparent',
- marginRight: '4px',
+ // marginRight: '4px',
});
diff --git a/libs/components/editor-plugins/src/menu/left-menu/LeftMenuPlugin.tsx b/libs/components/editor-plugins/src/menu/left-menu/LeftMenuPlugin.tsx
index 00d301287e..29c421f29f 100644
--- a/libs/components/editor-plugins/src/menu/left-menu/LeftMenuPlugin.tsx
+++ b/libs/components/editor-plugins/src/menu/left-menu/LeftMenuPlugin.tsx
@@ -1,5 +1,5 @@
import { BlockDomInfo, HookType } from '@toeverything/framework/virgo';
-import React, { StrictMode } from 'react';
+import { StrictMode } from 'react';
import { BasePlugin } from '../../base-plugin';
import { ignoreBlockTypes } from './menu-config';
import { LineInfoSubject, LeftMenuDraggable } from './LeftMenuDraggable';
diff --git a/libs/components/editor-plugins/src/placeholder/PlaceholderPanel.tsx b/libs/components/editor-plugins/src/placeholder/PlaceholderPanel.tsx
index 429336c976..89b66256f7 100644
--- a/libs/components/editor-plugins/src/placeholder/PlaceholderPanel.tsx
+++ b/libs/components/editor-plugins/src/placeholder/PlaceholderPanel.tsx
@@ -141,8 +141,7 @@ export const PlaceholderPanel = (props: PlaceholderPanelProps) => {
setOpen(false);
props.onClickTips();
};
- const templateList: Array =
- TemplateFactory.defaultTemplateList;
+ const templateList = TemplateFactory.defaultTemplateList;
const handleNewFromTemplate = async (template: TemplateMeta) => {
const pageId = await editor.getRootBlockId();
const newPage = await services.api.editorBlock.getBlock(
@@ -162,33 +161,30 @@ export const PlaceholderPanel = (props: PlaceholderPanelProps) => {
setOpen(false);
};
return (
- <>
-
-
- Press Enter to continue with an empty page, or pick a
- template
-
-
- {templateList.map((template, index) => {
- return (
- {
- handleNewFromTemplate(template);
- }}
- >
- {template.name}
-
- );
- })}
-
-
- >
+
+
+ Press Enter to continue with an empty page, or pick a template
+
+
+ {templateList.map((template, index) => {
+ return (
+ {
+ handleNewFromTemplate(template);
+ }}
+ >
+ {template.name}
+
+ );
+ })}
+
+
);
};
diff --git a/libs/components/ui/src/popover/container.tsx b/libs/components/ui/src/popover/Container.tsx
similarity index 92%
rename from libs/components/ui/src/popover/container.tsx
rename to libs/components/ui/src/popover/Container.tsx
index f91e95b024..8fdfc5aea9 100644
--- a/libs/components/ui/src/popover/container.tsx
+++ b/libs/components/ui/src/popover/Container.tsx
@@ -15,11 +15,11 @@ export const PopoverContainer = styled('div')<
const shadow = theme.affine.shadows.shadowSxDownLg;
const white = theme.affine.palette.white;
- const border_radius =
+ const borderRadius =
border_radius_map[direction] || border_radius_map['left-top'];
return {
boxShadow: shadow,
- borderRadius: border_radius,
+ borderRadius: borderRadius,
padding: '8px 4px',
backgroundColor: white,
...style,
diff --git a/libs/components/ui/src/popover/Popover.tsx b/libs/components/ui/src/popover/Popover.tsx
index 67ab3f3c29..d03a65f322 100644
--- a/libs/components/ui/src/popover/Popover.tsx
+++ b/libs/components/ui/src/popover/Popover.tsx
@@ -1,7 +1,7 @@
import type { MuiPopperPlacementType as PopperPlacementType } from '../mui';
import React, { forwardRef, type PropsWithChildren } from 'react';
import { type PopperHandler, Popper } from '../popper';
-import { PopoverContainer } from './container';
+import { PopoverContainer } from './Container';
import type { PopoverProps, PopoverDirection } from './interface';
export const placementToContainerDirection: Record<
diff --git a/libs/components/ui/src/popover/index.tsx b/libs/components/ui/src/popover/index.ts
similarity index 53%
rename from libs/components/ui/src/popover/index.tsx
rename to libs/components/ui/src/popover/index.ts
index c829b413b6..718c074cce 100644
--- a/libs/components/ui/src/popover/index.tsx
+++ b/libs/components/ui/src/popover/index.ts
@@ -1,3 +1,3 @@
export * from './Popover';
export * from './interface';
-export { PopoverContainer } from './container';
+export { PopoverContainer } from './Container';
diff --git a/libs/datasource/db-service/src/services/editor-block/templates/template-factory.ts b/libs/datasource/db-service/src/services/editor-block/templates/template-factory.ts
index 953cf0e6de..88a8d08bbe 100644
--- a/libs/datasource/db-service/src/services/editor-block/templates/template-factory.ts
+++ b/libs/datasource/db-service/src/services/editor-block/templates/template-factory.ts
@@ -13,7 +13,7 @@ const groupTemplateMap = {
grid: gridTemplate,
} as GroupTemplateMap;
-const defaultTemplateList = [
+const defaultTemplateList: Array = [
{
name: 'New From Quick Start',
groupKeys: ['todolist'],
@@ -22,10 +22,10 @@ const defaultTemplateList = [
{ name: 'New From Blog', groupKeys: ['blog'] },
{ name: ' New Todolist', groupKeys: ['todolist'] },
{ name: ' New Empty Page', groupKeys: ['empty'] },
-] as const;
+];
const TemplateFactory = {
- defaultTemplateList: defaultTemplateList,
+ defaultTemplateList,
generatePageTemplateByGroupKeys(props: TemplateMeta): Template {
const newTitle = props.name || 'Get Started with AFFiNE';
const keys: GroupTemplateKeys[] = props.groupKeys || [];
diff --git a/libs/datasource/jwt/src/index.ts b/libs/datasource/jwt/src/index.ts
index c8d868cff7..16bbf5a8c4 100644
--- a/libs/datasource/jwt/src/index.ts
+++ b/libs/datasource/jwt/src/index.ts
@@ -541,6 +541,10 @@ export class BlockClient<
this.set_page(abstract_block);
});
this.#block_caches.set(abstract_block.id, abstract_block);
+
+ if (root && abstract_block.flavor === BlockFlavors.page) {
+ root.insertChildren(abstract_block);
+ }
return abstract_block;
}
}