From db10746bec23c724f0e4c07191be7e8793b73724 Mon Sep 17 00:00:00 2001 From: Andrey Sobolev Date: Mon, 23 Sep 2024 12:24:19 +0700 Subject: [PATCH 1/5] UBERF-8224: Fix undefined rejection exception (#6677) Signed-off-by: Andrey Sobolev --- services/github/pod-github/src/platform.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/services/github/pod-github/src/platform.ts b/services/github/pod-github/src/platform.ts index 626f1237fd..57091ea7d4 100644 --- a/services/github/pod-github/src/platform.ts +++ b/services/github/pod-github/src/platform.ts @@ -698,16 +698,16 @@ export class PlatformWorker { errors++ return } + if (workspaceInfo?.workspace === undefined) { + this.ctx.error('No workspace exists for workspaceId', { workspace }) + errors++ + return + } + if (workspaceInfo?.disabled === true) { + this.ctx.error('Workspace is disabled workspaceId', { workspace }) + return + } try { - if (workspaceInfo?.workspace === undefined) { - this.ctx.error('No workspace exists for workspaceId', { workspace }) - errors++ - return - } - if (workspaceInfo?.disabled === true) { - this.ctx.error('Workspace is disabled workspaceId', { workspace }) - return - } const branding = Object.values(this.brandingMap).find((b) => b.key === workspaceInfo?.branding) ?? null const workerCtx = this.ctx.newChild('worker', { workspace: workspaceInfo.workspace }, {}) From eef1bd2e0dc1d1d2f1a756d4f016fd82700ffb89 Mon Sep 17 00:00:00 2001 From: Kristina Date: Mon, 23 Sep 2024 09:56:45 +0400 Subject: [PATCH 2/5] Group activity by time in document sidebar and fix double show more (#6679) Signed-off-by: Kristina Fefelova --- .../attributes/SetAttributesPresenter.svelte | 1 + .../src/components/sidebar/Activity.svelte | 11 +++++++++-- .../src/components/MarkupDiffPresenter.svelte | 11 +++++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/plugins/activity-resources/src/components/doc-update-message/attributes/SetAttributesPresenter.svelte b/plugins/activity-resources/src/components/doc-update-message/attributes/SetAttributesPresenter.svelte index 605c857b63..e50a586b7a 100644 --- a/plugins/activity-resources/src/components/doc-update-message/attributes/SetAttributesPresenter.svelte +++ b/plugins/activity-resources/src/components/doc-update-message/attributes/SetAttributesPresenter.svelte @@ -69,6 +69,7 @@ attribute={attributeModel.attribute} value={values[0]} {prevValue} + withShowMore={false} showOnlyDiff /> {/if} diff --git a/plugins/document-resources/src/components/sidebar/Activity.svelte b/plugins/document-resources/src/components/sidebar/Activity.svelte index 2a55727b35..c6a02152f9 100644 --- a/plugins/document-resources/src/components/sidebar/Activity.svelte +++ b/plugins/document-resources/src/components/sidebar/Activity.svelte @@ -16,7 +16,12 @@ --> - +{#if withShowMore} + + {#key [value, prevValue]} + + {/key} + +{:else} {#key [value, prevValue]} {/key} - +{/if} From fd9d956db94b8b720bbbcc02b069046eb546b65c Mon Sep 17 00:00:00 2001 From: Kristina Date: Mon, 23 Sep 2024 09:57:06 +0400 Subject: [PATCH 3/5] Load reactions with lookup and make creation instant (#6680) Signed-off-by: Kristina Fefelova --- models/activity/package.json | 1 + models/activity/src/index.ts | 5 +++ packages/core/src/operations.ts | 16 ++++---- .../src/components/Activity.svelte | 5 +++ .../src/components/reactions/Reactions.svelte | 2 +- .../reactions/ReactionsPresenter.svelte | 40 +++++++++++-------- .../reactions/ReactionsPreview.svelte | 2 +- plugins/activity-resources/src/utils.ts | 20 ++-------- .../src/channelDataProvider.ts | 19 ++++++--- 9 files changed, 62 insertions(+), 48 deletions(-) diff --git a/models/activity/package.json b/models/activity/package.json index 00d35887ac..71570dd350 100644 --- a/models/activity/package.json +++ b/models/activity/package.json @@ -35,6 +35,7 @@ "@hcengineering/model": "^0.6.11", "@hcengineering/model-core": "^0.6.0", "@hcengineering/model-preference": "^0.6.0", + "@hcengineering/model-presentation": "^0.6.0", "@hcengineering/model-view": "^0.6.0", "@hcengineering/notification": "^0.6.23", "@hcengineering/platform": "^0.6.11", diff --git a/models/activity/src/index.ts b/models/activity/src/index.ts index c14f33b646..6d63a993c0 100644 --- a/models/activity/src/index.ts +++ b/models/activity/src/index.ts @@ -70,6 +70,7 @@ import preference, { TPreference } from '@hcengineering/model-preference' import view from '@hcengineering/model-view' import type { Asset, IntlString, Resource } from '@hcengineering/platform' import { type AnyComponent } from '@hcengineering/ui/src/types' +import presentation from '@hcengineering/model-presentation' import activity from './plugin' import { buildActions } from './actions' @@ -375,6 +376,10 @@ export function createModel (builder: Builder): void { ] }) + builder.mixin(activity.class.Reaction, core.class.Class, presentation.mixin.InstantTransactions, { + txClasses: [core.class.TxCreateDoc] + }) + buildActions(builder) buildNotifications(builder) } diff --git a/packages/core/src/operations.ts b/packages/core/src/operations.ts index 5dd2c35e4c..9db10bdae0 100644 --- a/packages/core/src/operations.ts +++ b/packages/core/src/operations.ts @@ -98,7 +98,7 @@ export class TxOperations implements Omit { throw new Error('createDoc cannot be called for DOMAIN_MODEL classes with non-model space') } const tx = this.txFactory.createTxCreateDoc(_class, space, attributes, id, modifiedOn, modifiedBy) - await this.client.tx(tx) + await this.tx(tx) return tx.objectId } @@ -122,7 +122,7 @@ export class TxOperations implements Omit { modifiedOn, modifiedBy ) - await this.client.tx(tx) + await this.tx(tx) return tx.tx.objectId as unknown as Ref

} @@ -147,7 +147,7 @@ export class TxOperations implements Omit { modifiedOn, modifiedBy ) - await this.client.tx(tx) + await this.tx(tx) return tx.objectId } @@ -170,7 +170,7 @@ export class TxOperations implements Omit { modifiedOn, modifiedBy ) - await this.client.tx(tx) + await this.tx(tx) return tx.objectId } @@ -184,7 +184,7 @@ export class TxOperations implements Omit { modifiedBy?: Ref ): Promise { const tx = this.txFactory.createTxUpdateDoc(_class, space, objectId, operations, retrieve, modifiedOn, modifiedBy) - return this.client.tx(tx) + return this.tx(tx) } removeDoc( @@ -195,7 +195,7 @@ export class TxOperations implements Omit { modifiedBy?: Ref ): Promise { const tx = this.txFactory.createTxRemoveDoc(_class, space, objectId, modifiedOn, modifiedBy) - return this.client.tx(tx) + return this.tx(tx) } createMixin( @@ -216,7 +216,7 @@ export class TxOperations implements Omit { modifiedOn, modifiedBy ) - return this.client.tx(tx) + return this.tx(tx) } updateMixin( @@ -237,7 +237,7 @@ export class TxOperations implements Omit { modifiedOn, modifiedBy ) - return this.client.tx(tx) + return this.tx(tx) } async update( diff --git a/plugins/activity-resources/src/components/Activity.svelte b/plugins/activity-resources/src/components/Activity.svelte index 9fea4555e9..5a2cc7db4f 100644 --- a/plugins/activity-resources/src/components/Activity.svelte +++ b/plugins/activity-resources/src/components/Activity.svelte @@ -211,6 +211,11 @@ { sort: { createdOn: SortingOrder.Ascending + }, + lookup: { + _id: { + reactions: activity.class.Reaction + } } } ) diff --git a/plugins/activity-resources/src/components/reactions/Reactions.svelte b/plugins/activity-resources/src/components/reactions/Reactions.svelte index 7df064d594..440cb291ba 100644 --- a/plugins/activity-resources/src/components/reactions/Reactions.svelte +++ b/plugins/activity-resources/src/components/reactions/Reactions.svelte @@ -55,7 +55,7 @@ ev.preventDefault() ev.stopPropagation() showPopup(EmojiPopup, {}, ev.target as HTMLElement, async (emoji: string) => { - await updateDocReactions(client, reactions, object, emoji) + await updateDocReactions(reactions, object, emoji) }) } diff --git a/plugins/activity-resources/src/components/reactions/ReactionsPresenter.svelte b/plugins/activity-resources/src/components/reactions/ReactionsPresenter.svelte index a495545053..86eb49e3a1 100644 --- a/plugins/activity-resources/src/components/reactions/ReactionsPresenter.svelte +++ b/plugins/activity-resources/src/components/reactions/ReactionsPresenter.svelte @@ -14,40 +14,48 @@ --> -{#if object && hasReactions} +{#if object && reactions.length > 0}

diff --git a/plugins/activity-resources/src/components/reactions/ReactionsPreview.svelte b/plugins/activity-resources/src/components/reactions/ReactionsPreview.svelte index 9e5f5374c0..917e11a97a 100644 --- a/plugins/activity-resources/src/components/reactions/ReactionsPreview.svelte +++ b/plugins/activity-resources/src/components/reactions/ReactionsPreview.svelte @@ -66,7 +66,7 @@ e.stopPropagation() e.preventDefault() showPopup(EmojiPopup, {}, e.target as HTMLElement, (emoji: string) => { - void updateDocReactions(client, reactions, message, emoji) + void updateDocReactions(reactions, message, emoji) }) } diff --git a/plugins/activity-resources/src/utils.ts b/plugins/activity-resources/src/utils.ts index 7a91bb20bb..06df26ee33 100644 --- a/plugins/activity-resources/src/utils.ts +++ b/plugins/activity-resources/src/utils.ts @@ -1,12 +1,5 @@ import type { ActivityMessage, Reaction } from '@hcengineering/activity' -import core, { - getCurrentAccount, - isOtherHour, - type Doc, - type Ref, - type TxOperations, - type Space -} from '@hcengineering/core' +import core, { getCurrentAccount, isOtherHour, type Doc, type Ref, type Space } from '@hcengineering/core' import { getClient, isSpace } from '@hcengineering/presentation' import { EmojiPopup, @@ -22,18 +15,13 @@ import { get } from 'svelte/store' import { savedMessagesStore } from './activity' import activity from './plugin' -export async function updateDocReactions ( - client: TxOperations, - reactions: Reaction[], - object?: Doc, - emoji?: string -): Promise { +export async function updateDocReactions (reactions: Reaction[], object?: Doc, emoji?: string): Promise { if (emoji === undefined || object === undefined) { return } + const client = getClient() const currentAccount = getCurrentAccount() - const reaction = reactions.find((r) => r.emoji === emoji && r.createBy === currentAccount._id) if (reaction == null) { @@ -72,7 +60,7 @@ export async function addReactionAction ( closePopup() showPopup(EmojiPopup, {}, element, (emoji: string) => { - void updateDocReactions(client, reactions, message, emoji) + void updateDocReactions(reactions, message, emoji) params?.onClose?.() }) params?.onOpen?.() diff --git a/plugins/chunter-resources/src/channelDataProvider.ts b/plugins/chunter-resources/src/channelDataProvider.ts index 66244cb07d..9de379d93c 100644 --- a/plugins/chunter-resources/src/channelDataProvider.ts +++ b/plugins/chunter-resources/src/channelDataProvider.ts @@ -20,6 +20,7 @@ import { type DocumentQuery, getCurrentAccount, isOtherDay, + type Lookup, type Ref, SortingOrder, type Space, @@ -285,13 +286,21 @@ export class ChannelDataProvider implements IChannelDataProvider { }, { sort: { createdOn: SortingOrder.Descending }, - lookup: { - _id: { attachments: attachment.class.Attachment, inlineButtons: chunter.class.InlineButton } - } + lookup: this.getLookup() } ) } + getLookup (): Lookup { + return { + _id: { + attachments: attachment.class.Attachment, + inlineButtons: chunter.class.InlineButton, + reactions: activity.class.Reaction + } + } + } + isNextLoading (mode: LoadMode): boolean { return mode === 'forward' ? get(this.isForwardLoading) : get(this.isBackwardLoading) } @@ -331,9 +340,7 @@ export class ChannelDataProvider implements IChannelDataProvider { { limit: limit ?? this.limit, sort: { createdOn: isBackward ? SortingOrder.Descending : SortingOrder.Ascending }, - lookup: { - _id: { attachments: attachment.class.Attachment, inlineButtons: chunter.class.InlineButton } - } + lookup: this.getLookup() } ) From 4bdfaaa28e010135144a7fe752e9e38620e7e519 Mon Sep 17 00:00:00 2001 From: Kristina Date: Mon, 23 Sep 2024 10:35:52 +0400 Subject: [PATCH 4/5] Freeze scroll and reading if tab not active (#6681) Signed-off-by: Kristina Fefelova --- .../src/channelDataProvider.ts | 9 ++- .../src/components/ChannelScrollView.svelte | 72 ++++++++++++++++--- 2 files changed, 71 insertions(+), 10 deletions(-) diff --git a/plugins/chunter-resources/src/channelDataProvider.ts b/plugins/chunter-resources/src/channelDataProvider.ts index 9de379d93c..c095d0e855 100644 --- a/plugins/chunter-resources/src/channelDataProvider.ts +++ b/plugins/chunter-resources/src/channelDataProvider.ts @@ -120,7 +120,7 @@ export class ChannelDataProvider implements IChannelDataProvider { }) constructor ( - readonly context: DocNotifyContext | undefined, + private context: DocNotifyContext | undefined, readonly space: Ref, chatId: Ref, _class: Ref>, @@ -210,6 +210,13 @@ export class ChannelDataProvider implements IChannelDataProvider { ) } + async updateNewTimestamp (context?: DocNotifyContext): Promise { + this.context = context ?? this.context + const firstNewMsgIndex = await this.getFirstNewMsgIndex() + const metadata = get(this.metadataStore) + this.newTimestampStore.set(firstNewMsgIndex !== undefined ? metadata[firstNewMsgIndex]?.createdOn : undefined) + } + private async loadInitialMessages ( selectedMsg?: Ref, loadAll = false, diff --git a/plugins/chunter-resources/src/components/ChannelScrollView.svelte b/plugins/chunter-resources/src/components/ChannelScrollView.svelte index 5dffbc7151..6b5644d56b 100644 --- a/plugins/chunter-resources/src/components/ChannelScrollView.svelte +++ b/plugins/chunter-resources/src/components/ChannelScrollView.svelte @@ -26,7 +26,7 @@ messageInFocus, sortActivityMessages } from '@hcengineering/activity-resources' - import { Doc, getDay, Ref, Timestamp } from '@hcengineering/core' + import { Doc, getCurrentAccount, getDay, Ref, Timestamp } from '@hcengineering/core' import { DocNotifyContext } from '@hcengineering/notification' import { InboxNotificationsClientImpl } from '@hcengineering/notification-resources' import { getResource } from '@hcengineering/platform' @@ -72,6 +72,7 @@ const minMsgHeightRem = 2 const loadMoreThreshold = 40 + const me = getCurrentAccount() const client = getClient() const inboxClient = InboxNotificationsClientImpl.getClient() const contextByDocStore = inboxClient.contextByDoc @@ -131,8 +132,23 @@ } }) + let isPageHidden = false + let lastMsgBeforeFreeze: Ref | undefined = undefined + + function handleVisibilityChange (): void { + if (document.hidden) { + isPageHidden = true + lastMsgBeforeFreeze = shouldScrollToNew ? displayMessages[displayMessages.length - 1]?._id : undefined + } else { + if (isPageHidden) { + isPageHidden = false + void provider.updateNewTimestamp(notifyContext) + } + } + } + function isFreeze (): boolean { - return freeze + return freeze || isPageHidden } $: displayMessages = filterChatMessages(messages, filters, filterResources, doc._class, selectedFilters) @@ -295,6 +311,38 @@ } } + function scrollToStartOfNew (): void { + if (!scrollElement || !lastMsgBeforeFreeze) { + return + } + + const lastIndex = displayMessages.findIndex(({ _id }) => _id === lastMsgBeforeFreeze) + if (lastIndex === -1) return + const firstNewMessage = displayMessages.find(({ createdBy }, index) => index > lastIndex && createdBy !== me._id) + + if (firstNewMessage === undefined) { + scrollToBottom() + return + } + + const messagesElements = scrollContentBox?.getElementsByClassName('activityMessage') + const msgElement = messagesElements?.[firstNewMessage._id as any] + + if (!msgElement) { + return + } + + const messageRect = msgElement.getBoundingClientRect() + + const topOffset = messageRect.top - 150 + + if (topOffset < 0) { + scroller?.scrollBy(topOffset) + } else if (topOffset > 0) { + scroller?.scrollBy(topOffset) + } + } + async function handleScroll ({ autoScrolling }: ScrollParams): Promise { saveScrollPosition() updateDownButtonVisibility($metadataStore, displayMessages, scrollElement) @@ -555,8 +603,12 @@ return } + const prevCount = messagesCount + messagesCount = newCount + if (isFreeze()) { - messagesCount = newCount + await wait() + scrollToStartOfNew() return } @@ -565,15 +617,13 @@ } else if (dateToJump !== undefined) { await wait() scrollToDate(dateToJump) - } else if (shouldScrollToNew && messagesCount > 0 && newCount > messagesCount) { + } else if (shouldScrollToNew && prevCount > 0 && newCount > prevCount) { await wait() scrollToNewMessages() } else { await wait() readViewportMessages() } - - messagesCount = newCount } $: void handleMessagesUpdated(displayMessages.length) @@ -610,10 +660,12 @@ afterUpdate(() => { if (!scrollElement) return - const { scrollHeight } = scrollElement + const { offsetHeight, scrollHeight, scrollTop } = scrollElement - if (!isInitialScrolling && prevScrollHeight < scrollHeight && isScrollAtBottom) { + if (!isInitialScrolling && !isFreeze() && prevScrollHeight < scrollHeight && isScrollAtBottom) { scrollToBottom() + } else if (isFreeze()) { + isScrollAtBottom = scrollHeight <= Math.ceil(scrollTop + offsetHeight) } }) @@ -641,10 +693,12 @@ onMount(() => { chatReadMessagesStore.update(() => new Set()) + document.addEventListener('visibilitychange', handleVisibilityChange) }) onDestroy(() => { unsubscribe() + document.removeEventListener('visibilitychange', handleVisibilityChange) }) let showScrollDownButton = false @@ -715,7 +769,7 @@ const canLoadNextForwardStore = provider.canLoadNextForwardStore - $: if (!freeze) { + $: if (!freeze && !isPageHidden && isScrollInitialized) { readViewportMessages() } From bbe2e4e9ce5ccd744cab4c3c4b430ce8db1f00f4 Mon Sep 17 00:00:00 2001 From: Kristina Date: Mon, 23 Sep 2024 10:36:08 +0400 Subject: [PATCH 5/5] Add chat fixes (#6682) Signed-off-by: Kristina Fefelova --- packages/ui/src/utils.ts | 2 +- .../components/ActivityMessageActions.svelte | 2 +- .../src/components/ChannelScrollView.svelte | 5 ++-- .../chat/specials/SavedMessages.svelte | 8 +++--- .../threads/ThreadParentPresenter.svelte | 9 ++++++- .../src/components/threads/Threads.svelte | 20 ++++++++++----- plugins/chunter-resources/src/utils.ts | 10 ++------ .../components/sidebar/SidebarExpanded.svelte | 25 +++++++++++++++++-- .../activity-resources/src/references.ts | 2 +- .../notification-resources/src/index.ts | 8 +++--- 10 files changed, 62 insertions(+), 29 deletions(-) diff --git a/packages/ui/src/utils.ts b/packages/ui/src/utils.ts index fb056b68bc..e769f24194 100644 --- a/packages/ui/src/utils.ts +++ b/packages/ui/src/utils.ts @@ -111,7 +111,7 @@ export function addNotification ( title, subTitle, severity, - position: NotificationPosition.TopRight, + position: NotificationPosition.BottomLeft, component, closeTimeout, params diff --git a/plugins/activity-resources/src/components/ActivityMessageActions.svelte b/plugins/activity-resources/src/components/ActivityMessageActions.svelte index 62129d1bf8..5a28faa06e 100644 --- a/plugins/activity-resources/src/components/ActivityMessageActions.svelte +++ b/plugins/activity-resources/src/components/ActivityMessageActions.svelte @@ -39,7 +39,7 @@ $: void updateInlineActions(message, excludedActions) savedMessagesStore.subscribe(() => { - void updateInlineActions(message) + void updateInlineActions(message, excludedActions) }) function handleActionMenuOpened (): void { diff --git a/plugins/chunter-resources/src/components/ChannelScrollView.svelte b/plugins/chunter-resources/src/components/ChannelScrollView.svelte index 6b5644d56b..d02a25591e 100644 --- a/plugins/chunter-resources/src/components/ChannelScrollView.svelte +++ b/plugins/chunter-resources/src/components/ChannelScrollView.svelte @@ -387,7 +387,7 @@ return messageRect.top >= containerRect.top && messageRect.bottom - messageRect.height / 2 <= containerRect.bottom } - const messagesToReadAccumulator: DisplayActivityMessage[] = [] + const messagesToReadAccumulator: Set = new Set() let messagesToReadAccumulatorTimer: any function readViewportMessages (): void { @@ -407,13 +407,14 @@ } if (messageInView(msgElement, containerRect)) { - messagesToReadAccumulator.push(message) + messagesToReadAccumulator.add(message) } } clearTimeout(messagesToReadAccumulatorTimer) messagesToReadAccumulatorTimer = setTimeout(() => { const messagesToRead = [...messagesToReadAccumulator] + messagesToReadAccumulator.clear() void readChannelMessages(sortActivityMessages(messagesToRead), notifyContext) }, 500) } diff --git a/plugins/chunter-resources/src/components/chat/specials/SavedMessages.svelte b/plugins/chunter-resources/src/components/chat/specials/SavedMessages.svelte index 54a3d3d5ee..d1855f0b59 100644 --- a/plugins/chunter-resources/src/components/chat/specials/SavedMessages.svelte +++ b/plugins/chunter-resources/src/components/chat/specials/SavedMessages.svelte @@ -37,14 +37,14 @@ $: savedMessages = $savedMessagesStore $: savedAttachments = $savedAttachmentsStore - async function openAttachment (attach?: Attachment) { + async function openAttachment (attach?: Attachment): Promise { if (attach === undefined) { return } const messageId: Ref = attach.attachedTo as Ref await client.findOne(activity.class.ActivityMessage, { _id: messageId }).then((res) => { if (res !== undefined) { - openMessageFromSpecial(res) + void openMessageFromSpecial(res) } }) } @@ -62,8 +62,8 @@ } } } - function handleMessageClicked (message?: ActivityMessage) { - openMessageFromSpecial(message) + function handleMessageClicked (message?: ActivityMessage): void { + void openMessageFromSpecial(message) } diff --git a/plugins/chunter-resources/src/components/threads/ThreadParentPresenter.svelte b/plugins/chunter-resources/src/components/threads/ThreadParentPresenter.svelte index 0f9403890f..c0436d5e95 100644 --- a/plugins/chunter-resources/src/components/threads/ThreadParentPresenter.svelte +++ b/plugins/chunter-resources/src/components/threads/ThreadParentPresenter.svelte @@ -19,4 +19,11 @@ export let message: ActivityMessage - + diff --git a/plugins/chunter-resources/src/components/threads/Threads.svelte b/plugins/chunter-resources/src/components/threads/Threads.svelte index 73c954fba3..3e3a0cc68c 100644 --- a/plugins/chunter-resources/src/components/threads/Threads.svelte +++ b/plugins/chunter-resources/src/components/threads/Threads.svelte @@ -19,6 +19,8 @@ import activity, { ActivityMessage } from '@hcengineering/activity' import { PersonAccount } from '@hcengineering/contact' import { ActivityMessagePresenter } from '@hcengineering/activity-resources' + import notification from '@hcengineering/notification' + import attachment from '@hcengineering/attachment' import chunter from '../../plugin' import Header from '../Header.svelte' @@ -32,15 +34,21 @@ $: threadsQuery.query( activity.class.ActivityMessage, { - replies: { $exists: true } + replies: { $exists: true }, + [`${notification.mixin.Collaborators}.collaborators`]: me._id }, (res) => { - threads = res.filter( - ({ createdBy, repliedPersons, replies }) => - (replies !== undefined && replies > 0 && createdBy === me._id) || repliedPersons?.includes(me.person) - ) + threads = res.filter(({ replies }) => (replies ?? 0) > 0) }, - { sort: { modifiedOn: SortingOrder.Descending } } + { + sort: { modifiedOn: SortingOrder.Descending }, + lookup: { + _id: { + attachments: attachment.class.Attachment, + reactions: activity.class.Reaction + } + } + } ) diff --git a/plugins/chunter-resources/src/utils.ts b/plugins/chunter-resources/src/utils.ts index 87b75edcc7..950ea5ec1a 100644 --- a/plugins/chunter-resources/src/utils.ts +++ b/plugins/chunter-resources/src/utils.ts @@ -430,11 +430,7 @@ export async function readChannelMessages ( messages: DisplayActivityMessage[], context: DocNotifyContext | undefined ): Promise { - if (messages.length === 0) { - return - } - - if (context === undefined) { + if (messages.length === 0 || context === undefined) { return } @@ -442,9 +438,7 @@ export async function readChannelMessages ( const client = getClient().apply(undefined, 'readViewportMessages') try { - const readMessages = get(chatReadMessagesStore) - const allIds = getAllIds(messages).filter((id) => !readMessages.has(id)) - + const allIds = getAllIds(messages) const notifications = get(inboxClient.activityInboxNotifications) .filter(({ attachedTo, $lookup, isViewed }) => { if (isViewed) return false diff --git a/plugins/workbench-resources/src/components/sidebar/SidebarExpanded.svelte b/plugins/workbench-resources/src/components/sidebar/SidebarExpanded.svelte index ef3285a94a..7209b04357 100644 --- a/plugins/workbench-resources/src/components/sidebar/SidebarExpanded.svelte +++ b/plugins/workbench-resources/src/components/sidebar/SidebarExpanded.svelte @@ -21,7 +21,8 @@ location as locationStore, Location, Header, - Breadcrumbs + Breadcrumbs, + getCurrentLocation } from '@hcengineering/ui' import { onDestroy } from 'svelte' @@ -45,13 +46,33 @@ $: widgetState = widget !== undefined ? $sidebarStore.widgetsState.get(widget._id) : undefined $: tabId = widgetState?.tab - $: tabs = widgetState?.tabs ?? [] + $: tabs = getTabs(widget, widgetState) $: tab = tabId !== undefined ? tabs.find((it) => it.id === tabId) ?? tabs[0] : tabs[0] $: if ($sidebarStore.widget === undefined) { sidebarStore.update((s) => ({ ...s, variant: SidebarVariant.MINI })) } + function getTabs (widget?: Widget, state?: WidgetState): WidgetTab[] { + if (widget === undefined || !state?.tabs) return [] + const loc = getCurrentLocation() + + const result: WidgetTab[] = [] + for (const tab of state.tabs) { + if (tab.allowedPath !== undefined && !tab.isPinned) { + const path = loc.path.join('/') + if (!path.startsWith(tab.allowedPath)) { + void handleTabClose(tab.id, widget) + continue + } + } + + result.push(tab) + } + + return result + } + const unsubscribe = locationStore.subscribe((loc: Location) => { if (widget === undefined) return diff --git a/server-plugins/activity-resources/src/references.ts b/server-plugins/activity-resources/src/references.ts index d2e66a7531..f260299f70 100644 --- a/server-plugins/activity-resources/src/references.ts +++ b/server-plugins/activity-resources/src/references.ts @@ -248,7 +248,7 @@ export async function getPersonNotificationTxes ( ...content, docNotifyContext: context._id, _id: generateId(), - _class: notification.class.CommonInboxNotification, + _class: notification.class.MentionInboxNotification, space: receiverSpace._id, modifiedOn: originTx.modifiedOn, modifiedBy: sender._id diff --git a/server-plugins/notification-resources/src/index.ts b/server-plugins/notification-resources/src/index.ts index 9390692e34..a09e410c19 100644 --- a/server-plugins/notification-resources/src/index.ts +++ b/server-plugins/notification-resources/src/index.ts @@ -78,7 +78,7 @@ import serverNotification, { SenderInfo } from '@hcengineering/server-notification' import serverView from '@hcengineering/server-view' -import { markupToHTML, markupToText, stripTags } from '@hcengineering/text' +import { markupToText, stripTags } from '@hcengineering/text' import { encodeObjectURI } from '@hcengineering/view' import { workbenchId } from '@hcengineering/workbench' import webpush, { WebPushError } from 'web-push' @@ -240,8 +240,10 @@ export async function getContentByTemplate ( notificationData !== undefined && control.hierarchy.isDerived(notificationData._class, notification.class.MentionInboxNotification) ) { - const text = (notificationData as MentionInboxNotification).messageHtml - params.body = text !== undefined ? markupToHTML(text) : params.body + const messageContent = (notificationData as MentionInboxNotification).messageHtml + const text = messageContent !== undefined ? markupToText(messageContent) : undefined + params.body = text ?? params.body + params.message = text ?? params.message } if (message !== undefined) {