From dd70ea43ffce7a051836d999303bec77e8e357b1 Mon Sep 17 00:00:00 2001 From: Alexey Zinoviev Date: Tue, 9 Apr 2024 16:25:38 +0400 Subject: [PATCH] UBERF-6353: Extensible preview (#5264) --- models/attachment/package.json | 3 +- models/attachment/src/index.ts | 57 ++++++++++++- models/attachment/src/plugin.ts | 3 +- .../src/components/PDFViewer.svelte | 22 +++-- plugins/attachment-assets/lang/en.json | 3 +- plugins/attachment-assets/lang/es.json | 3 +- plugins/attachment-assets/lang/pt.json | 3 +- plugins/attachment-assets/lang/ru.json | 3 +- .../src/components/AttachmentActions.svelte | 45 ++++++++-- .../src/components/AttachmentPresenter.svelte | 38 +++++---- plugins/attachment-resources/src/index.ts | 7 +- plugins/attachment-resources/src/utils.ts | 83 ++++++++++++++++++- plugins/attachment/package.json | 3 +- plugins/attachment/src/index.ts | 28 ++++++- 14 files changed, 256 insertions(+), 45 deletions(-) diff --git a/models/attachment/package.json b/models/attachment/package.json index 78693f45be..8eeaa666ad 100644 --- a/models/attachment/package.json +++ b/models/attachment/package.json @@ -38,6 +38,7 @@ "@hcengineering/model-view": "^0.6.0", "@hcengineering/platform": "^0.6.9", "@hcengineering/ui": "^0.6.11", - "@hcengineering/view": "^0.6.9" + "@hcengineering/view": "^0.6.9", + "@hcengineering/model-presentation": "^0.6.0" } } diff --git a/models/attachment/src/index.ts b/models/attachment/src/index.ts index 66807a0b57..054f05bdbc 100644 --- a/models/attachment/src/index.ts +++ b/models/attachment/src/index.ts @@ -14,7 +14,14 @@ // import activity from '@hcengineering/activity' -import type { Attachment, AttachmentMetadata, Photo, SavedAttachments } from '@hcengineering/attachment' +import type { + Attachment, + AttachmentMetadata, + Photo, + SavedAttachments, + AttachmentPreviewExtension +} from '@hcengineering/attachment' +import presentation, { TComponentPointExtension } from '@hcengineering/model-presentation' import { type Domain, IndexKind, type Ref } from '@hcengineering/core' import { type Builder, @@ -31,6 +38,7 @@ import { import core, { TAttachedDoc } from '@hcengineering/model-core' import preference, { TPreference } from '@hcengineering/model-preference' import view, { createAction } from '@hcengineering/model-view' +import { type Resource } from '@hcengineering/platform' import attachment from './plugin' @@ -78,8 +86,17 @@ export class TSavedAttachments extends TPreference implements SavedAttachments { declare attachedTo: Ref } +@Model(attachment.class.AttachmentPreviewExtension, presentation.class.ComponentPointExtension) +export class TAttachmentPreviewExtension extends TComponentPointExtension implements AttachmentPreviewExtension { + @Prop(TypeString(), attachment.string.ContentType) + contentType!: string | string[] + + alignment?: string + availabilityChecker?: Resource<() => Promise> +} + export function createModel (builder: Builder): void { - builder.createModel(TAttachment, TPhoto, TSavedAttachments) + builder.createModel(TAttachment, TPhoto, TSavedAttachments, TAttachmentPreviewExtension) builder.mixin(attachment.class.Attachment, core.class.Class, view.mixin.ObjectPresenter, { presenter: attachment.component.AttachmentPresenter @@ -164,6 +181,42 @@ export function createModel (builder: Builder): void { attachment.category.Attachments ) + builder.createDoc( + attachment.class.AttachmentPreviewExtension, + core.space.Model, + { + contentType: 'image/*', + alignment: 'centered', + component: attachment.component.PDFViewer, + extension: attachment.extension.AttachmentPreview + }, + attachment.previewExtension.Image + ) + + builder.createDoc( + attachment.class.AttachmentPreviewExtension, + core.space.Model, + { + contentType: ['video/*', 'audio/*'], + alignment: 'float', + component: attachment.component.MediaViewer, + extension: attachment.extension.AttachmentPreview + }, + attachment.previewExtension.Media + ) + + builder.createDoc( + attachment.class.AttachmentPreviewExtension, + core.space.Model, + { + contentType: ['application/pdf', 'application/json', 'text/*'], + alignment: 'float', + component: attachment.component.PDFViewer, + extension: attachment.extension.AttachmentPreview + }, + attachment.previewExtension.PDF + ) + createAction(builder, { action: view.actionImpl.ShowEditor, actionProps: { diff --git a/models/attachment/src/plugin.ts b/models/attachment/src/plugin.ts index 18da210538..7370194f96 100644 --- a/models/attachment/src/plugin.ts +++ b/models/attachment/src/plugin.ts @@ -40,7 +40,8 @@ export default mergeIds(attachmentId, attachment, { PinAttachment: '' as IntlString, UnPinAttachment: '' as IntlString, FilterAttachments: '' as IntlString, - RemovedAttachment: '' as IntlString + RemovedAttachment: '' as IntlString, + ContentType: '' as IntlString }, ids: { TxAttachmentCreate: '' as Ref, diff --git a/packages/presentation/src/components/PDFViewer.svelte b/packages/presentation/src/components/PDFViewer.svelte index 4b5e3da591..6cb20468e2 100644 --- a/packages/presentation/src/components/PDFViewer.svelte +++ b/packages/presentation/src/components/PDFViewer.svelte @@ -29,6 +29,7 @@ export let showIcon = true export let fullSize = false export let isLoading = false + export let css: string | undefined = undefined const dispatch = createEventDispatcher() @@ -45,6 +46,19 @@ let download: HTMLAnchorElement $: src = file === undefined ? '' : getFileUrl(file, 'full', name) $: isImage = contentType !== undefined && contentType.startsWith('image/') + + let frame: HTMLIFrameElement | undefined = undefined + // eslint-disable-next-line @typescript-eslint/prefer-optional-chain + $: if (css !== undefined && frame !== undefined && frame !== null) { + frame.onload = () => { + const head = frame?.contentDocument?.querySelector('head') + + // eslint-disable-next-line @typescript-eslint/prefer-optional-chain + if (css !== undefined && head !== undefined && head !== null) { + head.appendChild(document.createElement('style')).textContent = css + } + } + } @@ -69,7 +83,7 @@ - {#if !isLoading && isImage && src !== ''} + {#if !isLoading && src !== ''}