Add chat fixes (#6682)

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
Kristina 2024-09-23 10:36:08 +04:00 committed by GitHub
parent 4bdfaaa28e
commit bbe2e4e9ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 62 additions and 29 deletions

View File

@ -111,7 +111,7 @@ export function addNotification (
title, title,
subTitle, subTitle,
severity, severity,
position: NotificationPosition.TopRight, position: NotificationPosition.BottomLeft,
component, component,
closeTimeout, closeTimeout,
params params

View File

@ -39,7 +39,7 @@
$: void updateInlineActions(message, excludedActions) $: void updateInlineActions(message, excludedActions)
savedMessagesStore.subscribe(() => { savedMessagesStore.subscribe(() => {
void updateInlineActions(message) void updateInlineActions(message, excludedActions)
}) })
function handleActionMenuOpened (): void { function handleActionMenuOpened (): void {

View File

@ -387,7 +387,7 @@
return messageRect.top >= containerRect.top && messageRect.bottom - messageRect.height / 2 <= containerRect.bottom return messageRect.top >= containerRect.top && messageRect.bottom - messageRect.height / 2 <= containerRect.bottom
} }
const messagesToReadAccumulator: DisplayActivityMessage[] = [] const messagesToReadAccumulator: Set<DisplayActivityMessage> = new Set<DisplayActivityMessage>()
let messagesToReadAccumulatorTimer: any let messagesToReadAccumulatorTimer: any
function readViewportMessages (): void { function readViewportMessages (): void {
@ -407,13 +407,14 @@
} }
if (messageInView(msgElement, containerRect)) { if (messageInView(msgElement, containerRect)) {
messagesToReadAccumulator.push(message) messagesToReadAccumulator.add(message)
} }
} }
clearTimeout(messagesToReadAccumulatorTimer) clearTimeout(messagesToReadAccumulatorTimer)
messagesToReadAccumulatorTimer = setTimeout(() => { messagesToReadAccumulatorTimer = setTimeout(() => {
const messagesToRead = [...messagesToReadAccumulator] const messagesToRead = [...messagesToReadAccumulator]
messagesToReadAccumulator.clear()
void readChannelMessages(sortActivityMessages(messagesToRead), notifyContext) void readChannelMessages(sortActivityMessages(messagesToRead), notifyContext)
}, 500) }, 500)
} }

View File

@ -37,14 +37,14 @@
$: savedMessages = $savedMessagesStore $: savedMessages = $savedMessagesStore
$: savedAttachments = $savedAttachmentsStore $: savedAttachments = $savedAttachmentsStore
async function openAttachment (attach?: Attachment) { async function openAttachment (attach?: Attachment): Promise<void> {
if (attach === undefined) { if (attach === undefined) {
return return
} }
const messageId: Ref<ActivityMessage> = attach.attachedTo as Ref<ActivityMessage> const messageId: Ref<ActivityMessage> = attach.attachedTo as Ref<ActivityMessage>
await client.findOne(activity.class.ActivityMessage, { _id: messageId }).then((res) => { await client.findOne(activity.class.ActivityMessage, { _id: messageId }).then((res) => {
if (res !== undefined) { if (res !== undefined) {
openMessageFromSpecial(res) void openMessageFromSpecial(res)
} }
}) })
} }
@ -62,8 +62,8 @@
} }
} }
} }
function handleMessageClicked (message?: ActivityMessage) { function handleMessageClicked (message?: ActivityMessage): void {
openMessageFromSpecial(message) void openMessageFromSpecial(message)
} }
</script> </script>

View File

@ -19,4 +19,11 @@
export let message: ActivityMessage export let message: ActivityMessage
</script> </script>
<ActivityMessagePresenter value={message} hideFooter hoverStyles="filledHover" withShowMore={false} skipLabel /> <ActivityMessagePresenter
value={message}
hideFooter
hoverStyles="filledHover"
withShowMore={false}
attachmentImageSize="x-large"
skipLabel
/>

View File

@ -19,6 +19,8 @@
import activity, { ActivityMessage } from '@hcengineering/activity' import activity, { ActivityMessage } from '@hcengineering/activity'
import { PersonAccount } from '@hcengineering/contact' import { PersonAccount } from '@hcengineering/contact'
import { ActivityMessagePresenter } from '@hcengineering/activity-resources' import { ActivityMessagePresenter } from '@hcengineering/activity-resources'
import notification from '@hcengineering/notification'
import attachment from '@hcengineering/attachment'
import chunter from '../../plugin' import chunter from '../../plugin'
import Header from '../Header.svelte' import Header from '../Header.svelte'
@ -32,15 +34,21 @@
$: threadsQuery.query( $: threadsQuery.query(
activity.class.ActivityMessage, activity.class.ActivityMessage,
{ {
replies: { $exists: true } replies: { $exists: true },
[`${notification.mixin.Collaborators}.collaborators`]: me._id
}, },
(res) => { (res) => {
threads = res.filter( threads = res.filter(({ replies }) => (replies ?? 0) > 0)
({ createdBy, repliedPersons, replies }) =>
(replies !== undefined && replies > 0 && createdBy === me._id) || repliedPersons?.includes(me.person)
)
}, },
{ sort: { modifiedOn: SortingOrder.Descending } } {
sort: { modifiedOn: SortingOrder.Descending },
lookup: {
_id: {
attachments: attachment.class.Attachment,
reactions: activity.class.Reaction
}
}
}
) )
</script> </script>

View File

@ -430,11 +430,7 @@ export async function readChannelMessages (
messages: DisplayActivityMessage[], messages: DisplayActivityMessage[],
context: DocNotifyContext | undefined context: DocNotifyContext | undefined
): Promise<void> { ): Promise<void> {
if (messages.length === 0) { if (messages.length === 0 || context === undefined) {
return
}
if (context === undefined) {
return return
} }
@ -442,9 +438,7 @@ export async function readChannelMessages (
const client = getClient().apply(undefined, 'readViewportMessages') const client = getClient().apply(undefined, 'readViewportMessages')
try { try {
const readMessages = get(chatReadMessagesStore) const allIds = getAllIds(messages)
const allIds = getAllIds(messages).filter((id) => !readMessages.has(id))
const notifications = get(inboxClient.activityInboxNotifications) const notifications = get(inboxClient.activityInboxNotifications)
.filter(({ attachedTo, $lookup, isViewed }) => { .filter(({ attachedTo, $lookup, isViewed }) => {
if (isViewed) return false if (isViewed) return false

View File

@ -21,7 +21,8 @@
location as locationStore, location as locationStore,
Location, Location,
Header, Header,
Breadcrumbs Breadcrumbs,
getCurrentLocation
} from '@hcengineering/ui' } from '@hcengineering/ui'
import { onDestroy } from 'svelte' import { onDestroy } from 'svelte'
@ -45,13 +46,33 @@
$: widgetState = widget !== undefined ? $sidebarStore.widgetsState.get(widget._id) : undefined $: widgetState = widget !== undefined ? $sidebarStore.widgetsState.get(widget._id) : undefined
$: tabId = widgetState?.tab $: tabId = widgetState?.tab
$: tabs = widgetState?.tabs ?? [] $: tabs = getTabs(widget, widgetState)
$: tab = tabId !== undefined ? tabs.find((it) => it.id === tabId) ?? tabs[0] : tabs[0] $: tab = tabId !== undefined ? tabs.find((it) => it.id === tabId) ?? tabs[0] : tabs[0]
$: if ($sidebarStore.widget === undefined) { $: if ($sidebarStore.widget === undefined) {
sidebarStore.update((s) => ({ ...s, variant: SidebarVariant.MINI })) 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) => { const unsubscribe = locationStore.subscribe((loc: Location) => {
if (widget === undefined) return if (widget === undefined) return

View File

@ -248,7 +248,7 @@ export async function getPersonNotificationTxes (
...content, ...content,
docNotifyContext: context._id, docNotifyContext: context._id,
_id: generateId(), _id: generateId(),
_class: notification.class.CommonInboxNotification, _class: notification.class.MentionInboxNotification,
space: receiverSpace._id, space: receiverSpace._id,
modifiedOn: originTx.modifiedOn, modifiedOn: originTx.modifiedOn,
modifiedBy: sender._id modifiedBy: sender._id

View File

@ -78,7 +78,7 @@ import serverNotification, {
SenderInfo SenderInfo
} from '@hcengineering/server-notification' } from '@hcengineering/server-notification'
import serverView from '@hcengineering/server-view' 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 { encodeObjectURI } from '@hcengineering/view'
import { workbenchId } from '@hcengineering/workbench' import { workbenchId } from '@hcengineering/workbench'
import webpush, { WebPushError } from 'web-push' import webpush, { WebPushError } from 'web-push'
@ -240,8 +240,10 @@ export async function getContentByTemplate (
notificationData !== undefined && notificationData !== undefined &&
control.hierarchy.isDerived(notificationData._class, notification.class.MentionInboxNotification) control.hierarchy.isDerived(notificationData._class, notification.class.MentionInboxNotification)
) { ) {
const text = (notificationData as MentionInboxNotification).messageHtml const messageContent = (notificationData as MentionInboxNotification).messageHtml
params.body = text !== undefined ? markupToHTML(text) : params.body const text = messageContent !== undefined ? markupToText(messageContent) : undefined
params.body = text ?? params.body
params.message = text ?? params.message
} }
if (message !== undefined) { if (message !== undefined) {