mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-28 20:45:00 +02:00
Init poll applet (#9586)
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
@@ -18,17 +18,21 @@
|
||||
import cardPlugin from '@hcengineering/card'
|
||||
import { getCurrentAccount } from '@hcengineering/core'
|
||||
import { AttachmentPreview, LinkPreview } from '@hcengineering/attachment-resources'
|
||||
import { LinkPreviewID, Message, MessageType } from '@hcengineering/communication-types'
|
||||
import { AttachmentID, Message, MessageType } from '@hcengineering/communication-types'
|
||||
import { getResource } from '@hcengineering/platform'
|
||||
import { isAppletAttachment, isBlobAttachment, isLinkPreviewAttachment } from '@hcengineering/communication-shared'
|
||||
import { Component } from '@hcengineering/ui'
|
||||
|
||||
import ReactionsList from '../ReactionsList.svelte'
|
||||
import MessageThread from '../thread/Thread.svelte'
|
||||
import { toggleReaction } from '../../utils'
|
||||
import communication from '../../plugin'
|
||||
|
||||
export let message: Message
|
||||
|
||||
const me = getCurrentAccount()
|
||||
const communicationClient = getCommunicationClient()
|
||||
const client = getClient()
|
||||
|
||||
function canReply (): boolean {
|
||||
return message.type !== MessageType.Activity && message.extra?.threadRoot !== true
|
||||
@@ -53,49 +57,69 @@
|
||||
await r(_id, c)
|
||||
}
|
||||
|
||||
async function removeLinkPreview (id: LinkPreviewID): Promise<void> {
|
||||
await communicationClient.linkPreviewPatch(message.cardId, message.id, {
|
||||
detach: [id]
|
||||
async function removeLinkPreview (id: AttachmentID): Promise<void> {
|
||||
await communicationClient.attachmentPatch(message.cardId, message.id, {
|
||||
remove: [id]
|
||||
})
|
||||
}
|
||||
|
||||
const appletsModels = client.getModel().findAllSync(communication.class.Applet, {})
|
||||
$: blobs = message.attachments.filter(isBlobAttachment) ?? []
|
||||
$: links = message.attachments.filter(isLinkPreviewAttachment) ?? []
|
||||
$: applets = message.attachments.filter(isAppletAttachment) ?? []
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
{#if message.blobs.length > 0 && !message.removed}
|
||||
{#if applets.length > 0 && !message.removed}
|
||||
<div class="message__applets">
|
||||
{#each applets as applet (applet.id)}
|
||||
{@const appletModel = appletsModels.find((it) => it.type === applet.type)}
|
||||
{#if appletModel}
|
||||
<Component
|
||||
is={appletModel.component}
|
||||
props={{
|
||||
applet: appletModel,
|
||||
attachment: applet
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if blobs.length > 0 && !message.removed}
|
||||
<div class="message__files">
|
||||
{#each message.blobs as blob (blob.blobId)}
|
||||
{#each blobs as blob (blob.id)}
|
||||
<AttachmentPreview
|
||||
value={{
|
||||
file: blob.blobId,
|
||||
type: blob.mimeType,
|
||||
name: blob.fileName,
|
||||
size: blob.size,
|
||||
metadata: blob.metadata
|
||||
file: blob.params.blobId,
|
||||
type: blob.params.mimeType,
|
||||
name: blob.params.fileName,
|
||||
size: blob.params.size,
|
||||
metadata: blob.params.metadata
|
||||
}}
|
||||
imageSize="x-large"
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{#if (message.linkPreviews ?? []).length > 0 && !message.removed}
|
||||
{#if links.length > 0 && !message.removed}
|
||||
<div class="message__links">
|
||||
{#each message.linkPreviews as link (link.id)}
|
||||
{#each links as link (link.id)}
|
||||
<LinkPreview
|
||||
isOwn={me.socialIds.includes(message.creator)}
|
||||
on:delete={() => {
|
||||
void removeLinkPreview(link.id)
|
||||
}}
|
||||
linkPreview={{
|
||||
url: link.url,
|
||||
host: link.host,
|
||||
title: link.title,
|
||||
description: link.description,
|
||||
hostname: link.siteName,
|
||||
image: link.previewImage?.url,
|
||||
imageWidth: link.previewImage?.width,
|
||||
imageHeight: link.previewImage?.height,
|
||||
icon: link.iconUrl
|
||||
url: link.params.url,
|
||||
host: link.params.host,
|
||||
title: link.params.title,
|
||||
description: link.params.description,
|
||||
hostname: link.params.siteName,
|
||||
image: link.params.previewImage?.url,
|
||||
imageWidth: link.params.previewImage?.width,
|
||||
imageHeight: link.params.previewImage?.height,
|
||||
icon: link.params.iconUrl
|
||||
}}
|
||||
/>
|
||||
{/each}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import { Markup, RateLimiter, Ref } from '@hcengineering/core'
|
||||
import { generateId, Markup, RateLimiter, Ref } from '@hcengineering/core'
|
||||
import { tick, createEventDispatcher } from 'svelte'
|
||||
import {
|
||||
uploadFile,
|
||||
@@ -24,20 +24,30 @@
|
||||
getFileMetadata,
|
||||
isLinkPreviewEnabled
|
||||
} from '@hcengineering/presentation'
|
||||
import { Message, MessageID, BlobData, LinkPreviewData } from '@hcengineering/communication-types'
|
||||
import {
|
||||
Message,
|
||||
MessageID,
|
||||
LinkPreviewParams,
|
||||
BlobParams,
|
||||
AttachmentID,
|
||||
linkPreviewType,
|
||||
BlobAttachment,
|
||||
AppletParams
|
||||
} from '@hcengineering/communication-types'
|
||||
import { AttachmentPresenter, LinkPreviewCard } from '@hcengineering/attachment-resources'
|
||||
import { areEqualMarkups, isEmptyMarkup } from '@hcengineering/text'
|
||||
import { updateMyPresence } from '@hcengineering/presence-resources'
|
||||
import { ThrottledCaller } from '@hcengineering/ui'
|
||||
import { Component, showPopup, ThrottledCaller } from '@hcengineering/ui'
|
||||
import { getCurrentEmployee } from '@hcengineering/contact'
|
||||
import { Card } from '@hcengineering/card'
|
||||
import { setPlatformStatus, unknownError } from '@hcengineering/platform'
|
||||
import { getResource, setPlatformStatus, unknownError } from '@hcengineering/platform'
|
||||
import { isAppletAttachment, isBlobAttachment, isLinkPreviewAttachment } from '@hcengineering/communication-shared'
|
||||
|
||||
import TextInput from '../TextInput.svelte'
|
||||
import IconAttach from '../icons/Attach.svelte'
|
||||
import { defaultMessageInputActions, toMarkdown, toMarkup, loadLinkPreviewData } from '../../utils'
|
||||
import { defaultMessageInputActions, toMarkdown, toMarkup, loadLinkPreviewParams } from '../../utils'
|
||||
import communication from '../../plugin'
|
||||
import { type TextInputAction, type PresenceTyping, MessageDraft } from '../../types'
|
||||
import { type TextInputAction, type PresenceTyping, MessageDraft, AppletDraft } from '../../types'
|
||||
import TypingPresenter from '../TypingPresenter.svelte'
|
||||
import { getDraft, messageToDraft, saveDraft, getEmptyDraft, removeDraft } from '../../draft'
|
||||
|
||||
@@ -45,7 +55,7 @@
|
||||
export let message: Message | undefined = undefined
|
||||
export let title: string = ''
|
||||
export let onCancel: (() => void) | undefined = undefined
|
||||
export let onSubmit: ((markdown: string, blobs: BlobData[]) => Promise<void>) | undefined = undefined
|
||||
export let onSubmit: ((markdown: string, blobs: BlobParams[]) => Promise<void>) | undefined = undefined
|
||||
|
||||
const throttle = new ThrottledCaller(500)
|
||||
const dispatch = createEventDispatcher()
|
||||
@@ -55,7 +65,7 @@
|
||||
|
||||
const maxLinkPreviewCount = 4
|
||||
const previewUrls = new Map<string, boolean>()
|
||||
const linksData = new Map<string, LinkPreviewData | null>()
|
||||
const linksData = new Map<string, LinkPreviewParams | null>()
|
||||
|
||||
let prevCard: Ref<Card> | undefined = card._id
|
||||
let prevMessage: MessageID | undefined = message?.id
|
||||
@@ -99,6 +109,7 @@
|
||||
const markup = event.detail
|
||||
const blobsToLoad = draft.blobs
|
||||
const linksToLoad = draft.links
|
||||
const appletsToLoad = draft.applets
|
||||
const urlsToLoad = Array.from(previewUrls.keys()).filter((it) => previewUrls.get(it) === true)
|
||||
|
||||
draft = getEmptyDraft()
|
||||
@@ -115,31 +126,69 @@
|
||||
}
|
||||
|
||||
if (message === undefined) {
|
||||
await createMessage(markdown, blobsToLoad, linksToLoad, urlsToLoad)
|
||||
await createMessage(markdown, blobsToLoad, linksToLoad, urlsToLoad, appletsToLoad)
|
||||
dispatch('sent')
|
||||
} else {
|
||||
await editMessage(message, markdown, blobsToLoad, linksToLoad)
|
||||
await editMessage(message, markdown, blobsToLoad, linksToLoad, appletsToLoad)
|
||||
}
|
||||
}
|
||||
|
||||
async function attachApplets (messageId: MessageID, appletDrafts: AppletDraft[]): Promise<void> {
|
||||
if (appletDrafts.length === 0) return
|
||||
const toAttach: AppletDraft[] = []
|
||||
for (const appletDraft of appletDrafts) {
|
||||
try {
|
||||
const ap = applets.find((it) => it._id === appletDraft.appletId)
|
||||
if (ap?.createFn == null) {
|
||||
toAttach.push(appletDraft)
|
||||
continue
|
||||
}
|
||||
const r = await getResource(ap.createFn)
|
||||
await r(card, messageId, appletDraft.params)
|
||||
toAttach.push(appletDraft)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
if (toAttach.length > 0) {
|
||||
void communicationClient.attachmentPatch<AppletParams>(card._id, messageId, {
|
||||
add: toAttach.map((it) => ({
|
||||
type: it.type,
|
||||
params: it.params
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function createMessage (
|
||||
markdown: string,
|
||||
blobs: BlobData[],
|
||||
links: LinkPreviewData[],
|
||||
urlsToLoad: string[]
|
||||
blobs: BlobParams[],
|
||||
links: LinkPreviewParams[],
|
||||
urlsToLoad: string[],
|
||||
appletDrafts: AppletDraft[]
|
||||
): Promise<void> {
|
||||
const { messageId } = await communicationClient.createMessage(card._id, card._class, markdown)
|
||||
void client.update(card, {}, false, Date.now())
|
||||
|
||||
void attachApplets(messageId, appletDrafts)
|
||||
|
||||
if (blobs.length > 0) {
|
||||
void communicationClient.blobPatch(card._id, messageId, {
|
||||
attach: blobs
|
||||
void communicationClient.attachmentPatch<BlobParams>(card._id, messageId, {
|
||||
add: blobs.map((it) => ({
|
||||
id: it.blobId as any as AttachmentID,
|
||||
type: it.mimeType,
|
||||
params: it
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
if (links.length > 0) {
|
||||
void communicationClient.linkPreviewPatch(card._id, messageId, {
|
||||
attach: links
|
||||
void communicationClient.attachmentPatch<LinkPreviewParams>(card._id, messageId, {
|
||||
add: links.map((it) => ({
|
||||
type: linkPreviewType,
|
||||
params: it
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -147,10 +196,15 @@
|
||||
if (links.some((it) => it.url === url)) continue
|
||||
const fetchedData = linksData.get(url)
|
||||
if (fetchedData === null) continue
|
||||
const data = fetchedData ?? (await loadLinkPreviewData(url))
|
||||
if (data === undefined) continue
|
||||
void communicationClient.linkPreviewPatch(card._id, messageId, {
|
||||
attach: [data]
|
||||
const params = fetchedData ?? (await loadLinkPreviewParams(url))
|
||||
if (params === undefined) continue
|
||||
void communicationClient.attachmentPatch<LinkPreviewParams>(card._id, messageId, {
|
||||
add: [
|
||||
{
|
||||
type: linkPreviewType,
|
||||
params
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -158,31 +212,62 @@
|
||||
async function editMessage (
|
||||
message: Message,
|
||||
markdown: string,
|
||||
blobs: BlobData[],
|
||||
links: LinkPreviewData[]
|
||||
blobs: BlobParams[],
|
||||
links: LinkPreviewParams[],
|
||||
appletDrafts: AppletDraft[]
|
||||
): Promise<void> {
|
||||
await communicationClient.updateMessage(card._id, message.id, markdown)
|
||||
|
||||
const attachBlobs = blobs.filter((it) => !message.blobs.some((b) => b.blobId === it.blobId))
|
||||
const attachBlobs = blobs.filter(
|
||||
(b) => !message.attachments.some((it) => isBlobAttachment(it) && it.params.blobId === b.blobId)
|
||||
)
|
||||
|
||||
void attachApplets(
|
||||
message.id,
|
||||
appletDrafts.filter((a) => !message.attachments.some((it) => it.id === a.id))
|
||||
)
|
||||
|
||||
if (attachBlobs.length > 0) {
|
||||
void communicationClient.blobPatch(card._id, message.id, {
|
||||
attach: attachBlobs
|
||||
void communicationClient.attachmentPatch<BlobParams>(card._id, message.id, {
|
||||
add: attachBlobs.map((it) => ({
|
||||
id: it.blobId as any as AttachmentID,
|
||||
type: it.mimeType,
|
||||
params: it
|
||||
}))
|
||||
})
|
||||
}
|
||||
const detachBlobs = message.blobs.filter((it) => !blobs.some((b) => b.blobId === it.blobId))
|
||||
|
||||
const detachBlobs = message.attachments.filter(
|
||||
(it) => isBlobAttachment(it) && !blobs.some((b) => b.blobId === it.params.blobId)
|
||||
) as BlobAttachment[]
|
||||
if (detachBlobs.length > 0) {
|
||||
detachBlobs.forEach((it) => {
|
||||
void deleteFile(it.blobId)
|
||||
void deleteFile(it.params.blobId)
|
||||
})
|
||||
void communicationClient.blobPatch(card._id, message.id, {
|
||||
detach: detachBlobs.map((it) => it.blobId)
|
||||
void communicationClient.attachmentPatch(card._id, message.id, {
|
||||
remove: detachBlobs.map((it) => it.id)
|
||||
})
|
||||
}
|
||||
const attachLinks = links.filter((it) => !message.linkPreviews.some((b) => b.url === it.url))
|
||||
|
||||
void communicationClient.linkPreviewPatch(card._id, message.id, {
|
||||
attach: attachLinks
|
||||
const detachApplets = message.attachments.filter(
|
||||
(it) => isAppletAttachment(it) && !appletDrafts.some((a) => a.id === it.id)
|
||||
)
|
||||
|
||||
if (detachApplets.length > 0) {
|
||||
void communicationClient.attachmentPatch(card._id, message.id, {
|
||||
remove: detachApplets.map((it) => it.id)
|
||||
})
|
||||
}
|
||||
|
||||
const attachLinks = links.filter(
|
||||
(l) => !message.attachments.some((it) => isLinkPreviewAttachment(it) && it.params.url === l.url)
|
||||
)
|
||||
|
||||
void communicationClient.attachmentPatch(card._id, message.id, {
|
||||
add: attachLinks.map((it) => ({
|
||||
type: linkPreviewType,
|
||||
params: it
|
||||
}))
|
||||
})
|
||||
|
||||
dispatch('edited')
|
||||
@@ -237,7 +322,8 @@
|
||||
async function handleCancel (): Promise<void> {
|
||||
onCancel?.()
|
||||
for (const blob of draft.blobs) {
|
||||
const fromMessage = message?.blobs.some((it) => it.blobId === blob.blobId)
|
||||
const fromMessage =
|
||||
message?.attachments.some((it) => isBlobAttachment(it) && it.params.blobId === blob.blobId) ?? false
|
||||
if (!fromMessage) {
|
||||
void deleteFile(blob.blobId)
|
||||
}
|
||||
@@ -342,7 +428,7 @@
|
||||
|
||||
for (const url of urls) {
|
||||
try {
|
||||
const data = linksData.get(url) ?? (await loadLinkPreviewData(url))
|
||||
const data = linksData.get(url) ?? (await loadLinkPreviewParams(url))
|
||||
linksData.set(url, data ?? null)
|
||||
if (data === undefined || !previewUrls.has(url)) continue
|
||||
if (draftId !== draft._id) return
|
||||
@@ -376,17 +462,41 @@
|
||||
}
|
||||
|
||||
function isEmptyDraft (): boolean {
|
||||
return isEmptyMarkup(draft.content) && draft.blobs.length === 0
|
||||
return isEmptyMarkup(draft.content) && draft.blobs.length === 0 && draft.applets.length === 0
|
||||
}
|
||||
|
||||
function hasChanges (blobs: BlobData[], message: Message | undefined): boolean {
|
||||
function hasChanges (blobs: BlobParams[], message: Message | undefined, appletDrafts: any[]): boolean {
|
||||
if (isEmptyDraft()) return false
|
||||
if (message === undefined) return blobs.length > 0 || !isEmptyMarkup(draft.content)
|
||||
if (message.blobs.length !== blobs.length) return true
|
||||
if (message.blobs.some((it) => !blobs.some((f) => f.blobId === it.blobId))) return true
|
||||
if (message === undefined) return blobs.length > 0 || !isEmptyMarkup(draft.content) || appletDrafts.length > 0
|
||||
const messageBlobs = message?.attachments.filter(isBlobAttachment) ?? []
|
||||
const messageApplets = message?.attachments.filter(isAppletAttachment) ?? []
|
||||
|
||||
if (messageBlobs.length !== blobs.length) return true
|
||||
if (messageBlobs.some((it) => !blobs.some((b) => b.blobId === it.params.blobId))) return true
|
||||
if (messageApplets.length !== appletDrafts.length) return true
|
||||
if (messageApplets.some((it) => !appletDrafts.some((a) => a.id === it.id))) return true
|
||||
|
||||
return !areEqualMarkups(draft.content, toMarkup(message.content))
|
||||
}
|
||||
|
||||
const applets = client.getModel().findAllSync(communication.class.Applet, {})
|
||||
const appletActions: TextInputAction[] = applets.map((applet) => {
|
||||
return {
|
||||
label: applet.label,
|
||||
icon: applet.icon,
|
||||
action: () => {
|
||||
showPopup(applet.createComponent, { applet }, 'center', (result) => {
|
||||
if (result != null) {
|
||||
draft = {
|
||||
...draft,
|
||||
applets: [...draft.applets, { id: generateId(), type: applet.type, appletId: applet._id, params: result }]
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
order: 99999
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
@@ -413,16 +523,50 @@
|
||||
placeholder={title !== '' ? communication.string.MessageIn : undefined}
|
||||
placeholderParams={title !== '' ? { title } : undefined}
|
||||
loading={progress}
|
||||
hasChanges={hasChanges(draft.blobs, message)}
|
||||
actions={[...defaultMessageInputActions, attachAction]}
|
||||
hasChanges={hasChanges(draft.blobs, message, draft.applets)}
|
||||
actions={[...defaultMessageInputActions, attachAction, ...appletActions]}
|
||||
on:submit={handleSubmit}
|
||||
on:update={onUpdate}
|
||||
onCancel={onCancel ? handleCancel : undefined}
|
||||
onPaste={pasteAction}
|
||||
>
|
||||
<div slot="header" class="header">
|
||||
{#if draft.blobs.length > 0 || draft.links.length > 0}
|
||||
{#if draft.blobs.length > 0 || draft.links.length > 0 || draft.applets.length > 0}
|
||||
<div class="flex-row-center files-list scroll-divider-color flex-gap-2 mt-2">
|
||||
{#each draft.applets as appletDraft}
|
||||
{@const applet = applets.find((it) => it._id === appletDraft.appletId)}
|
||||
{#if applet}
|
||||
<Component
|
||||
is={applet.previewComponent}
|
||||
props={{
|
||||
applet,
|
||||
params: appletDraft.params,
|
||||
editing: message !== undefined && message.attachments.some((it) => it.id === appletDraft.id)
|
||||
}}
|
||||
on:change={() => {
|
||||
showPopup(applet.createComponent, { applet, params: appletDraft.params }, 'center', (result) => {
|
||||
if (result != null) {
|
||||
draft = {
|
||||
...draft,
|
||||
applets: draft.applets.map((it) => {
|
||||
if (it.id === appletDraft.id) {
|
||||
return { ...it, params: result }
|
||||
}
|
||||
return it
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}}
|
||||
on:delete={() => {
|
||||
draft = {
|
||||
...draft,
|
||||
applets: draft.applets.filter((it) => it.id !== appletDraft.id)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
{#each draft.blobs as attachedBlob (attachedBlob.blobId)}
|
||||
<div class="item flex">
|
||||
<AttachmentPresenter
|
||||
@@ -442,7 +586,11 @@
|
||||
blobs: draft.blobs.filter((it) => it.blobId !== attachedBlob.blobId)
|
||||
}
|
||||
|
||||
if (!message?.blobs?.some((it) => it.blobId === attachedBlob.blobId)) {
|
||||
if (
|
||||
!message?.attachments?.some(
|
||||
(it) => isBlobAttachment(it) && it.params.blobId === attachedBlob.blobId
|
||||
)
|
||||
) {
|
||||
void deleteFile(attachedBlob.blobId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
} from '../../stores'
|
||||
import { getMessageActions } from '../../actions'
|
||||
import communication from '../../plugin'
|
||||
import { isBlobAttachment } from '@hcengineering/communication-shared'
|
||||
import { getCommunicationClient } from '@hcengineering/presentation'
|
||||
|
||||
export let card: Card
|
||||
export let message: Message
|
||||
|
||||
+25
-9
@@ -15,23 +15,39 @@
|
||||
<script lang="ts">
|
||||
import { AttributeModel } from '@hcengineering/view'
|
||||
import { ActivityAttributeUpdate } from '@hcengineering/communication-types'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { Class, Ref } from '@hcengineering/core'
|
||||
import { Card } from '@hcengineering/card'
|
||||
import { Component } from '@hcengineering/ui'
|
||||
|
||||
import ActivitySetAttributesViewer from './ActivitySetAttributeViewer.svelte'
|
||||
import ActivityAddAttributeViewer from './ActivityAddAttributeViewer.svelte'
|
||||
import ActivityRemoveAttributeViewer from './ActivityRemoveAttributeViewer.svelte'
|
||||
import communication from '../../../plugin'
|
||||
|
||||
export let model: AttributeModel
|
||||
export let model: AttributeModel | undefined
|
||||
export let update: ActivityAttributeUpdate
|
||||
export let cardType: Ref<Class<Card>>
|
||||
|
||||
const client = getClient()
|
||||
$: customPresenter = client.getModel().findAllSync(communication.class.CustomActivityPresenter, {
|
||||
attribute: update.attrKey,
|
||||
type: cardType
|
||||
})[0]
|
||||
</script>
|
||||
|
||||
{#if update?.set !== undefined}
|
||||
<ActivitySetAttributesViewer {model} value={update.set} />
|
||||
{/if}
|
||||
{#if customPresenter}
|
||||
<Component is={customPresenter.component} props={{ update }} />
|
||||
{:else}
|
||||
{#if update?.set !== undefined && model}
|
||||
<ActivitySetAttributesViewer {model} value={update.set} />
|
||||
{/if}
|
||||
|
||||
{#if (update.added?.length ?? 0) > 0}
|
||||
<ActivityAddAttributeViewer {model} value={update.added ?? []} />
|
||||
{/if}
|
||||
{#if model && (update.added?.length ?? 0) > 0}
|
||||
<ActivityAddAttributeViewer {model} value={update.added ?? []} />
|
||||
{/if}
|
||||
|
||||
{#if (update.removed?.length ?? 0) > 0}
|
||||
<ActivityRemoveAttributeViewer {model} value={update.removed ?? []} />
|
||||
{#if model && (update.removed?.length ?? 0) > 0}
|
||||
<ActivityRemoveAttributeViewer {model} value={update.removed ?? []} />
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
+2
-2
@@ -30,8 +30,8 @@
|
||||
export let author: Person | undefined
|
||||
</script>
|
||||
|
||||
{#if update.type === ActivityUpdateType.Attribute && model}
|
||||
<ActivityUpdateAttributeViewer {model} {update} />
|
||||
{#if update.type === ActivityUpdateType.Attribute}
|
||||
<ActivityUpdateAttributeViewer {model} {update} cardType={card._class} />
|
||||
{:else if update.type === ActivityUpdateType.Tag}
|
||||
<ActivityUpdateTagViewer {update} {content} />
|
||||
{:else if update.type === ActivityUpdateType.Collaborators}
|
||||
|
||||
Reference in New Issue
Block a user