Skip to content

Commit

Permalink
Enhanced drawing overlay for screenshots (#7231)
Browse files Browse the repository at this point in the history
Signed-off-by: Nikolay Chunosov <[email protected]>
  • Loading branch information
Chunosov authored Nov 26, 2024
1 parent aea704f commit 27547e5
Show file tree
Hide file tree
Showing 26 changed files with 284 additions and 96 deletions.
4 changes: 4 additions & 0 deletions models/attachment/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,10 @@ export function createModel (builder: Builder): void {
{ _class: 1 }
]
})

builder.mixin(attachment.class.Drawing, core.class.Class, view.mixin.ObjectPresenter, {
presenter: attachment.component.DrawingPresenter
})
}

export default attachment
3 changes: 2 additions & 1 deletion packages/presentation/lang/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"FailedToPreview": "Náhled se nezdařil",
"ContentType": "Typ obsahu",
"ContentTypeNotSupported": "Náhled není dostupný pro tento typ obsahu",
"StartDrawing": "Načmárejte"
"StartDrawing": "Načmárejte",
"DrawingHistory": "Čmárání historie"
},
"status": {
"FileTooLarge": "Soubor je příliš velký"
Expand Down
3 changes: 2 additions & 1 deletion packages/presentation/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"FailedToPreview": "Failed to preview",
"ContentType": "Content type",
"ContentTypeNotSupported": "Preview is not available for this content type",
"StartDrawing": "Scribble over"
"StartDrawing": "Scribble over",
"DrawingHistory": "Scribble history"
},
"status": {
"FileTooLarge": "File too large"
Expand Down
3 changes: 2 additions & 1 deletion packages/presentation/lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"FailedToPreview": "Error al previsualizar",
"ContentType": "Tipo de contenido",
"ContentTypeNotSupported": "La vista previa no está disponible para este tipo de contenido",
"StartDrawing": "Garabatear encima"
"StartDrawing": "Garabatear encima",
"DrawingHistory": "Historia de garabatos"
},
"status": {
"FileTooLarge": "Archivo demasiado grande"
Expand Down
3 changes: 2 additions & 1 deletion packages/presentation/lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"FailedToPreview": "Échec de l'aperçu",
"ContentType": "Type de contenu",
"ContentTypeNotSupported": "L'aperçu n'est pas disponible pour ce type de contenu",
"StartDrawing": "Gribouiller dessus"
"StartDrawing": "Gribouiller dessus",
"DrawingHistory": "Histoire de gribouillage"
},
"status": {
"FileTooLarge": "Fichier trop volumineux"
Expand Down
3 changes: 2 additions & 1 deletion packages/presentation/lang/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"FailedToPreview": "Impossibile mostrare l'anteprima",
"ContentType": "Tipo di contenuto",
"ContentTypeNotSupported": "Anteprima non disponibile per questo tipo di contenuto",
"StartDrawing": "Scarabocchiare sopra"
"StartDrawing": "Scarabocchiare sopra",
"DrawingHistory": "Scarabocchiare la storia"
},
"status": {
"FileTooLarge": "File troppo grande"
Expand Down
3 changes: 2 additions & 1 deletion packages/presentation/lang/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"FailedToPreview": "Falha ao pré-visualizar",
"ContentType": "Tipo de conteúdo",
"ContentTypeNotSupported": "A visualização não está disponível para este tipo de conteúdo",
"StartDrawing": "Scarabocchiare sopra"
"StartDrawing": "Scarabocchiare sopra",
"DrawingHistory": "História de rabiscos"
},
"status": {
"FileTooLarge": "Ficheiro demasiado grande"
Expand Down
3 changes: 2 additions & 1 deletion packages/presentation/lang/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"FailedToPreview": "Ошибка предпросмотра",
"ContentType": "Тип контента",
"ContentTypeNotSupported": "Предварительный просмотр недоступен для этого типа контента",
"StartDrawing": "Сделать набросок"
"StartDrawing": "Сделать набросок",
"DrawingHistory": "История набросков"
},
"status": {
"FileTooLarge": "Файл слишком большой"
Expand Down
3 changes: 2 additions & 1 deletion packages/presentation/lang/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"FailedToPreview": "预览失败",
"ContentType": "内容类型",
"ContentTypeNotSupported": "此內容類型無法預覽",
"StartDrawing": "随意涂鸦"
"StartDrawing": "随意涂鸦",
"DrawingHistory": "涂鸦的历史"
},
"status": {
"FileTooLarge": "文件太大"
Expand Down
31 changes: 28 additions & 3 deletions packages/presentation/src/components/DocPopup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
-->
<script lang="ts">
import { getObjectValue, type Class, type Doc, type Ref } from '@hcengineering/core'
import type { IntlString } from '@hcengineering/platform'
import { getResource, type IntlString } from '@hcengineering/platform'
import {
AnySvelteComponent,
Button,
EditWithIcon,
FocusHandler,
Expand All @@ -31,6 +32,7 @@
showPopup,
tooltip
} from '@hcengineering/ui'
import view from '@hcengineering/view'
import { createEventDispatcher } from 'svelte'
import presentation from '..'
import { ObjectCreate } from '../types'
Expand All @@ -47,7 +49,7 @@
export let placeholder: IntlString = presentation.string.Search
export let selectedObjects: Ref<Doc>[] = []
export let shadows: boolean = true
export let width: 'medium' | 'large' | 'full' = 'medium'
export let width: 'medium' | 'large' | 'full' | 'auto' = 'medium'
export let size: 'small' | 'medium' | 'large' = 'large'
export let noSearchField: boolean = false
Expand All @@ -59,7 +61,7 @@
export let created: Doc[] = []
export let embedded: boolean = false
export let loading: boolean = false
export let type: 'text' | 'object' = 'text'
export let type: 'text' | 'object' | 'presenter' = 'text'
let search: string = ''
Expand All @@ -71,6 +73,11 @@
created.length > 0 ||
objects.map((it) => getObjectValue(groupBy, it)).filter((it, index, arr) => arr.indexOf(it) === index).length > 1
let presenter: AnySvelteComponent | undefined = undefined
$: if (type === 'presenter') {
findObjectPresenter(_class)
}
const checkSelected = (item?: Doc): void => {
if (item === undefined) {
return
Expand Down Expand Up @@ -154,6 +161,19 @@
}
return getObjectValue(groupBy, toAny(doc))
}
function findObjectPresenter (_class: Ref<Class<Doc>>): void {
const presenterMixin = client.getHierarchy().classHierarchyMixin(_class, view.mixin.ObjectPresenter)
if (presenterMixin?.presenter !== undefined) {
getResource(presenterMixin.presenter)
.then((result) => {
presenter = result
})
.catch((err) => {
console.error('Failed to find presenter for class ' + _class, err)
})
}
}
</script>

<FocusHandler {manager} />
Expand All @@ -164,6 +184,7 @@
class:full-width={width === 'full'}
class:plainContainer={!shadows}
class:width-40={width === 'large'}
class:auto={width === 'auto'}
class:embedded
on:keydown={onKeydown}
use:resizeObserver={() => {
Expand Down Expand Up @@ -229,6 +250,10 @@
<span class="label" class:disabled={readonly || isDeselectDisabled || loading}>
<slot name="item" item={obj} />
</span>
{:else if type === 'presenter'}
{#if presenter !== undefined}
<svelte:component this={presenter} value={obj} />
{/if}
{:else}
<slot name="item" item={obj} />
{/if}
Expand Down
63 changes: 56 additions & 7 deletions packages/presentation/src/components/DrawingBoard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,30 @@
-->
<script lang="ts">
import { Button, IconDelete, IconEdit, resizeObserver } from '@hcengineering/ui'
import { onDestroy } from 'svelte'
import { drawing, type DrawingData, type DrawingTool } from '../drawing'
import IconEraser from './icons/Eraser.svelte'
export let active = false
export let readonly = false
export let readonly = true
export let imageWidth: number | undefined
export let imageHeight: number | undefined
export let drawingData: DrawingData
export let saveDrawing: (data: any) => Promise<void>
export let drawings: DrawingData[]
export let createDrawing: (data: any) => Promise<void>
let drawingTool: DrawingTool = 'pen'
let penColor = 'blue'
const penColors = ['red', 'green', 'blue', 'white', 'black']
let drawingData: DrawingData | undefined
let board: HTMLDivElement
let toolbar: HTMLDivElement
let toolbarInside = false
let oldReadonly: boolean
let oldDrawings: DrawingData[]
let modified = false
$: updateToolbarPosition(readonly, board, toolbar)
$: updateEditableState(drawings, readonly)
function updateToolbarPosition (readonly: boolean, board: HTMLDivElement, toolbar: HTMLDivElement): void {
if (!readonly && board?.offsetTop !== undefined && toolbar?.clientHeight !== undefined) {
Expand All @@ -41,9 +46,47 @@
toolbarInside = board.offsetTop <= toolbar.clientHeight * 3
}
}
function updateEditableState (drawings: DrawingData[], readonly: boolean): void {
if (readonly !== oldReadonly || drawings !== oldDrawings) {
if (drawings !== undefined) {
if (readonly) {
if (modified && drawingData !== undefined) {
createDrawing(drawingData).catch((error) => {
console.error('Failed to save drawing', error)
})
}
drawingData = drawings[0]
modified = false
} else {
if (drawingData === undefined) {
drawingData = {}
} else {
// Edit current content as a new drawing
drawingData = {
content: drawingData.content
}
}
modified = false
}
} else {
drawingData = undefined
}
oldDrawings = drawings
oldReadonly = readonly
}
}
onDestroy(() => {
if (modified && drawingData !== undefined) {
createDrawing(drawingData).catch((error) => {
console.error('Failed to save drawing', error)
})
}
})
</script>

{#if active}
{#if active && drawingData !== undefined}
<div
{...$$restProps}
style:position="relative"
Expand All @@ -56,9 +99,14 @@
imageWidth,
imageHeight,
drawingData,
saveDrawing,
drawingTool,
penColor
penColor,
changed: (content) => {
modified = true
if (drawingData !== undefined) {
drawingData.content = content
}
}
}}
>
{#if !readonly}
Expand All @@ -68,6 +116,7 @@
kind="icon"
on:click={() => {
drawingData = {}
modified = true
}}
/>
<div class="divider buttons-divider" />
Expand Down
Loading

0 comments on commit 27547e5

Please sign in to comment.