Chat: show dates when the day changes (js)

このコミットが含まれているのは:
n9k 2022-08-10 00:01:27 +00:00
コミット d7b4717cf5
3個のファイルの変更88行の追加23行の削除

ファイルの表示

@ -189,6 +189,7 @@ const create_chat_message = (object) => {
chat_message.classList.add("chat-message");
chat_message.dataset.seq = object.seq;
chat_message.dataset.tokenHash = object.token_hash;
chat_message.dataset.date = object.date;
const chat_message_time = document.createElement("time");
chat_message_time.classList.add("chat-message__time");
@ -256,23 +257,65 @@ const create_chat_user_components = (user) => {
result.push(...[chat_user_name, chat_user_tripcode_nbsp, chat_user_tripcode]);
return result;
}
const zeropad = (n) => ("0" + n).slice(-2);
const datestamp = () => {
const date = new Date();
return `${date.getUTCFullYear()}-${zeropad(date.getUTCMonth() + 1)}-${zeropad(date.getUTCDate())}`;
}
const create_and_add_chat_message = (object) => {
// date
last_chat_message = chat_messages.querySelector(".chat-message:last-of-type");
if (last_chat_message === null || last_chat_message.dataset.date !== object.date) {
const chat_date = document.createElement("li");
chat_date.classList.add("chat-date");
chat_date.dataset.date = object.date;
const chat_date_hr = document.createElement("hr");
const chat_date_div = document.createElement("div");
const chat_date_div_time = document.createElement("time");
chat_date_div_time.datetime = object.date;
chat_date_div_time.innerText = object.date;
chat_date_div.insertAdjacentElement("beforeend", chat_date_div_time);
chat_date.insertAdjacentElement("beforeend", chat_date_hr);
chat_date.insertAdjacentElement("beforeend", chat_date_div);
if (last_chat_message === null && object.date === datestamp())
chat_date.dataset.hidden = "";
chat_messages.insertAdjacentElement("beforeend", chat_date);
}
// message
const chat_message = create_chat_message(object);
chat_messages.insertAdjacentElement("beforeend", chat_message);
while (chat_messages.children.length > max_chat_scrollback) {
chat_messages.children[0].remove();
const first_chat_message = chat_messages.querySelector(".chat-message");
if (first_chat_message !== null) {
const first_chat_date = chat_messages.querySelector(".chat-date");
if (first_chat_date !== null && first_chat_date.hasAttribute("data-hidden") && (object.date !== first_chat_message.dataset.date || object.date !== datestamp()))
first_chat_date.removeAttribute("data-hidden");
}
const string_seqs = new Set();
for (const this_chat_message of chat_messages.querySelectorAll(".chat-message")) {
if (chat_messages.querySelectorAll(".chat-message").length - string_seqs.size > max_chat_scrollback)
string_seqs.add(this_chat_message.dataset.seq);
else
break;
}
delete_chat_messages({string_seqs});
}
const delete_chat_messages = (seqs) => {
string_seqs = new Set(seqs.map(n => n.toString()));
to_delete = [];
for (const chat_message of chat_messages.children) {
if (string_seqs.has(chat_message.dataset.seq))
to_delete.push(chat_message);
const delete_chat_messages = ({string_seqs, keep=false}) => {
const keep_dates = new Set();
for (const chat_message of chat_messages.querySelectorAll(".chat-message")) {
if (string_seqs.has(chat_message.dataset.seq) === keep)
keep_dates.add(chat_message.dataset.date);
}
for (const chat_message of to_delete) {
chat_message.remove();
const to_delete = [];
for (const child of chat_messages.children) {
if (child.classList.contains("chat-date") && !keep_dates.has(child.dataset.date) || child.classList.contains("chat-message") && string_seqs.has(child.dataset.seq) !== keep)
to_delete.push(child);
}
for (const element of to_delete)
element.remove();
}
let users = {};
@ -632,17 +675,8 @@ const on_websocket_message = async (event) => {
chat_form_submit.disabled = false;
// remove messages the server isn't acknowledging the existence of
const seqs = new Set(receipt.messages.map((message) => {return message.seq;}));
const to_delete = [];
for (const chat_message of chat_messages.children) {
const chat_message_seq = parseInt(chat_message.dataset.seq);
if (!seqs.has(chat_message_seq)) {
to_delete.push(chat_message);
}
}
for (const chat_message of to_delete) {
chat_message.remove();
}
const string_seqs = new Set(receipt.messages.map(message => message.seq.toString()));
delete_chat_messages({string_seqs, keep: true});
// settings
default_name = receipt.default;
@ -744,7 +778,7 @@ const on_websocket_message = async (event) => {
case "delete":
console.log("ws delete", receipt);
delete_chat_messages(receipt.seqs);
delete_chat_messages({string_seqs: new Set(receipt.seqs.map(n => n.toString()))});
break;
case "set-users":
@ -969,6 +1003,14 @@ chat_messages_unlock.addEventListener("click", (event) => {
chat_messages.scrollTop = chat_messages.scrollTopMax;
});
/* show initial chat date if a day has passed */
const show_initial_date = () => {
const chat_date = chat_messages.querySelector(".chat-date:first-child");
if (chat_date !== null && chat_date.hasAttribute("data-hidden") && chat_date.dataset.date !== datestamp())
chat_date.removeAttribute("data-hidden");
}
setInterval(show_initial_date, 30000);
/* close websocket after prolonged absence of pings */
const rotate_websocket = () => {

ファイルの表示

@ -273,6 +273,29 @@ noscript {
font-size: 9pt;
cursor: default;
}
.chat-date {
text-align: center;
position: relative;
display: grid;
align-items: center;
margin: 8px 0;
color: #b2b2b3;
cursor: default;
}
.chat-date[data-hidden] {
display: none;
}
.chat-date > hr {
margin: 0;
position: absolute;
width: 100%;
box-sizing: border-box;
}
.chat-date > :not(hr) > time {
padding: 0 1ch;
background-color: #232327;
position: relative;
}
#chat__body__users {
background-color: #121214;
mask-image: linear-gradient(black calc(100% - 0.625rem), transparent calc(100% - 0.125rem));

ファイルの表示

@ -193,7 +193,7 @@
<ol id="chat-messages">
{% for message in messages | reverse %}
{% with this_user = users_by_token[message.token] %}
<li class="chat-message" data-seq="{{ message.seq }}" data-token-hash="{{ this_user.token_hash }}">
<li class="chat-message" data-seq="{{ message.seq }}" data-token-hash="{{ this_user.token_hash }}" data-date="{{ message.date }}">
<time class="chat-message__time" datetime="{{ message.date }}T{{ message.time_seconds }}Z" title="{{ message.date }} {{ message.time_seconds }}">{{ message.time_minutes }}</time>
{{- '&nbsp;' | safe -}}
{{ appearance(this_user, insignia_class='chat-message__insignia', name_class='chat-message__name', tag_class='chat-message__name__tag') }}