platform/plugins/chat-resources/src/ui.ts
Kristina c49439070a
Update communication (#8578)
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
2025-04-16 13:50:15 +07:00

100 lines
2.7 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'
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 (entry.isIntersecting) {
onMessageView(entry.target as HTMLDivElement)
messageObserver.unobserve(entry.target)
}
})
},
{
root: null,
rootMargin: '-150px 0px -120px 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()
}
}