diff --git a/packages/presentation/src/components/DrawingBoardToolbar.svelte b/packages/presentation/src/components/DrawingBoardToolbar.svelte
index 1d5f793615..856b96405e 100644
--- a/packages/presentation/src/components/DrawingBoardToolbar.svelte
+++ b/packages/presentation/src/components/DrawingBoardToolbar.svelte
@@ -80,7 +80,7 @@
case 'add-color': {
if (colorSelector !== undefined) {
colorSelector.value = penColor
- colorSelector.click()
+ colorSelector.showPicker()
}
break
}
@@ -130,8 +130,8 @@
if (!penColors.includes(penColor)) {
penColor = penColors[0] ?? defaultColor
}
- penWidth = parseInt(localStorage.getItem(storageKey.penWidth) ?? '4')
- eraserWidth = parseInt(localStorage.getItem(storageKey.eraserWidth) ?? '30')
+ penWidth = parseInt(localStorage.getItem(storageKey.penWidth) ?? '6')
+ eraserWidth = parseInt(localStorage.getItem(storageKey.eraserWidth) ?? '50')
})
function updatePenWidth (): void {
@@ -181,9 +181,25 @@
{/if}
{#if tool === 'pen'}
-
+
{:else}
-
+
{/if}
{#each penColors as color}
@@ -247,4 +263,8 @@
width: 0;
opacity: 0;
}
+
+ .widthSelector {
+ width: 80px;
+ }
diff --git a/packages/presentation/src/drawing.ts b/packages/presentation/src/drawing.ts
index cc9a97b402..fd459fda00 100644
--- a/packages/presentation/src/drawing.ts
+++ b/packages/presentation/src/drawing.ts
@@ -295,7 +295,6 @@ export function drawing (
}
})
prevPos = { x, y }
- props.panned?.(draw.offset)
})
}
}
@@ -310,6 +309,8 @@ export function drawing (
if (draw.isDrawingTool()) {
draw.drawLive(e.offsetX, e.offsetY, true)
storeCommand()
+ } else if (draw.tool === 'pan') {
+ props.panned?.(draw.offset)
}
draw.on = false
}
@@ -347,6 +348,7 @@ export function drawing (
canvas.style.cursor = props.defaultCursor ?? 'default'
} else if (draw.isDrawingTool()) {
canvas.style.cursor = 'none'
+ canvasCursor.style.visibility = 'visible'
const erasing = draw.tool === 'erase'
const w = draw.cursorWidth()
canvasCursor.style.background = erasing ? 'none' : draw.penColor
diff --git a/packages/ui/src/components/Dialog.svelte b/packages/ui/src/components/Dialog.svelte
index ef8f85087d..9679461d9f 100644
--- a/packages/ui/src/components/Dialog.svelte
+++ b/packages/ui/src/components/Dialog.svelte
@@ -35,6 +35,10 @@
const dispatch = createEventDispatcher()
+ export function maximize (): void {
+ toggleFullSize = true
+ }
+
let fullSize: boolean = false
let toggleFullSize: boolean = fullSize
$: needFullSize = checkAdaptiveMatching($deviceInfo.size, 'md')
diff --git a/plugins/text-editor-resources/src/components/CollaborativeTextEditor.svelte b/plugins/text-editor-resources/src/components/CollaborativeTextEditor.svelte
index 938e5d7714..711a7c4b34 100644
--- a/plugins/text-editor-resources/src/components/CollaborativeTextEditor.svelte
+++ b/plugins/text-editor-resources/src/components/CollaborativeTextEditor.svelte
@@ -16,7 +16,15 @@
-->
+
+{#if savedCmds !== undefined && savedProps !== undefined}
+ {#if loading}
+
+
+
+
+ {:else}
+ {
+ savedCmds.push([cmd])
+ },
+ panned: (offset) => {
+ savedProps.set('offset', offset)
+ }
+ }}
+ >
+ {#if grabFocus}
+
+
+
+ {/if}
+ {#if !readonly}
+ {
+ savedCmds.delete(0, savedCmds.length)
+ savedProps.set('offset', { x: 0, y: 0 })
+ }}
+ />
+ {/if}
+
+
+ {/if}
+{/if}
+
+
diff --git a/plugins/text-editor-resources/src/components/DrawingBoardNodeView.svelte b/plugins/text-editor-resources/src/components/DrawingBoardNodeView.svelte
new file mode 100644
index 0000000000..6c8d20b80e
--- /dev/null
+++ b/plugins/text-editor-resources/src/components/DrawingBoardNodeView.svelte
@@ -0,0 +1,176 @@
+
+
+
+{#if savedBoard?.commands !== undefined && savedBoard?.props !== undefined}
+
+
+
+
+ {#if selected}
+
+
+ {/if}
+
+
+{/if}
+
+
diff --git a/plugins/text-editor-resources/src/components/DrawingBoardPopup.svelte b/plugins/text-editor-resources/src/components/DrawingBoardPopup.svelte
index 75348ad5e2..2d894be680 100644
--- a/plugins/text-editor-resources/src/components/DrawingBoardPopup.svelte
+++ b/plugins/text-editor-resources/src/components/DrawingBoardPopup.svelte
@@ -13,109 +13,36 @@
// limitations under the License.
-->
{#if savedCmds !== undefined && savedProps !== undefined}
{/if}
diff --git a/plugins/text-editor-resources/src/components/extension/drawingBoard.ts b/plugins/text-editor-resources/src/components/extension/drawingBoard.ts
index c1476599cb..e01d31a569 100644
--- a/plugins/text-editor-resources/src/components/extension/drawingBoard.ts
+++ b/plugins/text-editor-resources/src/components/extension/drawingBoard.ts
@@ -13,41 +13,26 @@
// limitations under the License.
//
-import { type DrawingCmd, type DrawingProps, drawing } from '@hcengineering/presentation'
+import { type DrawingCmd } from '@hcengineering/presentation'
import { showPopup } from '@hcengineering/ui'
import { type Editor, mergeAttributes, Node } from '@tiptap/core'
import { NodeSelection } from '@tiptap/pm/state'
-import type { Array as YArray, Doc as YDoc, Map as YMap } from 'yjs'
+import type { Array as YArray, Map as YMap } from 'yjs'
+import DrawingBoardNodeView from '../DrawingBoardNodeView.svelte'
import DrawingBoardPopup from '../DrawingBoardPopup.svelte'
-
-const defaultHeight = 500
-const maxHeight = 1000
-const minHeight = 100
+import { SvelteNodeViewRenderer } from '../node-view'
export interface DrawingBoardOptions {
- ydoc?: YDoc
+ getSavedBoard: (id: string) => SavedBoard
}
-const scribbleSvg = ``
-const chevronSvg = ``
-
-interface SavedBoard {
+export interface SavedBoard {
commands: YArray
props: YMap
+ loading: boolean
}
-function getSavedBoard (ydoc: YDoc | undefined, id: string): SavedBoard {
- const board = ydoc?.getMap(`drawing-board-${id}`)
- const commands = board?.get('commands') as YArray
- const props = board?.get('props') as YMap
- return { commands, props }
-}
-
-function showBoardPopup (board: SavedBoard, editor: Editor): void {
+export function showBoardPopup (board: SavedBoard, editor: Editor): void {
if (board.commands !== undefined && board.props !== undefined) {
showPopup(
DrawingBoardPopup,
@@ -76,23 +61,35 @@ export const DrawingBoardExtension = Node.create({
group: 'block',
+ draggable: true,
+
renderHTML ({ HTMLAttributes }) {
return ['div', mergeAttributes({ 'data-type': this.name }, HTMLAttributes)]
},
+ parseHTML () {
+ return [
+ {
+ tag: 'div[data-type="drawingBoard"]'
+ }
+ ]
+ },
+
addOptions () {
return {
- ydoc: undefined
+ getSavedBoard: (id) => ({}) as any as SavedBoard
}
},
addAttributes () {
return {
id: {
- renderHTML: (attrs) => ({ 'data-id': attrs.id })
+ renderHTML: (attrs) => ({ 'data-id': attrs.id }),
+ parseHTML: (element) => element.getAttribute('data-id')
},
height: {
- renderHTML: (attrs) => ({ 'data-height': attrs.height })
+ renderHTML: (attrs) => ({ 'data-height': attrs.height }),
+ parseHTML: (element) => parseInt(element.getAttribute('data-height') ?? '500')
}
}
},
@@ -105,8 +102,10 @@ export const DrawingBoardExtension = Node.create({
if (state.selection instanceof NodeSelection) {
const node = state.selection.node
if (node?.type.name === this.name) {
- const board = getSavedBoard(this.options.ydoc, node.attrs.id)
- showBoardPopup(board, this.editor)
+ const board = this.options.getSavedBoard(node.attrs.id)
+ if (!board.loading) {
+ showBoardPopup(board, this.editor)
+ }
return true
}
}
@@ -122,155 +121,11 @@ export const DrawingBoardExtension = Node.create({
},
addNodeView () {
- return ({ node, getPos }) => {
- const board = getSavedBoard(this.options.ydoc, node.attrs.id)
- if (board.commands === undefined || board.props === undefined) {
- return {}
+ return SvelteNodeViewRenderer(DrawingBoardNodeView, {
+ contentAs: 'div',
+ componentProps: {
+ getSavedBoard: this.options.getSavedBoard
}
-
- const normalBorder = '1px solid var(--theme-navpanel-border)'
- const selectedBorder = '1px solid var(--theme-editbox-focus-border)'
-
- const dom = document.createElement('div')
- dom.id = node.attrs.id
- dom.contentEditable = 'false'
- dom.style.width = '100%'
- dom.style.position = 'relative'
- dom.style.height = `${node.attrs.height ?? defaultHeight}px`
- dom.style.border = normalBorder
- dom.style.borderRadius = 'var(--small-BorderRadius)'
- dom.style.backgroundColor = 'var(--theme-navpanel-color)'
- dom.ondblclick = () => {
- showBoardPopup(board, this.editor)
- }
-
- const drawingProps: DrawingProps = {
- readonly: true,
- autoSize: true,
- commands: board.commands.toArray(),
- commandCount: board.commands.length,
- offset: board.props.get('offset')
- }
-
- const { canvas, update: updateDrawing } = drawing(dom, drawingProps)
- if (canvas === undefined || updateDrawing === undefined) {
- return {}
- }
- dom.appendChild(canvas)
-
- const listenSavedCommands = (): void => {
- let update = false
- if (board.commands.length === 0) {
- update = true
- drawingProps.commands = []
- } else if (board.commands.length > drawingProps.commands.length) {
- update = true
- for (let i = drawingProps.commands.length; i < board.commands.length; i++) {
- drawingProps.commands.push(board.commands.get(i))
- }
- }
- if (update) {
- drawingProps.commandCount = board.commands.length
- updateDrawing(drawingProps)
- }
- }
- const listenSavedProps = (): void => {
- drawingProps.offset = board.props.get('offset')
- updateDrawing(drawingProps)
- }
- board.commands.observe(listenSavedCommands)
- board.props.observe(listenSavedProps)
-
- const button = document.createElement('div')
- button.style.visibility = 'hidden'
- button.style.cursor = 'pointer'
- button.style.position = 'absolute'
- button.style.top = '0.3rem'
- button.style.right = '0.3rem'
- button.style.width = '2.2rem'
- button.style.height = '2.2rem'
- button.style.color = 'var(--primary-button-color)'
- button.style.backgroundColor = 'var(--primary-button-default)'
- button.style.borderRadius = 'var(--extra-small-BorderRadius)'
- button.style.border = normalBorder
- button.style.display = 'flex'
- button.style.alignItems = 'center'
- button.style.justifyContent = 'center'
- button.innerHTML = scribbleSvg
- button.onclick = () => {
- showBoardPopup(board, this.editor)
- }
- dom.appendChild(button)
-
- const resizer = document.createElement('div')
- resizer.style.position = 'absolute'
- resizer.style.bottom = '0'
- resizer.style.left = 'calc(50% - 4rem)'
- resizer.style.width = '8rem'
- resizer.style.height = '0.6rem'
- resizer.style.cursor = 'row-resize'
- resizer.style.color = 'var(--global-on-accent-TextColor)'
- resizer.style.backgroundColor = 'var(--global-accent-IconColor)'
- resizer.style.border = selectedBorder
- resizer.style.display = 'flex'
- resizer.style.alignItems = 'center'
- resizer.style.justifyContent = 'center'
- resizer.style.visibility = 'hidden'
- resizer.style.borderTopLeftRadius = 'var(--small-BorderRadius)'
- resizer.style.borderTopRightRadius = 'var(--small-BorderRadius)'
- resizer.style.borderBottom = 'none'
- resizer.style.opacity = '0.5'
- resizer.innerHTML = chevronSvg
- resizer.onpointerenter = () => {
- resizer.style.opacity = '1'
- }
- resizer.onpointerleave = () => {
- resizer.style.opacity = '0.5'
- }
- resizer.onpointerdown = (e: PointerEvent): void => {
- e.preventDefault()
- resizer.setPointerCapture(e.pointerId)
- const { offsetHeight } = dom
- const startY = e.clientY - offsetHeight
- let height = node.attrs.height ?? defaultHeight
- const onPointerMove = (e: PointerEvent): void => {
- e.preventDefault()
- height = Math.max(minHeight, e.clientY - startY)
- height = Math.min(maxHeight, height)
- dom.style.height = `${height}px`
- }
- const onPointerUp = (e: PointerEvent): void => {
- e.preventDefault()
- resizer.releasePointerCapture(e.pointerId)
- if (typeof getPos === 'function') {
- const tr = this.editor.state.tr.setNodeMarkup(getPos(), undefined, { ...node.attrs, height })
- this.editor.view.dispatch(tr)
- }
- dom.removeEventListener('pointermove', onPointerMove)
- dom.removeEventListener('pointerup', onPointerUp)
- }
- dom.addEventListener('pointermove', onPointerMove)
- dom.addEventListener('pointerup', onPointerUp)
- }
- dom.appendChild(resizer)
-
- return {
- dom,
- selectNode: () => {
- dom.style.border = selectedBorder
- button.style.visibility = 'visible'
- resizer.style.visibility = 'visible'
- },
- deselectNode: () => {
- dom.style.border = normalBorder
- button.style.visibility = 'hidden'
- resizer.style.visibility = 'hidden'
- },
- destroy: () => {
- board.commands.unobserve(listenSavedCommands)
- board.props.unobserve(listenSavedProps)
- }
- }
- }
+ })
}
})