Improve when time is shown and improve post UI

This commit introduces a heuristic for when to show time, introduces a
date separator and tweaks the margins of posts.
This commit is contained in:
Midgard 2022-06-11 17:25:12 +02:00
parent 8d0d0dd3a7
commit f7344dc63f
Signed by: midgard
GPG key ID: 511C112F1331BBB4
3 changed files with 89 additions and 22 deletions

View file

@ -215,15 +215,25 @@ ul#server_selection_list {
margin-bottom: 0.5em;
}
.date_separator {
font-weight: bold;
margin-top: 0.3em;
font-size: 75%;
text-align: center;
color: #555;
border-top: 1px solid #ccc;
}
.post {
padding: 0.1em;
margin: 0.6em 0 0.2em;
padding: 0.2em;
margin-top: 0.3em;
display: grid;
grid-template-rows: auto auto;
grid-template-rows: auto auto auto;
grid-template-columns: auto auto;
min-height: 3ex;
}
.post.same_author {
margin-top: 0.2em;
margin-top: 0;
}
.post:first-child {
margin-top: 8px;
@ -234,6 +244,9 @@ ul#server_selection_list {
.post:hover {
background-color: #e4e4e4;
}
.post:not(.show_time) {
position: relative;
}
.post .author {
grid-row: 1;
@ -242,7 +255,7 @@ ul#server_selection_list {
font-weight: bold;
align-self: end;
}
.post.same_author .author {
.post.same_author:not(.show_time) .author {
display: none;
}
@ -254,8 +267,16 @@ ul#server_selection_list {
color: #888;
align-self: end;
}
.post.same_author .create_at {
.post:not(.show_time) .create_at {
display: none;
position: absolute;
background-color: #e4e4e4;
padding: 0 0.2em;
right: 0;
top: 0;
}
.post:not(.show_time):hover .create_at {
display: block;
}
.post .message {
@ -264,8 +285,15 @@ ul#server_selection_list {
grid-column-start: 1;
grid-column-end: 3;
}
.post.special .message {
color: #555;
font-size: 75%;
}
.post ul.attachments {
grid-row: 3;
grid-column-start: 1;
grid-column-end: 3;
margin: 0;
padding: 0;
list-style: none;

View file

@ -90,8 +90,9 @@ function toTimeZone(date, timezoneString) {
return new Date(date.toLocaleString("en-US", {timeZone: timezoneString}));
}
function formatDdddMmYy(date) {
return `${date.getFullYear()}-${padLeft(date.getMonth() + 1, 2, "0")}-${padLeft(date.getDate(), 2, "0")}`;
function formatYyyyMmDdWeekday(date) {
const weekday = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"][date.getDay()];
return `${date.getFullYear()}-${padLeft(date.getMonth() + 1, 2, "0")}-${padLeft(date.getDate(), 2, "0")}, ${weekday}`;
}
function formatHhMm(date) {

View file

@ -8,25 +8,63 @@ function transformMessageText(message) {
}
function shouldShowTime(lastShownTime, time) {
const sim = dateSimilarity(lastShownTime, time);
if (sim < DATE_SIMILARITY.date) {
return {date: true, time: true};
}
const minutesSinceLastShown = (time - lastShownTime) / 1000 / 60;
if (minutesSinceLastShown >= 15) {
return {date: false, time: true};
}
return {date: false, time: false};
}
async function createMessageElement(client, post, lastTime, lastAuthor) {
let nodes = [];
const users = await client.getUsers();
const isThreadReply = !!post.parent_id;
const createAt = new Date(post.create_at);
let createAtLocalized = createAt;
let lastTimeLocalized = lastTime;
try {
if (client.me.timezone.useAutomaticTimezone !== "true") {
createAtLocalized = toTimeZone(createAt, client.me.timezone.manualTimezone);
lastTimeLocalized = toTimeZone(lastTime, client.me.timezone.manualTimezone);
}
} catch(e) {}
const showTime = shouldShowTime(lastTimeLocalized, createAtLocalized);
if (showTime.time) {
lastTime = createAt;
}
const postDiv = document.createElement("div");
postDiv.className = "post";
if (post.type !== "") {
postDiv.className += " special";
}
if (showTime.date) {
const dateElement = document.createElement("div");
dateElement.className = "date_separator";
dateElement.innerText = formatYyyyMmDdWeekday(createAtLocalized);
nodes.push(dateElement);
}
if (showTime.time) {
postDiv.className += " show_time";
}
const messageDiv = document.createElement("div");
messageDiv.className = "message";
messageDiv.innerText = transformMessageText(post.message);
let createAt = new Date(post.create_at);
if (client.me.timezone.useAutomaticTimezone !== "true") {
createAt = toTimeZone(createAt, client.me.timezone.manualTimezone);
}
const createAtDiv = document.createElement("time");
createAtDiv.className = "create_at";
const sim = dateSimilarity(lastTime, createAt);
lastTime = createAt;
let createAtText = "";
if (sim < DATE_SIMILARITY.date) createAtText += formatDdddMmYy(createAt);
if (sim < DATE_SIMILARITY.minutes) createAtText += " " + formatHhMm(createAt);
let createAtText = formatHhMm(createAtLocalized);
createAtDiv.title = createAt.toString();
createAtDiv.innerText = createAtText;
createAtDiv.dateTime = createAt.toISOString();
@ -36,8 +74,6 @@ async function createMessageElement(client, post, lastTime, lastAuthor) {
authorDiv.className = "author";
authorDiv.innerText = authorName;
const postDiv = document.createElement("div");
postDiv.className = "post";
if (lastAuthor === post.user_id) {
postDiv.className += " same_author";
}
@ -72,7 +108,9 @@ async function createMessageElement(client, post, lastTime, lastAuthor) {
postDiv.appendChild(attachmentsUl);
}
return {postDiv, lastTime, lastAuthor};
nodes.push(postDiv);
return {nodes, lastTime, lastAuthor};
}
@ -84,7 +122,7 @@ async function populateChannelContents(client, channel, contents) {
let nodes = [];
for (let id of contents.order) {
result = await createMessageElement(client, contents.posts[id], result.lastTime, result.lastAuthor);
nodes.push(result.postDiv);
nodes.push(...result.nodes);
}
byId("channel_contents").dataset["server"] = client.endpoint;
@ -106,7 +144,7 @@ async function addMessage(client, post) {
);
byId("channel_contents").dataset["lastTime"] = result.lastTime.getTime();
byId("channel_contents").dataset["lastAuthor"] = result.lastAuthor;
byId("channel_contents").appendChild(result.postDiv);
byId("channel_contents").append(...result.nodes);
if (shouldScroll) {
scrollToBottom();