Add chat fixes (#5437)

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
Kristina 2024-04-23 19:44:49 +04:00 committed by GitHub
parent 4423246b58
commit e202027d2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 60 additions and 56 deletions

View File

@ -64,7 +64,8 @@
$: devSize = $deviceInfo.size $: devSize = $deviceInfo.size
$: shrinkButtons = checkAdaptiveMatching(devSize, 'sm') $: shrinkButtons = checkAdaptiveMatching(devSize, 'sm')
$: canSubmit = (!isEmpty || haveAttachment) && !isEmptyMarkup(content) && !loading $: isEmptyContent = isEmpty || isEmptyMarkup(content)
$: canSubmit = (haveAttachment || !isEmptyContent) && !loading
function setContent (content: Markup): void { function setContent (content: Markup): void {
textEditor?.setContent(content) textEditor?.setContent(content)

View File

@ -164,13 +164,13 @@
readViewportMessages() readViewportMessages()
} }
function isDateRendered (date: Timestamp) { function isDateRendered (date: Timestamp): boolean {
const day = getDay(date) const day = getDay(date)
return document.getElementById(day.toString()) != null return document.getElementById(day.toString()) != null
} }
async function jumpToDate (e: CustomEvent) { function jumpToDate (e: CustomEvent): void {
const date = e.detail.date const date = e.detail.date
if (!date || !scrollElement) { if (!date || !scrollElement) {
@ -191,7 +191,7 @@
} }
} }
function scrollToDate (date: Timestamp) { function scrollToDate (date: Timestamp): void {
autoscroll = false autoscroll = false
dateToJump = undefined dateToJump = undefined
shouldWaitAndRead = false shouldWaitAndRead = false
@ -210,7 +210,7 @@
scroller?.scroll(offset) scroller?.scroll(offset)
} }
function updateShouldScrollToNew () { function updateShouldScrollToNew (): void {
if (scrollElement) { if (scrollElement) {
const { offsetHeight, scrollHeight, scrollTop } = scrollElement const { offsetHeight, scrollHeight, scrollTop } = scrollElement
const offset = 100 const offset = 100
@ -219,7 +219,7 @@
} }
} }
function shouldLoadMoreUp () { function shouldLoadMoreUp (): boolean {
if (!scrollElement) { if (!scrollElement) {
return false return false
} }
@ -227,7 +227,7 @@
return scrollElement.scrollTop === 0 return scrollElement.scrollTop === 0
} }
function shouldLoadMoreDown () { function shouldLoadMoreDown (): boolean {
if (!scrollElement) { if (!scrollElement) {
return false return false
} }
@ -239,7 +239,7 @@
let scrollToRestore = 0 let scrollToRestore = 0
function loadMore () { function loadMore (): void {
if (!loadMoreAllowed || $isLoadingMoreStore || !scrollElement || isInitialScrolling) { if (!loadMoreAllowed || $isLoadingMoreStore || !scrollElement || isInitialScrolling) {
return return
} }
@ -259,7 +259,7 @@
} }
} }
function handleScroll ({ autoScrolling }: ScrollParams) { function handleScroll ({ autoScrolling }: ScrollParams): void {
saveScrollPosition() saveScrollPosition()
if (autoScrolling) { if (autoScrolling) {
return return
@ -302,7 +302,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
} }
function readViewportMessages () { function readViewportMessages (): void {
if (!scrollElement || !scrollContentBox) { if (!scrollElement || !scrollContentBox) {
return return
} }
@ -327,7 +327,7 @@
void readChannelMessages(messagesToRead, notifyContext) void readChannelMessages(messagesToRead, notifyContext)
} }
function updateSelectedDate () { function updateSelectedDate (): void {
if (!withDates) { if (!withDates) {
return return
} }
@ -446,33 +446,16 @@
} }
} }
let scrollToLastMessage = false function scrollToNewMessages (): void {
function scrollUntilSeeLastMessage () {
if (isLastMessageViewed()) {
readViewportMessages()
shouldScrollToNew = true
scrollToLastMessage = false
} else if (scrollToLastMessage && shouldScrollToNew) {
setTimeout(() => {
scrollToBottom(scrollUntilSeeLastMessage)
}, 50)
} else {
scrollToLastMessage = false
}
}
function scrollToNewMessages () {
if (!scrollElement || !shouldScrollToNew) { if (!scrollElement || !shouldScrollToNew) {
return return
} }
scrollToLastMessage = true
scrollToBottom() scrollToBottom()
scrollUntilSeeLastMessage() readViewportMessages()
} }
async function wait () { async function wait (): Promise<void> {
// One tick is not enough for messages to be rendered, // One tick is not enough for messages to be rendered,
// I think this is due to the fact that we are using a Component, which takes some time to load, // I think this is due to the fact that we are using a Component, which takes some time to load,
// because after one tick I see spinners from Component // because after one tick I see spinners from Component
@ -498,7 +481,7 @@
shouldWaitAndRead = false shouldWaitAndRead = false
} }
async function handleMessagesUpdated (newCount: number) { async function handleMessagesUpdated (newCount: number): Promise<void> {
if (newCount === messagesCount) { if (newCount === messagesCount) {
return return
} }
@ -516,11 +499,17 @@
messagesCount = newCount messagesCount = newCount
} }
$: handleMessagesUpdated(displayMessages.length) $: void handleMessagesUpdated(displayMessages.length)
function handleResize () { function handleResize (): void {
if (!isInitialScrolling && isScrollInitialized) { if (isInitialScrolling || !isScrollInitialized) {
loadMore() return
} }
if (shouldScrollToNew) {
scrollToBottom()
}
loadMore()
} }
let prevScrollHeight = 0 let prevScrollHeight = 0
@ -632,7 +621,11 @@
</div> </div>
{#if object} {#if object}
<div class="ref-input"> <div class="ref-input">
<ActivityExtensionComponent kind="input" {extensions} props={{ object, boundary: scrollElement, collection }} /> <ActivityExtensionComponent
kind="input"
{extensions}
props={{ object, boundary: scrollElement, collection, autofocus: true }}
/>
</div> </div>
{/if} {/if}
{/if} {/if}

View File

@ -145,18 +145,16 @@ async function OnThreadMessageCreated (tx: Tx, control: TriggerControl): Promise
async function OnChatMessageCreated (tx: TxCUD<Doc>, control: TriggerControl): Promise<Tx[]> { async function OnChatMessageCreated (tx: TxCUD<Doc>, control: TriggerControl): Promise<Tx[]> {
const hierarchy = control.hierarchy const hierarchy = control.hierarchy
const actualTx = TxProcessor.extractTx(tx) const actualTx = TxProcessor.extractTx(tx) as TxCreateDoc<ChatMessage>
if (actualTx._class !== core.class.TxCreateDoc) { if (
return [] actualTx._class !== core.class.TxCreateDoc ||
} !hierarchy.isDerived(actualTx.objectClass, chunter.class.ChatMessage)
) {
const chatMessage = TxProcessor.createDoc2Doc(actualTx as TxCreateDoc<ChatMessage>)
if (!hierarchy.isDerived(chatMessage._class, chunter.class.ChatMessage)) {
return [] return []
} }
const chatMessage = TxProcessor.createDoc2Doc(actualTx)
const mixin = hierarchy.classHierarchyMixin(chatMessage.attachedToClass, notification.mixin.ClassCollaborators) const mixin = hierarchy.classHierarchyMixin(chatMessage.attachedToClass, notification.mixin.ClassCollaborators)
if (mixin === undefined) { if (mixin === undefined) {

View File

@ -1235,9 +1235,13 @@ async function OnActivityNotificationViewed (
} }
const inboxNotification = ( const inboxNotification = (
await control.findAll(notification.class.ActivityInboxNotification, { await control.findAll(
_id: tx.objectId as Ref<ActivityInboxNotification> notification.class.ActivityInboxNotification,
}) {
_id: tx.objectId as Ref<ActivityInboxNotification>
},
{ projection: { _id: 1, attachedTo: 1, user: 1 } }
)
)[0] )[0]
if (inboxNotification === undefined) { if (inboxNotification === undefined) {
@ -1247,19 +1251,27 @@ async function OnActivityNotificationViewed (
// Read reactions notifications when message is read // Read reactions notifications when message is read
const { attachedTo, user } = inboxNotification const { attachedTo, user } = inboxNotification
const reactionMessages = await control.findAll(activity.class.DocUpdateMessage, { const reactionMessages = await control.findAll(
attachedTo, activity.class.DocUpdateMessage,
objectClass: activity.class.Reaction {
}) attachedTo,
objectClass: activity.class.Reaction
},
{ projection: { _id: 1 } }
)
if (reactionMessages.length === 0) { if (reactionMessages.length === 0) {
return [] return []
} }
const reactionNotifications = await control.findAll(notification.class.ActivityInboxNotification, { const reactionNotifications = await control.findAll(
attachedTo: { $in: reactionMessages.map(({ _id }) => _id) }, notification.class.ActivityInboxNotification,
user {
}) attachedTo: { $in: reactionMessages.map(({ _id }) => _id) },
user
},
{ projection: { _id: 1, _class: 1, space: 1 } }
)
return reactionNotifications.map(({ _id, _class, space }) => return reactionNotifications.map(({ _id, _class, space }) =>
control.txFactory.createTxUpdateDoc(_class, space, _id, { isViewed: true }) control.txFactory.createTxUpdateDoc(_class, space, _id, { isViewed: true })