Files
huly-platform/plugins/communication-resources/src/messages.ts
T
42865885c3 Add fixes for new chat/inbox (#8984)
* Add chat fixes

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>

* Update pnpm

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>

* Freeze chat if app out of focus, add reaction notification, add inbox clearing

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>

* Read reactions notifications

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>

* Fix format

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>

* Update packages/ui-next/src/components/message/MessageInput.svelte

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Kristina <kristin.fefelova@gmail.com>

* Update packages/ui-next/src/components/message/MessageInput.svelte

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Kristina <kristin.fefelova@gmail.com>

* Fix processes section

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>

---------

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
Signed-off-by: Kristina <kristin.fefelova@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-05-19 17:04:27 +07:00

103 lines
2.9 KiB
TypeScript

//
// Copyright © 2025 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
import { type Message } from '@hcengineering/communication-types'
import { isAppFocusedStore } from '@hcengineering/ui'
import { get } from 'svelte/store'
export interface MessagesGroup {
day: number
messages: Message[]
}
export function getGroupDay (date: Date): number {
return new Date(date).setHours(0, 0, 0, 0)
}
export function groupMessagesByDay (messages: Message[]): MessagesGroup[] {
const result: MessagesGroup[] = []
for (const message of messages) {
const day = getGroupDay(message.created)
const group = findOrCreateGroup(result, day, (group) => result.push(group))
group.messages.push(message)
}
return result
}
function findOrCreateGroup (
groups: MessagesGroup[],
dayTimestamp: number,
pushFn: (group: MessagesGroup) => void
): MessagesGroup {
let group = groups.find((g) => g.day === dayTimestamp)
if (group === undefined) {
group = { day: dayTimestamp, messages: [] }
pushFn(group)
}
return group
}
export function createMessagesObserver (
contentDiv: HTMLDivElement,
onMessageView: (node: HTMLDivElement) => void
): () => void {
const messageObserver = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (!get(isAppFocusedStore)) return
const isIntersecting = entry.isIntersecting
if (isIntersecting) {
onMessageView(entry.target as HTMLDivElement)
}
})
},
{
root: null,
rootMargin: '-180px 0px 0px 0px',
threshold: 0.1
}
)
contentDiv.querySelectorAll('.message').forEach((message) => {
messageObserver.observe(message)
})
const mutationObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node: Node) => {
const element = node as HTMLDivElement
if (element.classList?.contains('messages-group')) {
element.querySelectorAll('.message').forEach((message) => {
messageObserver.observe(message)
})
}
if (element.classList?.contains('message')) {
messageObserver.observe(element)
}
})
})
})
mutationObserver.observe(contentDiv, { childList: true, subtree: true })
return () => {
messageObserver.disconnect()
mutationObserver.disconnect()
}
}