frontend: messages

This commit is contained in:
hippoz 2021-03-22 19:39:10 +02:00
parent b039639ff8
commit b902a1fc04
Signed by untrusted user who does not match committer: hippoz
GPG key ID: 7C52899193467641
2 changed files with 31 additions and 9 deletions

View file

@ -119,14 +119,30 @@ class AppState {
constructor(token) {
this.connection = new GatewayConnection(token);
this.tc = new Tricarbon();
this.elements = {
messagesContainer: "#messages",
messageInput: "#message-input",
channels: "#channels",
topBar: "#top-bar"
};
this.tcEvents = this.tc.useEvents();
this.messageObserver = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.type === "childList") {
const messages = this.tc.A(this.elements.messagesContainer);
messages.scrollTop = messages.scrollHeight;
}
}
});
this.messageStore = {};
this.selectedChannelId = null;
this.Sidebar = (channels) => (ev) => `
${Object.keys(channels).map(k => `
<button class="sidebar-button" onclick="${ev(() => this.navigateToChannel(channels[k]))}">${channels[k].title}</button>
<button class="sidebar-button" id="${channels[k]._id}" onclick="${ev(() => this.navigateToChannel(channels[k]))}">${channels[k].title}</button>
`).join("")}
`;
@ -145,13 +161,14 @@ class AppState {
this.connection.onopen = (sessionInfo) => {
this.renderSidebar(sessionInfo.channels);
this.tc.A("#message-input").addEventListener("keydown", (e) => {
this.messageObserver.observe(this.tc.A(this.elements.messagesContainer), { childList: true });
this.tc.A(this.elements.messageInput).addEventListener("keydown", (e) => {
if (e.code === "Enter") {
if (!this.selectedChannelId) return;
const messageContent = this.tc.A("#message-input").value;
const messageContent = this.tc.A(this.elements.messageInput).value;
if (!messageContent) return;
this.connection.sendMessage(messageContent, this.selectedChannelId);
this.tc.A("#message-input").value = "";
this.tc.A(this.elements.messageInput).value = "";
}
});
};
@ -165,7 +182,7 @@ AppState.prototype.appendMessage = function(message) {
if (!this.messageStore[message.channel._id]) this.messageStore[message.channel._id] = [];
this.messageStore[message.channel._id].push({ content: message.content, author: message.author });
if (this.selectedChannelId === message.channel._id) {
this.tc.push(this.ChannelMessages(this.messageStore[message.channel._id] || []), "#messages", false, this.tcEvents("#messages"));
this.tc.push(this.ChannelMessages(this.messageStore[message.channel._id] || []), this.elements.messagesContainer, false, this.tcEvents(this.elements.messagesContainer));
}
};
@ -173,13 +190,16 @@ AppState.prototype.navigateToChannel = function(channel) {
console.log("app: navigating to channel", channel);
if (this.selectedChannelId !== channel._id) {
this.selectedChannelId = channel._id;
this.tc.push(this.ChannelTopBar(channel), "#top-bar", false);
this.tc.push(this.ChannelMessages(this.messageStore[channel._id] || []), "#messages", false, this.tcEvents("#messages"));
this.tc.push(this.ChannelTopBar(channel), this.elements.topBar, false);
this.tc.push(this.ChannelMessages(this.messageStore[channel._id] || []), this.elements.messagesContainer, false, this.tcEvents(this.elements.messagesContainer));
}
};
AppState.prototype.renderSidebar = function(channels) {
this.tc.push(this.Sidebar(channels), "#channels", false, this.tcEvents("#channels"));
this.tc.push(this.Sidebar(channels), this.elements.channels, false, this.tcEvents(this.elements.channels));
};
const app = new AppState(localStorage.getItem("token"));
let app;
document.addEventListener("DOMContentLoaded", () => {
app = new AppState(localStorage.getItem("token"));
});

View file

@ -35,6 +35,7 @@ main {
display: flex;
flex-direction: column;
flex: 10;
height: 100%;
}
.sidebar {
@ -97,6 +98,7 @@ main {
flex: 1;
flex-wrap: wrap;
overflow-y: auto;
height: 100%;
background-color: var(--bg);
}