): void {
@@ -463,29 +603,50 @@ export class WebChat extends LitElement {
}
}
- if (changed.has('channel')) {
- this.restoreFromLocal();
+ if (changed.has('messageGroups')) {
+ // console.log(this.messageGroups);
+ // this.scrollToBottom();
}
+ }
- if (changed.has('messages')) {
- // console.log('messages changed', this.messages);
- this.writeToLocal();
- // console.log(this.messages);
- this.scrollToBottom();
+ private addMessage(msg: Message): boolean {
+ if (msg.time && !msg.timeAsDate) {
+ msg.timeAsDate = new Date(msg.time);
}
- }
- private addMessage(msg: Message) {
+ if (
+ !this.oldestMessageDate ||
+ msg.timeAsDate.getTime() < this.oldestMessageDate.getTime()
+ ) {
+ this.oldestMessageDate = msg.timeAsDate;
+ }
+
+ const isNew = !this.msgMap.has(msg.msg_id);
+ this.msgMap.set(msg.msg_id, msg);
+ return isNew;
+
+ /*
let lastGroup =
- this.messages.length > 0 ? this.messages[this.messages.length - 1] : [];
- const isSame = lastGroup.length === 0 || lastGroup[0].origin === msg.origin;
+ this.messageGroups.length > 0 ? this.messageGroups[this.messageGroups.length - 1] : [];
+
+ const lastMsgId = lastGroup.length > 0 ? lastGroup[lastGroup.length - 1] : null;
+ const lastMsg = lastMsgId ? this.msgMap.get(lastMsgId) : null;
+
+ let isSame = !lastMsg || (lastMsg.origin === msg.origin && lastMsg.user?.name === msg.user?.name);
+ if (isSame && lastMsg && msg.timeAsDate.getTime() - lastMsg.timeAsDate.getTime() > BATCH_TIME_WINDOW) {
+ isSame = false;
+ }
+
if (!isSame) {
lastGroup = [];
}
if (lastGroup.length === 0) {
- this.messages.push(lastGroup);
+ this.messageGroups.push(lastGroup);
}
- lastGroup.push(msg);
+
+ this.msgMap.set(msg.msg_id, msg);
+ lastGroup.push(msg.msg_id);
+ */
}
public openChat(): void {
@@ -507,13 +668,16 @@ export class WebChat extends LitElement {
input.value = '';
const msg = {
+ msg_id: `pending-${this.newMessageCount++}`,
type: 'send_msg',
text: text,
+ time: new Date().toISOString(),
};
this.addMessage(msg);
- this.sock.send(JSON.stringify(msg));
- this.requestUpdate('messages');
+ this.insertGroups(this.groupMessages([msg.msg_id]).reverse(), true);
+ this.sendSockMessage(msg);
+
this.hasPendingText = input.value.length > 0;
}
}
@@ -527,42 +691,52 @@ export class WebChat extends LitElement {
}
private renderMessageGroup(
- messages: Message[],
+ msgIds: string[],
idx: number,
- groups: Message[][]
+ groups: string[][]
): TemplateResult {
- let lastBatchTime = null;
+ const today = new Date();
+ let prevMsg;
if (idx > 0) {
const lastGroup = groups[idx - 1];
if (lastGroup && lastGroup.length > 0) {
- lastBatchTime = lastGroup[lastGroup.length - 1].timestamp;
+ prevMsg = this.msgMap.get(lastGroup[0]);
}
}
- const newBatchTime = messages[0].timestamp;
- const showTime = newBatchTime - lastBatchTime > BATCH_TIME_WINDOW;
-
+ const currentMsg = this.msgMap.get(msgIds[msgIds.length - 1]);
let timeDisplay = null;
- if (showTime) {
- let lastTime = null;
- const newTime = new Date(newBatchTime);
- if (lastBatchTime) {
- lastTime = new Date(lastBatchTime);
- }
- const showDay = !lastTime || newTime.getDate() !== lastTime.getDate();
+ if (
+ prevMsg &&
+ !this.isSameGroup(prevMsg, currentMsg) &&
+ prevMsg.timeAsDate.getTime() - currentMsg.timeAsDate.getTime() >
+ BATCH_TIME_WINDOW
+ ) {
+ const showDay =
+ !prevMsg ||
+ prevMsg.timeAsDate.getDate() !== currentMsg.timeAsDate.getDate();
if (showDay) {
timeDisplay = html`
- ${newTime.toLocaleDateString(undefined, DAY_FORMAT)}
+ ${prevMsg.timeAsDate.toLocaleDateString(undefined, DAY_FORMAT)}
`;
} else {
- timeDisplay = html`
- ${newTime.toLocaleTimeString(undefined, TIME_FORMAT)}
-
`;
+ if (prevMsg.timeAsDate.getDate() !== today.getDate()) {
+ timeDisplay = html`
+ ${prevMsg.timeAsDate.toLocaleTimeString(undefined, VERBOSE_FORMAT)}
+
`;
+ } else {
+ timeDisplay = html`
+ ${prevMsg.timeAsDate.toLocaleTimeString(undefined, TIME_FORMAT)}
+
`;
+ }
}
}
- const blockTime = new Date(messages[messages.length - 1].timestamp);
- const incoming = !messages[0].origin;
+ const blockTime = new Date(this.msgMap.get(msgIds[msgIds.length - 1]).time);
+ const message = this.msgMap.get(msgIds[0]);
+ const incoming = !message.origin;
+ const avatar = message.user?.avatar;
+ const name = message.user?.name;
return html`
- ${timeDisplay}
${!incoming
? html`
`
: null}
- ${!incoming ? html`
Henry McHelper
` : null}
- ${messages.map(msg => html`
${msg.text}
`)}
+ ${!incoming ? html`
${name}
` : null}
+ ${msgIds.map(
+ msgId =>
+ html`
${this.msgMap.get(msgId).text}
`
+ )}
+ ${timeDisplay}
`;
}
private handleScroll(event: any) {
- this.hideBottomScroll =
- Math.round(event.target.scrollTop + event.target.clientHeight) >=
- event.target.scrollHeight;
- this.hideTopScroll = event.target.scrollTop === 0;
+ const ele = event.target;
+ const top = ele.scrollHeight - ele.clientHeight;
+ const scroll = Math.round(top + ele.scrollTop);
+ const scrollPct = scroll / top;
+
+ this.hideTopScroll = scrollPct <= 0.01;
+ this.hideBottomScroll = scrollPct >= 0.99;
+
+ if (this.blockHistoryFetching) {
+ return;
+ }
+
+ if (scrollPct < SCROLL_FETCH_BUFFER) {
+ this.fetchPreviousMessages();
+ }
}
private handleClickInputPanel(event: MouseEvent) {
@@ -617,7 +805,7 @@ export class WebChat extends LitElement {
: ''}"
>