diff --git a/.env.local b/.env.local-dev similarity index 100% rename from .env.local rename to .env.local-dev diff --git a/libs/components/account/src/login/firebase.tsx b/libs/components/account/src/login/firebase.tsx index 3637757dc..e2f0a6b08 100644 --- a/libs/components/account/src/login/firebase.tsx +++ b/libs/components/account/src/login/firebase.tsx @@ -1,7 +1,6 @@ /* eslint-disable filename-rules/match */ -import { useCallback, useMemo } from 'react'; +import { useCallback, useMemo, useState } from 'react'; import { initializeApp } from 'firebase/app'; -import { Error } from './../error'; import { GoogleAuthProvider, getAuth, @@ -13,11 +12,12 @@ import { LogoImg } from '@toeverything/components/common'; import { MuiButton, MuiBox, - MuiTypography, - MuiContainer, MuiGrid, + MuiSnackbar, } from '@toeverything/components/ui'; +import { Error } from './../error'; + const _firebaseConfig = { apiKey: 'AIzaSyD7A_VyGaKTXsPqtga9IbwrEsbWWc4rH3Y', authDomain: 'login.affine.pro', @@ -83,6 +83,8 @@ export const Firebase = () => { return [auth, provider]; }, []); + const [error, setError] = useState(false); + const handleAuth = useCallback(() => { signInWithPopup(auth, provider).catch(error => { const errorCode = error.code; @@ -90,11 +92,18 @@ export const Firebase = () => { const email = error.customData.email; const credential = GoogleAuthProvider.credentialFromError(error); console.log(errorCode, errorMessage, email, credential); + setError(true); + setTimeout(() => setError(false), 3000); }); }, [auth, provider]); return ( + void, + retry = 0 +) => { + const [page] = await services.api.editorBlock.search(workspace, { + tag: `id:${blockId}`, + }); + if (page?.content) { + onFinal(page?.content); + } else if (retry < 20) { + await sleep(500); + updateTitle(workspace, blockId, onFinal, retry + 1); + } else { + onFinal('Untitled'); + } +}; + +const bindBlock = async ( + handleId: string, + workspace: string, + blockId: string, + onFinal: (title: string) => void, + retry = 0 +): Promise<() => void> | undefined => { + const block = await services.api.editorBlock.getBlock(workspace, blockId); + if (block.id === blockId) { + const debouncedOnFinal = debounce(onFinal, 100, { maxWait: 500 }); + const onUpdated = () => + updateTitle(workspace, blockId, debouncedOnFinal); + block.on('content', handleId, onUpdated); + onUpdated(); + return () => block.off('content', handleId); + } else if (retry < 20) { + await sleep(500); + return bindBlock(handleId, workspace, blockId, onFinal, retry + 1); + } else { + onFinal('Untitled'); + return undefined; + } +}; + +const useBlockTitle = (block: AsyncBlock, blockId: string) => { + const [title, setTitle] = useState('Loading...'); + + useEffect(() => { + let callback: any = undefined; + + bindBlock( + block.id + nanoid(8), + block.workspace, + blockId, + setTitle + ).then(cb => { + callback = cb; + }); + + return () => callback?.(); + }, [block.id, block.workspace, blockId]); + + return title; +}; + +type BlockPreviewProps = { + block: AsyncBlock; + blockId: string; + editorElement?: () => JSX.Element; +}; + +const InternalBlockPreview = (props: BlockPreviewProps) => { + const container = useRef(); + const [preview, setPreview] = useState(true); + const title = useBlockTitle(props.block, props.blockId); + + const AffineEditor = props.editorElement as any; + + useEffect(() => { + if (container?.current) { + const element = container?.current; + const resizeObserver = new IntersectionObserver(entries => { + const height = entries?.[0]?.intersectionRect.height; + setPreview(height < 174); + }); + + resizeObserver.observe(element); + return () => resizeObserver.unobserve(element); + } + return undefined; + }, [container, props]); + + return ( +
+ + {preview ? ( + + Preview + + ) : AffineEditor ? ( + + ) : null} + +
+ ); +}; + +export const BlockPreview = memo(InternalBlockPreview, (prev, next) => { + return ( + prev.block.workspace === next.block.workspace && + prev.blockId === next.blockId + ); +}); 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 03ab18dab..bd06a0dd9 100644 --- a/libs/components/editor-blocks/src/components/source-view/SourceView.tsx +++ b/libs/components/editor-blocks/src/components/source-view/SourceView.tsx @@ -1,13 +1,11 @@ -import { FC, memo, useEffect, useMemo, useRef, useState } from 'react'; +import { FC } from 'react'; -import { StyledBlockPreview } from '@toeverything/components/common'; import { styled } from '@toeverything/components/ui'; import { AsyncBlock, useRecastBlockScene } from '@toeverything/framework/virgo'; import { formatUrl } from './format-url'; import { SCENE_CONFIG } from '../../blocks/group/config'; -import { services } from '@toeverything/datasource/db-service'; -import { debounce } from '@toeverything/utils'; +import { BlockPreview } from './BlockView'; const MouseMaskContainer = styled('div')({ position: 'absolute', zIndex: 1, @@ -47,96 +45,6 @@ const _getLinkStyle = (scene: string) => { } }; -type BlockPreviewProps = { - block: AsyncBlock; - blockId: string; - editorElement?: () => JSX.Element; -}; - -const BlockPreview = (props: BlockPreviewProps) => { - const container = useRef(); - const [preview, setPreview] = useState(true); - const [title, setTitle] = useState('Loading...'); - useEffect(() => { - let callback: any = undefined; - services.api.editorBlock - .getBlock(props.block.workspace, props.blockId) - .then(block => { - if (block.id === props.blockId) { - const updateTitle = debounce( - async () => { - const [page] = - await services.api.editorBlock.search( - props.block.workspace, - { tag: 'id:affine67Uz4DstDk6PKUbz' } - ); - - console.log(page); - setTitle(page?.content || 'Untitled'); - }, - 100, - { maxWait: 500 } - ); - block.on('content', props.block.id, updateTitle); - callback = () => block.off('content', props.block.id); - updateTitle(); - } else { - setTitle('Untitled'); - } - }); - return () => callback?.(); - }, [props.block.id, props.block.workspace, props.blockId]); - - const AffineEditor = props.editorElement as any; - - useEffect(() => { - if (container?.current) { - const element = container?.current; - const resizeObserver = new IntersectionObserver(entries => { - const height = entries?.[0]?.intersectionRect.height; - setPreview(height < 174); - }); - - resizeObserver.observe(element); - return () => resizeObserver.unobserve(element); - } - return undefined; - }, [container]); - - return ( -
- - {preview ? ( - - Preview - - ) : AffineEditor ? ( - - ) : null} - -
- ); -}; - -const MemoBlockPreview = memo(BlockPreview, (prev, next) => { - return ( - prev.block.workspace === next.block.workspace && - prev.blockId === next.blockId - ); -}); - const SourceViewContainer = styled('div')<{ isSelected: boolean; scene: string; @@ -186,7 +94,7 @@ export const SourceView: FC = props => { scene={SCENE_CONFIG.REFLINK} style={{ padding: '0' }} > - { loading, }; }; + export const useUserAndSpaces = process.env['NX_LOCAL'] ? _useUserAndSpacesForFreeLogin : _useUserAndSpace; diff --git a/package.json b/package.json index 49393c41c..6cba0f24a 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "license": "MIT", "author": "AFFiNE ", "scripts": { - "start": "env-cmd -f .env.local nx serve ligo-virgo", + "start": "env-cmd -f .env.local-dev nx serve ligo-virgo", "start:affine": "nx serve ligo-virgo", "start:keck": "nx serve keck", "build": "nx build ligo-virgo", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2ed3b0e5d..529cd6f4a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -379,6 +379,7 @@ importers: code-example: ^3.3.6 codemirror: 6.0.1 keymap: link:@codemirror/next/keymap + nanoid: ^4.0.0 react-resizable: ^3.0.4 react-window: ^1.8.7 slate: ^0.81.1 @@ -414,6 +415,7 @@ importers: code-example: 3.3.6 codemirror: 6.0.1 keymap: link:@codemirror/next/keymap + nanoid: 4.0.0 react-resizable: 3.0.4 react-window: 1.8.7 slate: 0.81.1