init: the first public commit for AFFiNE

This commit is contained in:
DarkSky
2022-07-22 15:49:21 +08:00
commit e3e3741393
1451 changed files with 108124 additions and 0 deletions
@@ -0,0 +1,131 @@
import { FC, useEffect, useLayoutEffect, useRef } from 'react';
import { ChildrenView } from '@toeverything/framework/virgo';
import { styled } from '@toeverything/components/ui';
import { sleep } from '@toeverything/utils';
import { GRID_ITEM_MIN_WIDTH, GRID_PROPERTY_KEY, removePercent } from '../grid';
export const GRID_ITEM_CLASS_NAME = 'grid-item';
export const GRID_ITEM_CONTENT_CLASS_NAME = `${GRID_ITEM_CLASS_NAME}-content`;
export const GridItem: FC<ChildrenView> = function (props) {
const { children, block } = props;
const RENDER_DELAY_TIME = 100;
const ref = useRef<HTMLDivElement>();
useLayoutEffect(() => {
if (block && ref.current) {
block.dom = ref.current;
}
});
const setWidth = (width: string) => {
const parent = ref.current?.parentElement as HTMLDivElement;
parent.style.width = width;
};
const checkAndRefreshWidth = async () => {
const currentWidth = block.getProperty(GRID_PROPERTY_KEY);
if (currentWidth) {
setWidth(currentWidth);
} else if (!block.dom?.style.width) {
const parent = await block.parent();
const children = await parent.children();
const length = children.length;
/* TODO fix db update time is not controllable */
await sleep(RENDER_DELAY_TIME);
/* if do not has gridItemWidth means it is a new block ,need set new width */
if (!block.getProperty(GRID_PROPERTY_KEY)) {
/* only new grid has two grid */
if (length <= 2) {
block.setProperty(GRID_PROPERTY_KEY, '50%');
setWidth('50%');
} else {
const newBlockLength = Math.floor(100 / length);
let totalWidth = newBlockLength;
let index = 0;
const minus = newBlockLength / (length - 1);
setWidth(`${newBlockLength}%`);
await block.setProperty(
GRID_PROPERTY_KEY,
`${newBlockLength}%`
);
let needFixWidth = 0;
for (const child of children) {
if (child.id !== block.id) {
/* fix other block`s width */
const originWidth = Number(
removePercent(
child.getProperty(GRID_PROPERTY_KEY)
)
);
let newWidth;
newWidth = Math.floor(originWidth - minus);
/*
if new width less then min width,
set min width and next block will be fix width
*/
if (newWidth < GRID_ITEM_MIN_WIDTH) {
needFixWidth += GRID_ITEM_MIN_WIDTH - newWidth;
newWidth = GRID_ITEM_MIN_WIDTH;
}
// if can fix width, fix width
if (
newWidth > GRID_ITEM_MIN_WIDTH &&
needFixWidth
) {
if (
newWidth - needFixWidth >=
GRID_ITEM_MIN_WIDTH
) {
newWidth = newWidth - needFixWidth;
needFixWidth = 0;
} else {
needFixWidth =
needFixWidth -
(newWidth - GRID_ITEM_MIN_WIDTH);
newWidth = GRID_ITEM_MIN_WIDTH;
}
}
if (index === children.length - 2) {
// the last other block width should be 100% - other totalWidth
newWidth = Math.floor(100 - totalWidth);
}
totalWidth += newWidth;
await child.setProperty(
GRID_PROPERTY_KEY,
`${newWidth}%`
);
if (child.dom.parentElement) {
child.dom.parentElement.style.width = `${newWidth}%`;
}
index += 1;
}
}
}
}
}
};
useEffect(() => {
checkAndRefreshWidth();
}, [block]);
return (
<GridItemContainer
data-block-id={props.block.id}
className={GRID_ITEM_CONTENT_CLASS_NAME}
ref={ref}
>
{children}
</GridItemContainer>
);
};
const GridItemContainer = styled('div')({
transition: 'background-color 0.3s ease-in-out',
maxWidth: 'calc(100% - 10px)',
padding: '4px',
flexGrow: 1,
border: '1px solid transparent',
borderRadius: '4px',
});
@@ -0,0 +1,18 @@
import { FC } from 'react';
import { RenderBlock } from '@toeverything/components/editor-core';
import { ChildrenView, CreateView } from '@toeverything/framework/virgo';
export const GridItemRender = function (creator: FC<ChildrenView>) {
const GridItem: FC<CreateView> = function (props) {
const { block } = props;
const children = (
<>
{block.childrenIds.map(id => {
return <RenderBlock key={id} blockId={id} />;
})}
</>
);
return <>{creator({ ...props, children })}</>;
};
return GridItem;
};
@@ -0,0 +1,25 @@
import { GridItem, GRID_ITEM_CLASS_NAME } from './GridItem';
import { Protocol } from '@toeverything/datasource/db-service';
import { AsyncBlock, BaseView } from '@toeverything/framework/virgo';
import { GridItemRender } from './GridItemRender';
export class GridItemBlock extends BaseView {
public override selectable = false;
public override activatable = false;
public override allowPendant = false;
type = Protocol.Block.Type.grid;
View = GridItemRender(GridItem);
override async onCreate(block: AsyncBlock): Promise<AsyncBlock> {
return block;
}
override async onDeleteChild(block: AsyncBlock): Promise<boolean> {
if (block.childrenIds.length === 0) {
await block.remove();
}
return true;
}
}