mirror of
https://github.com/hanzoai/forum.git
synced 2026-09-30 21:51:19 +00:00
This commit does several changes: - it moves the ownership of the last message info to the channel instead of storing it on the message, it avoids the need to iterate over every messages - makes an optimistic update of the last read message id - adds a spec to confirm this behavior
139 lines
3.7 KiB
Plaintext
139 lines
3.7 KiB
Plaintext
import Component from "@glimmer/component";
|
|
import { cached } from "@glimmer/tracking";
|
|
import { on } from "@ember/modifier";
|
|
import { action } from "@ember/object";
|
|
import { modifier } from "ember-modifier";
|
|
import concatClass from "discourse/helpers/concat-class";
|
|
import { i18n } from "discourse-i18n";
|
|
|
|
const IS_PINNED_CLASS = "is-pinned";
|
|
|
|
export default class ChatMessageSeparator extends Component {
|
|
track = modifier((element) => {
|
|
const intersectionObserver = new IntersectionObserver(
|
|
([entry]) => {
|
|
if (
|
|
entry.isIntersecting &&
|
|
entry.intersectionRatio < 1 &&
|
|
entry.boundingClientRect.y < entry.intersectionRect.y
|
|
) {
|
|
entry.target.classList.add(IS_PINNED_CLASS);
|
|
} else {
|
|
entry.target.classList.remove(IS_PINNED_CLASS);
|
|
}
|
|
},
|
|
{ threshold: [0, 1] }
|
|
);
|
|
|
|
intersectionObserver.observe(element);
|
|
|
|
return () => {
|
|
intersectionObserver?.disconnect();
|
|
};
|
|
});
|
|
|
|
@action
|
|
onDateClick() {
|
|
return this.args.fetchMessagesByDate?.(this.firstMessageOfTheDayAt);
|
|
}
|
|
|
|
@cached
|
|
get firstMessageOfTheDayAt() {
|
|
const message = this.args.message;
|
|
|
|
if (!message.previousMessage) {
|
|
return this.#startOfDay(message.createdAt);
|
|
}
|
|
|
|
if (
|
|
!this.#areDatesOnSameDay(
|
|
message.previousMessage.createdAt,
|
|
message.createdAt
|
|
)
|
|
) {
|
|
return this.#startOfDay(message.createdAt);
|
|
}
|
|
}
|
|
|
|
@cached
|
|
get formattedFirstMessageDate() {
|
|
if (this.firstMessageOfTheDayAt) {
|
|
return this.#calendarDate(this.firstMessageOfTheDayAt);
|
|
}
|
|
}
|
|
|
|
get isNewestMessage() {
|
|
return this.args.message.id === this.args.message.channel.newestMessage?.id;
|
|
}
|
|
|
|
#areDatesOnSameDay(a, b) {
|
|
return (
|
|
a.getFullYear() === b.getFullYear() &&
|
|
a.getMonth() === b.getMonth() &&
|
|
a.getDate() === b.getDate()
|
|
);
|
|
}
|
|
|
|
#startOfDay(date) {
|
|
return moment(date).startOf("day").format();
|
|
}
|
|
|
|
#calendarDate(date) {
|
|
return moment(date).calendar(moment(), {
|
|
sameDay: `[${i18n("chat.chat_message_separator.today")}]`,
|
|
lastDay: `[${i18n("chat.chat_message_separator.yesterday")}]`,
|
|
lastWeek: "LL",
|
|
sameElse: "LL",
|
|
});
|
|
}
|
|
|
|
<template>
|
|
{{#if this.formattedFirstMessageDate}}
|
|
<div
|
|
class={{concatClass
|
|
"chat-message-separator"
|
|
"chat-message-separator-date"
|
|
(if this.isNewestMessage "with-last-visit")
|
|
}}
|
|
role="button"
|
|
{{on "click" this.onDateClick passive=true}}
|
|
data-id={{@message.id}}
|
|
>
|
|
<div class="chat-message-separator__text-container" {{this.track}}>
|
|
<span class="chat-message-separator__text">
|
|
{{this.formattedFirstMessageDate}}
|
|
|
|
{{#if this.isNewestMessage}}
|
|
<span class="chat-message-separator__last-visit">
|
|
<span
|
|
class="chat-message-separator__last-visit-separator"
|
|
>-</span>
|
|
{{i18n "chat.last_visit"}}
|
|
</span>
|
|
{{/if}}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="chat-message-separator__line-container">
|
|
<div class="chat-message-separator__line"></div>
|
|
</div>
|
|
{{else if this.isNewestMessage}}
|
|
<div
|
|
class="chat-message-separator chat-message-separator-new"
|
|
data-id={{@message.id}}
|
|
>
|
|
<div class="chat-message-separator__text-container">
|
|
<span class="chat-message-separator__text">
|
|
{{i18n "chat.last_visit"}}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="chat-message-separator__line-container">
|
|
<div class="chat-message-separator__line"></div>
|
|
</div>
|
|
</div>
|
|
{{/if}}
|
|
</template>
|
|
}
|