2020-03-31 12:09:33 +02:00
|
|
|
function populateServerSelectionList() {
|
2020-03-31 18:12:03 +02:00
|
|
|
const servers = localstorage_credentials.getServers();
|
2020-03-31 12:09:33 +02:00
|
|
|
|
|
|
|
let nodes = [];
|
|
|
|
for (let server of servers) {
|
|
|
|
const li = document.createElement("li");
|
|
|
|
const endpoint = humanReadableEndpoint(server.endpoint);
|
|
|
|
li.innerText = `${server.login_id}@${endpoint} `;
|
|
|
|
|
|
|
|
const logoutButton = document.createElement("button");
|
|
|
|
logoutButton.className = "logout";
|
|
|
|
logoutButton.innerText = "Log out";
|
2021-02-17 17:13:15 +01:00
|
|
|
logoutButton.addEventListener("click", e => logOut(server.endpoint, e.currentTarget));
|
2020-03-31 12:09:33 +02:00
|
|
|
|
|
|
|
li.appendChild(logoutButton);
|
|
|
|
nodes.push(li);
|
|
|
|
}
|
|
|
|
byId("server_selection_list").innerHTML = "";
|
|
|
|
byId("server_selection_list").append(...nodes);
|
|
|
|
}
|
|
|
|
|
|
|
|
function populateChannelList() {
|
2021-02-17 16:07:15 +01:00
|
|
|
async function addChannelItems(client) {
|
2020-03-31 12:09:33 +02:00
|
|
|
const teams = await client.myTeams();
|
|
|
|
|
|
|
|
for (let team of teams) {
|
|
|
|
let nodes = [];
|
|
|
|
const channels = await client.myChannels(team.id);
|
|
|
|
for (let channel of channels) {
|
|
|
|
const li = document.createElement("li");
|
|
|
|
const a = document.createElement("a");
|
|
|
|
a.href = "javascript:void(0)";
|
|
|
|
const titleAndElements = channelNameElements(team, channel);
|
|
|
|
if (!titleAndElements) continue;
|
|
|
|
a.title = titleAndElements[0];
|
|
|
|
a.append(...titleAndElements[1]);
|
|
|
|
|
|
|
|
a.addEventListener("click", () => switchToChannel(client, team, channel));
|
|
|
|
|
|
|
|
li.appendChild(a);
|
|
|
|
li.dataset["id"] = channel.id;
|
|
|
|
nodes.push(li);
|
|
|
|
}
|
|
|
|
byId("channel_list").append(...nodes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
byId("channel_list").innerHTML = "";
|
2021-02-17 16:07:15 +01:00
|
|
|
const endpoints = localstorage_credentials.getServers().map(server => server.endpoint);
|
|
|
|
for (let client of mm_client.getMultiple(endpoints)) {
|
|
|
|
addChannelItems(client);
|
2020-03-31 12:09:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-17 21:58:06 +01:00
|
|
|
function transformMessageText(message) {
|
2021-04-26 17:40:07 +02:00
|
|
|
return message
|
|
|
|
.split(/(?<=:|\W|^)(:[a-z0-9_-]+:)(?=:|\W|$)/)
|
|
|
|
.map((x, i) => i % 2
|
|
|
|
? emoji[x.slice(1, -1)] || x
|
|
|
|
: x)
|
|
|
|
.join("");
|
2021-02-17 21:58:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-17 16:07:15 +01:00
|
|
|
async function createMessageElement(client, post, lastTime, lastAuthor) {
|
|
|
|
const users = await client.getUsers();
|
|
|
|
const isThreadReply = !!post.parent_id;
|
|
|
|
|
|
|
|
const messageDiv = document.createElement("div");
|
|
|
|
messageDiv.className = "message";
|
2021-02-17 21:58:06 +01:00
|
|
|
messageDiv.innerText = transformMessageText(post.message);
|
2021-02-17 16:07:15 +01:00
|
|
|
|
|
|
|
const createAt = new Date(post.create_at);
|
|
|
|
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);
|
|
|
|
createAtDiv.title = createAt.toString();
|
|
|
|
createAtDiv.innerText = createAtText;
|
|
|
|
createAtDiv.dateTime = createAt.toISOString();
|
|
|
|
|
|
|
|
const authorName = users[post.user_id] ? users[post.user_id].username : post.user_id;
|
|
|
|
const authorDiv = document.createElement("div");
|
|
|
|
authorDiv.className = "author";
|
|
|
|
authorDiv.innerText = authorName;
|
|
|
|
|
|
|
|
const postDiv = document.createElement("div");
|
|
|
|
postDiv.className = "post";
|
|
|
|
if (lastAuthor === post.user_id) {
|
|
|
|
postDiv.className += " same_author";
|
|
|
|
}
|
|
|
|
lastAuthor = post.user_id;
|
|
|
|
|
|
|
|
postDiv.dataset["id"] = post.id;
|
|
|
|
postDiv.appendChild(authorDiv);
|
|
|
|
postDiv.appendChild(createAtDiv);
|
|
|
|
postDiv.appendChild(messageDiv);
|
|
|
|
|
2021-02-17 18:15:57 +01:00
|
|
|
if (post.metadata && (post.metadata.files || []).length > 0) {
|
2021-02-17 16:07:15 +01:00
|
|
|
const attachmentsUl = document.createElement("ul");
|
|
|
|
attachmentsUl.className = "attachments";
|
|
|
|
for (let file of post.metadata.files || []) {
|
|
|
|
const attachmentLi = document.createElement("li");
|
|
|
|
attachmentLi.dataset["id"] = file.id;
|
|
|
|
|
|
|
|
const attachmentA = document.createElement("a");
|
|
|
|
client.filePublicLink(file.id).then(link => attachmentA.href = link);
|
|
|
|
attachmentA.target = "_blank";
|
|
|
|
attachmentA.innerText = file.name;
|
|
|
|
|
|
|
|
if (file.mini_preview) {
|
|
|
|
const attachmentImg = document.createElement("img");
|
|
|
|
attachmentImg.src = `data:image/jpeg;base64,${file.mini_preview}`;
|
|
|
|
attachmentA.appendChild(attachmentImg);
|
|
|
|
}
|
|
|
|
|
|
|
|
attachmentLi.appendChild(attachmentA);
|
|
|
|
attachmentsUl.appendChild(attachmentLi);
|
|
|
|
}
|
|
|
|
postDiv.appendChild(attachmentsUl);
|
|
|
|
}
|
|
|
|
|
|
|
|
return {postDiv, lastTime, lastAuthor};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function populateChannelContents(client, channel, contents) {
|
2020-03-31 12:09:33 +02:00
|
|
|
byId("channel_contents").innerHTML = "";
|
|
|
|
|
2021-02-17 16:07:15 +01:00
|
|
|
let result = {lastAuthor: null, lastTime: null, postDiv: null};
|
2021-02-07 21:47:59 +01:00
|
|
|
|
2020-03-31 12:09:33 +02:00
|
|
|
let nodes = [];
|
|
|
|
for (let id of contents.order) {
|
2021-02-17 16:07:15 +01:00
|
|
|
result = await createMessageElement(client, contents.posts[id], result.lastTime, result.lastAuthor);
|
|
|
|
nodes.push(result.postDiv);
|
2020-03-31 12:09:33 +02:00
|
|
|
}
|
|
|
|
|
2021-02-17 16:07:15 +01:00
|
|
|
byId("channel_contents").dataset["server"] = client.endpoint;
|
|
|
|
byId("channel_contents").dataset["id"] = channel.id;
|
|
|
|
byId("channel_contents").dataset["lastTime"] = result.lastTime.getTime();
|
|
|
|
byId("channel_contents").dataset["lastAuthor"] = result.lastAuthor;
|
2020-03-31 12:09:33 +02:00
|
|
|
byId("channel_contents").append(...nodes);
|
2021-02-07 21:10:36 +01:00
|
|
|
scrollToBottom();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-17 16:07:15 +01:00
|
|
|
async function addMessage(client, post) {
|
|
|
|
const shouldScroll = isScrolledToBottom();
|
|
|
|
|
|
|
|
const result = await createMessageElement(
|
|
|
|
client, post,
|
|
|
|
new Date(1 * (byId("channel_contents").dataset["lastTime"])),
|
|
|
|
byId("channel_contents").dataset["lastAuthor"]
|
|
|
|
);
|
|
|
|
console.log(result);
|
|
|
|
byId("channel_contents").dataset["lastTime"] = result.lastTime.getTime();
|
|
|
|
byId("channel_contents").dataset["lastAuthor"] = result.lastAuthor;
|
|
|
|
byId("channel_contents").appendChild(result.postDiv);
|
|
|
|
|
|
|
|
if (shouldScroll) {
|
|
|
|
scrollToBottom();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-07 21:10:36 +01:00
|
|
|
function scrollToBottom() {
|
|
|
|
const el = byId("channel_contents_wrapper");
|
|
|
|
el.scrollTop = el.scrollHeight;
|
|
|
|
el.className = "";
|
2020-03-31 12:09:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function updateComposeHeight() {
|
|
|
|
byId("compose").style.height = "";
|
|
|
|
byId("compose").style.height = (byId("compose").scrollHeight + 1) + "px";
|
|
|
|
}
|
|
|
|
byId("compose").addEventListener("input", updateComposeHeight);
|
|
|
|
|
2021-02-17 16:07:15 +01:00
|
|
|
function isScrolledToBottom() {
|
2020-03-31 12:09:33 +02:00
|
|
|
const el = byId("channel_contents_wrapper");
|
|
|
|
|
|
|
|
const scrolledTo = el.clientHeight + el.scrollTop;
|
2021-02-17 16:07:15 +01:00
|
|
|
return scrolledTo >= el.scrollHeight;
|
|
|
|
}
|
|
|
|
function checkScrolledToBottom() {
|
|
|
|
byId("channel_contents_wrapper").className = isScrolledToBottom() ? "" : "not-at-bottom";
|
2020-03-31 12:09:33 +02:00
|
|
|
}
|
|
|
|
byId("channel_contents_wrapper").addEventListener("scroll", checkScrolledToBottom);
|
2021-02-17 16:07:15 +01:00
|
|
|
|
|
|
|
|
|
|
|
pubsub.subscribe("MESSAGES_NEW", post => {
|
|
|
|
if (
|
|
|
|
post.endpoint === byId("channel_contents").dataset["server"] &&
|
|
|
|
post.channel_id === byId("channel_contents").dataset["id"]
|
|
|
|
) {
|
|
|
|
addMessage(mm_client.get(post.endpoint), post);
|
|
|
|
}
|
|
|
|
});
|