feathermost/js/controller.js

227 lines
6.1 KiB
JavaScript

"use strict";
function buttonDisable(element, text) {
if (!element.dataset.originalText) {
element.dataset.originalText = element.innerText;
}
element.innerText = text;
element.disabled = true;
}
function buttonEnable(element) {
element.innerText = element.dataset.originalText;
element.disabled = false;
}
function logIn() {
const client = mm_client.getOrCreate(normalizedEndpoint(byId("login_server").value));
buttonDisable(byId("login_button"), "Logging in...");
client.logIn(byId("login_login_id").value, byId("login_password").value)
.then(json => {
client.start();
buttonEnable(byId("login_button"));
byId("login_message").innerText = "";
byId("channel_list").innerText = `Logged in as ${json.username}`;
window.location = "#";
populateServerSelectionList();
populateChannelList();
})
.catch(error => {
console.error(error);
buttonEnable(byId("login_button"));
if (error.xhr && error.xhr.responseJson && error.xhr.responseJson.message) {
byId("login_message").innerText = `Error: ${error.xhr.responseJson.message}`;
} else {
byId("login_message").innerText = `${error}`;
}
});
}
function logOut(endpoint, button) {
const client = mm_client.getOrCreate(endpoint);
buttonDisable(button, "Logging out...");
client.logOut()
.then(response => {
console.info("Succesfully logged out");
populateServerSelectionList();
populateChannelList();
})
.catch(error => {
console.error(error);
const span = document.createElement("span");
span.innerText = `Failed to log out: ${error.message}`;
button.parentElement.appendChild(span);
buttonEnable(button);
});
mm_client.drop(endpoint);
}
function channelNameElements(team, channel) {
let icon = "";
let teamName = team.name;
let channelName = channel.name;
let title = "";
switch (channel.type) {
case "O": // Public channel
title = `${channel.name} in team ${team.name} (public)`;
break;
case "P": // Private channel
icon = "🔒";
title = `${channel.name} in team ${team.name} (private)`;
break;
case "D": // Direct message
return undefined; // XXX Because they clutter the list
teamName = "";
channelName = `👤 ...`;
title = `Direct message`;
break;
case "G": // Group chat
teamName = "";
channelName = `👥 ${channel.display_name}`;
title = `Group chat with ${channel.display_name}`;
break;
default: // Unsupported
icon = channel.type;
title = `${channel.name} in team ${team.name} (type ${channel.type})`;
break;
}
let elements = [];
if (icon) {
elements.push(`${icon} `);
}
if (teamName) {
const teamElement = document.createElement("span");
teamElement.className = "team-name";
teamElement.innerText = teamName;
elements.push(teamElement);
const separatorElement = document.createElement("span");
separatorElement.className = "separator";
separatorElement.innerText = "/";
elements.push(separatorElement);
}
const channelElement = document.createElement("span");
channelElement.className = "channel-name";
channelElement.innerText = channelName;
elements.push(channelElement);
return [title, elements];
}
function switchToChannel(client, team, channel) {
for (let el of byId("channel_list").childNodes) {
if (el.dataset["server"] == client.endpoint && el.dataset["id"] == channel.id) {
addClass(el, "active");
} else {
removeClass(el, "active");
}
}
byId("channel_contents").innerText = "Loading…";
client.channelPosts(channel.id)
.then(response => {
console.info(`Got channel contents of ${channel.id} (${channel.name})`);
response.order.reverse();
populateChannelContents(client, channel, response);
markChannelAsRead(client, channel);
})
.catch(error => {
console.error(error);
byId("channel_contents").innerText = `Failed to get channel contents:\n${error.message}`;
});
const [title, elements] = channelNameElements(team, channel);
byId("channel_header").innerHTML = "";
byId("channel_header").append(...elements);
byId("compose").setAttribute("placeholder", `Write to ${byId("channel_header").textContent}`);
}
function sendMessage(endpoint, channel_id, message) {
const client = mm_client.getOrCreate(endpoint);
client.writePost(channel_id, message);
//pubsub.publish("MESSAGES_NEW", {
//endpoint,
//channel_id: channel_id,
//create_at: (new Date()).getTime(),
//user_id: client.me.id,
//message
//});
}
async function executeSlashCommand(endpoint, channel_id, command) {
const client = mm_client.getOrCreate(endpoint);
const response = await client.executeSlashCommand(channel_id, command);
if (
response.responseJson &&
response.responseJson.text &&
response.responseJson.response_type !== "in_channel"
) {
pubsub.publish("MESSAGES_NEW", {
endpoint,
channel_id,
create_at: (new Date()).getTime(),
user_id: client.me.id,
message: "(only visible to you) " + response.responseJson.text
});
}
}
function markChannelAsRead(client, channel) {
return client.markChannelRead(channel.id);
}
function checkKeyPress(event) {
// Battle tested for many years in several browsers
if ((event.keyCode === event.DOM_VK_RETURN || event.keyCode === 13 || event.keyCode === 10 || event.key === "Enter" || event.keyIdentifier === "U+000A") && !event.shiftKey && !event.ctrlKey) {
if (byId("compose").value.length > 0) {
let message = byId("compose").value;
if (message[0] === "/") {
executeSlashCommand(
byId("channel_contents").dataset["server"],
byId("channel_contents").dataset["id"],
message
);
} else {
sendMessage(
byId("channel_contents").dataset["server"],
byId("channel_contents").dataset["id"],
message
);
}
byId("compose").value = "";
}
return true;
}
return false;
}
pubsub.subscribe("MESSAGES_NEW", post => {
if (!window.hasFocus) {
return;
}
const curChan = currentChannel();
if (post.endpoint === curChan.endpoint && post.channel_id === curChan.channel_id) {
mm_client.getOrCreate(post.endpoint).markChannelRead(post.channel_id);
}
});
pubsub.subscribe("WINDOW_FOCUSED", () => {
const curChan = currentChannel();
if (!curChan.channel_id) return;
mm_client.getOrCreate(curChan.endpoint).markChannelRead(curChan.channel_id);
});