Add channel viewing
This commit is contained in:
parent
4ce30be711
commit
49bc51175a
3 changed files with 105 additions and 7 deletions
16
ajax.js
16
ajax.js
|
@ -68,10 +68,26 @@ function xhrParseJsonResponse(xhr) {
|
|||
return xhr;
|
||||
}
|
||||
|
||||
function withParams(url, queryParams) {
|
||||
let sep = "?";
|
||||
for (let paramName of Object.getOwnPropertyNames(queryParams)) {
|
||||
const paramValue = queryParams[paramName];
|
||||
if (!paramValue) continue;
|
||||
url += `${sep}${encodeURIComponent(paramName)}`;
|
||||
if (paramValue !== true) {
|
||||
url += `=${encodeURIComponent(paramValue)}`;
|
||||
}
|
||||
sep = "&";
|
||||
}
|
||||
}
|
||||
|
||||
function getJson(url, options={}) {
|
||||
if (!options.queryParams) options.queryParams = {};
|
||||
if (!options.headers) options.headers = {};
|
||||
options.headers["Accept"] = MIME_JSON;
|
||||
|
||||
const urlWithParams = withParams(url, options.queryParams);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let xhr = xhrInitForPromise(resolve, reject, url, "GET", options.headers);
|
||||
xhr.send();
|
||||
|
|
|
@ -42,3 +42,29 @@ h1 img {
|
|||
#login_server_row td, #login_server_row th {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
.post {
|
||||
margin: 1em 0;
|
||||
display: grid;
|
||||
grid-template-rows: auto auto;
|
||||
grid-template-columns: auto auto;
|
||||
}
|
||||
|
||||
.post .author {
|
||||
grid-row: 1;
|
||||
grid-column: 1;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.post .create_at {
|
||||
text-align: right;
|
||||
grid-row: 1;
|
||||
grid-column: 2;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.post .message {
|
||||
grid-row: 2;
|
||||
grid-column-start: 1;
|
||||
grid-column-end: 3;
|
||||
}
|
||||
|
|
70
main.js
70
main.js
|
@ -54,16 +54,16 @@ class MattermostApi {
|
|||
return this._endpoint;
|
||||
}
|
||||
|
||||
async get(path, token) {
|
||||
async get(path, token, queryParams) {
|
||||
const headers = token ? {"Authorization": `Bearer ${token}`} : {};
|
||||
const response = await ajax.getJson(`${this._endpoint}${path}`, {headers});
|
||||
const response = await ajax.getJson(`${this._endpoint}${path}`, {headers, queryParams});
|
||||
if (!response.ok) {
|
||||
throw response;
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
async post(path, data, token) {
|
||||
async post(path, token, data) {
|
||||
const headers = token ? {"Authorization": `Bearer ${token}`} : {};
|
||||
const response = await ajax.postJson(`${this._endpoint}${path}`, data, {headers});
|
||||
if (!response.ok) {
|
||||
|
@ -81,7 +81,7 @@ class MattermostClient {
|
|||
}
|
||||
|
||||
async logIn(login_id, password) {
|
||||
const response = await this.api.post("/users/login", {login_id, password});
|
||||
const response = await this.api.post("/users/login", undefined, {login_id, password});
|
||||
const token = response.getResponseHeader("Token");
|
||||
if (!token) {
|
||||
throw Error("No Token header in response to log in request");
|
||||
|
@ -95,7 +95,7 @@ class MattermostClient {
|
|||
if (!stored || !stored.token) {
|
||||
throw Error("No token stored");
|
||||
}
|
||||
const response = await this.api.post("/users/logout", undefined, stored.token);
|
||||
const response = await this.api.post("/users/logout", stored.token);
|
||||
|
||||
// Verify that the token is now invalidated
|
||||
let tokenWorks;
|
||||
|
@ -137,6 +137,14 @@ class MattermostClient {
|
|||
const response = await this.api.get(`/users/me/teams/${team_id}/channels`, stored.token);
|
||||
return response.responseJson;
|
||||
}
|
||||
|
||||
async channelPosts(channel_id, beforePost=null, afterPost=null, since=null) {
|
||||
const stored = this.storage.get(this.api.id);
|
||||
const response = await this.api.get(`/channels/${channel_id}/posts`, stored.token, {
|
||||
before: beforePost, after: afterPost, since
|
||||
});
|
||||
return response.responseJson;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -231,7 +239,7 @@ function populateChannelList() {
|
|||
a.innerText = `${channel.type} ${team.name}/${channel.name}`;
|
||||
break;
|
||||
}
|
||||
a.addEventListener("click", () => switchToChannel(team.id, channel.id));
|
||||
a.addEventListener("click", () => switchToChannel(client, team.id, channel.id));
|
||||
li.appendChild(a);
|
||||
nodes.push(li);
|
||||
}
|
||||
|
@ -248,6 +256,42 @@ function populateChannelList() {
|
|||
}
|
||||
populateChannelList();
|
||||
|
||||
function populateChannelContents(contents) {
|
||||
byId("channel_contents").innerHTML = "";
|
||||
|
||||
let nodes = [];
|
||||
for (let id of contents.order) {
|
||||
const post = contents.posts[id];
|
||||
|
||||
const isThreadReply = !!post.parent_id;
|
||||
|
||||
const messageDiv = document.createElement("div");
|
||||
messageDiv.className = "message";
|
||||
messageDiv.innerText = post.message;
|
||||
|
||||
const createAt = new Date(post.create_at);
|
||||
const createAtDiv = document.createElement("time");
|
||||
createAtDiv.className = "create_at";
|
||||
createAtDiv.innerText = createAt.toLocaleString("nl-BE");
|
||||
createAtDiv.dateTime = createAt.toISOString();
|
||||
|
||||
const authorDiv = document.createElement("div");
|
||||
authorDiv.className = "author";
|
||||
authorDiv.innerText = `Auteur: ${post.user_id}`;
|
||||
|
||||
const postDiv = document.createElement("div");
|
||||
postDiv.className = "post";
|
||||
postDiv.dataset["postid"] = id;
|
||||
postDiv.appendChild(authorDiv);
|
||||
postDiv.appendChild(createAtDiv);
|
||||
postDiv.appendChild(messageDiv);
|
||||
|
||||
nodes.unshift(postDiv);
|
||||
}
|
||||
|
||||
byId("channel_contents").append(...nodes);
|
||||
}
|
||||
|
||||
function logIn() {
|
||||
const client = createClient(byId("login_server").value);
|
||||
|
||||
|
@ -289,8 +333,20 @@ function logOut(endpoint, button) {
|
|||
});
|
||||
}
|
||||
|
||||
function switchToChannel(team_id, channel_id) {
|
||||
function switchToChannel(client, team_id, channel_id) {
|
||||
byId("channel_contents").innerText = "Loading…";
|
||||
window.location = "#channel_contents";
|
||||
|
||||
client.channelPosts(channel_id)
|
||||
.then(response => {
|
||||
console.info(`Got channel contents of ${channel_id}`);
|
||||
populateChannelContents(response);
|
||||
window.location = "#channel_contents";
|
||||
//})
|
||||
//.catch(error => {
|
||||
//console.error(error);
|
||||
//byId("channel_contents").innerText = `Failed to get channel contents:\n${error.message}`;
|
||||
});
|
||||
}
|
||||
|
||||
byId("login_button").addEventListener("click", logIn);
|
||||
|
|
Loading…
Reference in a new issue