diff --git a/libs/components/affine-board/src/Board.tsx b/libs/components/affine-board/src/Board.tsx index 9936d115a0..783c469b64 100644 --- a/libs/components/affine-board/src/Board.tsx +++ b/libs/components/affine-board/src/Board.tsx @@ -51,11 +51,10 @@ const AffineBoard = ({ }; }); - const { shapes, bindings } = useShapes(workspace, rootBlockId); - + const { shapes } = useShapes(workspace, rootBlockId); useEffect(() => { if (app) { - app.replacePageContent(shapes || {}, bindings, {}); + app.replacePageContent(shapes || {}, {}, {}); } }, [app, shapes]); @@ -69,7 +68,9 @@ const AffineBoard = ({ onMount(app) { set_app(app); }, - + async onPaste(e, data) { + console.log('e,data: ', e, data); + }, async onCopy(e, groupIds) { const clip = await getClipDataOfBlocksById( editor, @@ -110,18 +111,6 @@ const AffineBoard = ({ }); } shape.affineId = block.id; - Object.keys(bindings).forEach(bilingKey => { - if ( - bindings[bilingKey]?.fromId === shape.id - ) { - bindings[bilingKey].fromId = block.id; - } - if ( - bindings[bilingKey]?.toId === shape.id - ) { - bindings[bilingKey].toId = block.id; - } - }); return await services.api.editorBlock.update({ workspace: shape.workspace, id: block.id, @@ -134,30 +123,6 @@ const AffineBoard = ({ } }) ); - const pageBindingsString = ( - await services.api.editorBlock.get({ - workspace: workspace, - ids: [rootBlockId], - }) - )?.[0].properties.bindings?.value; - const pageBindings = JSON.parse(pageBindingsString ?? '{}'); - Object.keys(bindings).forEach(bindingsKey => { - if (!bindings[bindingsKey]) { - delete pageBindings[bindingsKey]; - } else { - Object.assign(pageBindings, bindings); - } - }); - - await services.api.editorBlock.update({ - workspace: workspace, - id: rootBlockId, - properties: { - bindings: { - value: JSON.stringify(pageBindings), - }, - }, - }); }, }} /> diff --git a/libs/components/affine-board/src/hooks/use-shapes.ts b/libs/components/affine-board/src/hooks/use-shapes.ts index ba1bf066ff..23270b6c19 100644 --- a/libs/components/affine-board/src/hooks/use-shapes.ts +++ b/libs/components/affine-board/src/hooks/use-shapes.ts @@ -5,24 +5,12 @@ import { services } from '@toeverything/datasource/db-service'; import { usePageClientWidth } from '@toeverything/datasource/state'; import { useEffect, useState } from 'react'; -const getBindings = (workspace: string, rootBlockId: string) => { - return services.api.editorBlock - .get({ - workspace: workspace, - ids: [rootBlockId], - }) - .then(blcoks => { - return blcoks[0]?.properties.bindings?.value; - }); -}; - export const useShapes = (workspace: string, rootBlockId: string) => { const { pageClientWidth } = usePageClientWidth(); // page padding left and right total 300px const editorShapeInitSize = pageClientWidth - 300; const [blocks, setBlocks] = useState<{ shapes: [ReturnEditorBlock[]]; - bindings: string; }>(); useEffect(() => { Promise.all([ @@ -43,11 +31,8 @@ export const useShapes = (workspace: string, rootBlockId: string) => { return shapes; }), ]).then(shapes => { - getBindings(workspace, rootBlockId).then(bindings => { - setBlocks({ - shapes, - bindings: bindings, - }); + setBlocks({ + shapes: shapes, }); }); @@ -65,11 +50,8 @@ export const useShapes = (workspace: string, rootBlockId: string) => { return childBlock; }) ).then(shapes => { - getBindings(workspace, rootBlockId).then(bindings => { - setBlocks({ - shapes: [shapes], - bindings: bindings, - }); + setBlocks({ + shapes: [shapes], }); }); }) @@ -107,6 +89,5 @@ export const useShapes = (workspace: string, rootBlockId: string) => { return { shapes: blocksShapes, - bindings: JSON.parse(blocks?.bindings ?? '{}'), }; }; diff --git a/libs/components/board-draw/src/TlDraw.tsx b/libs/components/board-draw/src/TlDraw.tsx index 1961367235..a1444b76c0 100644 --- a/libs/components/board-draw/src/TlDraw.tsx +++ b/libs/components/board-draw/src/TlDraw.tsx @@ -362,7 +362,7 @@ const InnerTldraw = memo(function InnerTldraw({ // Hide bounds when not using the select tool, or when the only selected shape has handles const hideBounds = - (isInSession && app.session?.constructor.name !== 'BrushSession') || + (isInSession && app.session?.constructor.name === 'BrushSession') || !isSelecting || isHideBoundsShape || !!pageState.editingId; diff --git a/libs/components/board-draw/src/components/align-panel/index.tsx b/libs/components/board-draw/src/components/align-panel/index.tsx index d0ff48390d..ddc43b1254 100644 --- a/libs/components/board-draw/src/components/align-panel/index.tsx +++ b/libs/components/board-draw/src/components/align-panel/index.tsx @@ -56,7 +56,8 @@ const SelectableContainer = styled('div')<{ selected?: boolean }>( borderRadius: '5px', overflow: 'hidden', margin: '5px', - padding: '3px', + width: '24px', + height: '24px', cursor: 'pointer', boxSizing: 'border-box', '&:hover': { diff --git a/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx b/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx index 94e28bdc2f..031d4240a6 100644 --- a/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx +++ b/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx @@ -2,7 +2,6 @@ import { TLDR, TldrawApp } from '@toeverything/components/board-state'; import { Divider, Popover, styled } from '@toeverything/components/ui'; import { Fragment } from 'react'; import { AlignOperation } from './AlignOperation'; -import { ArrowTo } from './ArrowTo'; import { BorderColorConfig } from './BorderColorConfig'; import { DeleteShapes } from './DeleteOperation'; import { FillColorConfig } from './FillColorConfig'; @@ -107,12 +106,12 @@ export const CommandPanel = ({ app }: { app: TldrawApp }) => { shapes={config.deleteShapes.selectedShapes} > ) : null, - toNextShap: ( - - ), + // toNextShap: ( + // + // ), }; const nodes = Object.entries(configNodes).filter(([key, node]) => !!node); diff --git a/libs/components/board-shapes/src/arrow-util/arrow-util.tsx b/libs/components/board-shapes/src/arrow-util/arrow-util.tsx index 42045918f4..dace7eeb38 100644 --- a/libs/components/board-shapes/src/arrow-util/arrow-util.tsx +++ b/libs/components/board-shapes/src/arrow-util/arrow-util.tsx @@ -42,7 +42,7 @@ type E = HTMLDivElement; export class ArrowUtil extends TDShapeUtil { type = TDShapeType.Arrow as const; - override hideBounds = true; + override hideBounds = false; override canEdit = true; diff --git a/libs/components/board-shapes/src/rectangle-util/components/DashedRectangle.tsx b/libs/components/board-shapes/src/rectangle-util/components/DashedRectangle.tsx index 77ee2cec6a..36d4475b92 100644 --- a/libs/components/board-shapes/src/rectangle-util/components/DashedRectangle.tsx +++ b/libs/components/board-shapes/src/rectangle-util/components/DashedRectangle.tsx @@ -1,6 +1,8 @@ import { Utils } from '@tldraw/core'; -import type { ShapeStyles } from '@toeverything/components/board-types'; -import { BINDING_DISTANCE } from '@toeverything/components/board-types'; +import { + BINDING_DISTANCE, + ShapeStyles, +} from '@toeverything/components/board-types'; import * as React from 'react'; import { getShapeStyle } from '../../shared'; @@ -56,23 +58,20 @@ export const DashedRectangle = React.memo(function DashedRectangle({ return ( <> {style.isFilled && ( diff --git a/libs/components/board-state/src/tldraw-app.ts b/libs/components/board-state/src/tldraw-app.ts index 98bffcf654..1e95912db5 100644 --- a/libs/components/board-state/src/tldraw-app.ts +++ b/libs/components/board-state/src/tldraw-app.ts @@ -175,6 +175,10 @@ interface TDCallbacks { * (optional) A callback to run when the shape is copied. */ onCopy?: (e: ClipboardEvent, ids: string[]) => void; + /** + * (optional) A callback to run when the shape is paste. + */ + onPaste?: (e: ClipboardEvent, data: any) => void; } export interface TldrawAppCtorProps { @@ -1956,6 +1960,53 @@ export class TldrawApp extends StateManager { paste = async (point?: number[], e?: ClipboardEvent) => { if (this.readOnly) return; + if (e) { + const data = e.clipboardData?.getData('text/html'); + const paste_as_html = (html: string) => { + try { + const maybeJson = html.match(/(.*)<\/tldraw>/)?.[1]; + + if (!maybeJson) return; + + const json: { + type: string; + shapes: TDShape[]; + bindings: TDBinding[]; + assets: TDAsset[]; + } = JSON.parse(maybeJson); + return json; + } catch (e) { + return; + } + }; + this.callbacks.onPaste?.(e, paste_as_html(data)); + return this; + } + + const paste_as_html = (html: string) => { + try { + const maybeJson = html.match(/(.*)<\/tldraw>/)?.[1]; + + if (!maybeJson) return; + + const json: { + type: string; + shapes: TDShape[]; + bindings: TDBinding[]; + assets: TDAsset[]; + } = JSON.parse(maybeJson); + + if (json.type === 'tldr/clipboard') { + pasteInCurrentPage(json.shapes, json.bindings, json.assets); + return; + } else { + throw Error('Not tldraw data!'); + } + } catch (e) { + pasteTextAsShape(html); + return; + } + }; const pasteInCurrentPage = ( shapes: TDShape[], bindings: TDBinding[], @@ -2107,31 +2158,6 @@ export class TldrawApp extends StateManager { // this.select(shapeId); }; - const paste_as_html = (html: string) => { - try { - const maybeJson = html.match(/(.*)<\/tldraw>/)?.[1]; - - if (!maybeJson) return; - - const json: { - type: string; - shapes: TDShape[]; - bindings: TDBinding[]; - assets: TDAsset[]; - } = JSON.parse(maybeJson); - - if (json.type === 'tldr/clipboard') { - pasteInCurrentPage(json.shapes, json.bindings, json.assets); - return; - } else { - throw Error('Not tldraw data!'); - } - } catch (e) { - pasteTextAsShape(html); - return; - } - }; - if (e !== undefined) { const items: DataTransferItemList = e.clipboardData?.items ?? ({} as DataTransferItemList); diff --git a/libs/components/editor-blocks/src/blocks/code/CodeView.tsx b/libs/components/editor-blocks/src/blocks/code/CodeView.tsx index 2739c8a70c..1bcedf4251 100644 --- a/libs/components/editor-blocks/src/blocks/code/CodeView.tsx +++ b/libs/components/editor-blocks/src/blocks/code/CodeView.tsx @@ -1,58 +1,54 @@ -import { useState, useRef, useEffect } from 'react'; -import { StyleWithAtRules } from 'style9'; - -import { CreateView } from '@toeverything/framework/virgo'; -import CodeMirror, { ReactCodeMirrorRef } from './CodeMirror'; -import { styled } from '@toeverything/components/ui'; - -import { javascript } from '@codemirror/lang-javascript'; -import { html } from '@codemirror/lang-html'; -import { css } from '@codemirror/lang-css'; -import { json } from '@codemirror/lang-json'; -import { python } from '@codemirror/lang-python'; -import { markdown } from '@codemirror/lang-markdown'; -import { xml } from '@codemirror/lang-xml'; -import { sql, MySQL, PostgreSQL } from '@codemirror/lang-sql'; -import { java } from '@codemirror/lang-java'; -import { rust } from '@codemirror/lang-rust'; import { cpp } from '@codemirror/lang-cpp'; +import { css } from '@codemirror/lang-css'; +import { html } from '@codemirror/lang-html'; +import { java } from '@codemirror/lang-java'; +import { javascript } from '@codemirror/lang-javascript'; +import { json } from '@codemirror/lang-json'; import { lezer } from '@codemirror/lang-lezer'; +import { markdown } from '@codemirror/lang-markdown'; import { php } from '@codemirror/lang-php'; +import { python } from '@codemirror/lang-python'; +import { rust } from '@codemirror/lang-rust'; +import { MySQL, PostgreSQL, sql } from '@codemirror/lang-sql'; +import { xml } from '@codemirror/lang-xml'; import { StreamLanguage } from '@codemirror/language'; -import { go } from '@codemirror/legacy-modes/mode/go'; -import { ruby } from '@codemirror/legacy-modes/mode/ruby'; -import { shell } from '@codemirror/legacy-modes/mode/shell'; -import { lua } from '@codemirror/legacy-modes/mode/lua'; -import { swift } from '@codemirror/legacy-modes/mode/swift'; -import { tcl } from '@codemirror/legacy-modes/mode/tcl'; -import { yaml } from '@codemirror/legacy-modes/mode/yaml'; -import { vb } from '@codemirror/legacy-modes/mode/vb'; -import { powerShell } from '@codemirror/legacy-modes/mode/powershell'; import { brainfuck } from '@codemirror/legacy-modes/mode/brainfuck'; -import { stylus } from '@codemirror/legacy-modes/mode/stylus'; -import { erlang } from '@codemirror/legacy-modes/mode/erlang'; -import { elixir } from 'codemirror-lang-elixir'; -import { nginx } from '@codemirror/legacy-modes/mode/nginx'; -import { perl } from '@codemirror/legacy-modes/mode/perl'; -import { pascal } from '@codemirror/legacy-modes/mode/pascal'; -import { liveScript } from '@codemirror/legacy-modes/mode/livescript'; -import { scheme } from '@codemirror/legacy-modes/mode/scheme'; -import { toml } from '@codemirror/legacy-modes/mode/toml'; -import { vbScript } from '@codemirror/legacy-modes/mode/vbscript'; import { clojure } from '@codemirror/legacy-modes/mode/clojure'; import { coffeeScript } from '@codemirror/legacy-modes/mode/coffeescript'; import { dockerFile } from '@codemirror/legacy-modes/mode/dockerfile'; +import { erlang } from '@codemirror/legacy-modes/mode/erlang'; +import { go } from '@codemirror/legacy-modes/mode/go'; import { julia } from '@codemirror/legacy-modes/mode/julia'; +import { liveScript } from '@codemirror/legacy-modes/mode/livescript'; +import { lua } from '@codemirror/legacy-modes/mode/lua'; +import { nginx } from '@codemirror/legacy-modes/mode/nginx'; +import { pascal } from '@codemirror/legacy-modes/mode/pascal'; +import { perl } from '@codemirror/legacy-modes/mode/perl'; +import { powerShell } from '@codemirror/legacy-modes/mode/powershell'; import { r } from '@codemirror/legacy-modes/mode/r'; +import { ruby } from '@codemirror/legacy-modes/mode/ruby'; +import { scheme } from '@codemirror/legacy-modes/mode/scheme'; +import { shell } from '@codemirror/legacy-modes/mode/shell'; +import { stylus } from '@codemirror/legacy-modes/mode/stylus'; +import { swift } from '@codemirror/legacy-modes/mode/swift'; +import { tcl } from '@codemirror/legacy-modes/mode/tcl'; +import { toml } from '@codemirror/legacy-modes/mode/toml'; +import { vb } from '@codemirror/legacy-modes/mode/vb'; +import { vbScript } from '@codemirror/legacy-modes/mode/vbscript'; +import { yaml } from '@codemirror/legacy-modes/mode/yaml'; import { Extension } from '@codemirror/state'; -import { Option, Select } from '@toeverything/components/ui'; - import { - useOnSelect, BlockPendantProvider, + useOnSelect, } from '@toeverything/components/editor-core'; -import { copyToClipboard } from '@toeverything/utils'; import { DuplicateIcon } from '@toeverything/components/icons'; +import { Option, Select, styled } from '@toeverything/components/ui'; +import { CreateView } from '@toeverything/framework/virgo'; +import { copyToClipboard } from '@toeverything/utils'; +import { elixir } from 'codemirror-lang-elixir'; +import { useEffect, useRef, useState } from 'react'; +import { StyleWithAtRules } from 'style9'; +import CodeMirror, { ReactCodeMirrorRef } from './CodeMirror'; interface CreateCodeView extends CreateView { style9?: StyleWithAtRules; @@ -110,13 +106,15 @@ const CodeBlock = styled('div')(({ theme }) => ({ borderRadius: theme.affine.shape.borderRadius, '&:hover': { '.operation': { - display: 'flex', + opacity: 1, }, }, '.operation': { display: 'flex', flexWrap: 'wrap', justifyContent: 'space-between', + opacity: 0, + transition: 'opacity 1.5s', }, '.copy-block': { padding: '0px 10px',