Support writing messages
This commit is contained in:
parent
26ebbcc190
commit
8983e0e504
5 changed files with 70 additions and 28 deletions
|
@ -55,7 +55,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="centered compose-wrapper">
|
<div class="centered compose-wrapper">
|
||||||
<textarea id="compose" disabled="disabled" oninput="" rows="1"></textarea>
|
<textarea id="compose" rows="1"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -139,3 +139,32 @@ function switchToChannel(client, team, channel) {
|
||||||
byId("channel_header").append(...elements);
|
byId("channel_header").append(...elements);
|
||||||
byId("compose").setAttribute("placeholder", `Write to ${byId("channel_header").textContent}`);
|
byId("compose").setAttribute("placeholder", `Write to ${byId("channel_header").textContent}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendMessage(endpoint, channel_id, message) {
|
||||||
|
const client = mm_client.get(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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkKeyPress(event) {
|
||||||
|
console.debug(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) {
|
||||||
|
sendMessage(
|
||||||
|
byId("channel_contents").dataset["server"],
|
||||||
|
byId("channel_contents").dataset["id"],
|
||||||
|
byId("compose").value
|
||||||
|
);
|
||||||
|
byId("compose").value = "";
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,13 @@
|
||||||
byId("server_selection_add").addEventListener("click", e => { e.stopPropagation(); e.preventDefault(); window.location = "#login"; return false; });
|
byId("server_selection_add").addEventListener("click", e => { e.stopPropagation(); e.preventDefault(); window.location = "#login"; return false; });
|
||||||
byId("login").addEventListener("submit", e => { logIn(); e.stopPropagation(); e.preventDefault(); return false; });
|
byId("login").addEventListener("submit", e => { logIn(); e.stopPropagation(); e.preventDefault(); return false; });
|
||||||
byId("login_no_button").addEventListener("click", e => { e.stopPropagation(); e.preventDefault(); window.location = "#"; return false; });
|
byId("login_no_button").addEventListener("click", e => { e.stopPropagation(); e.preventDefault(); window.location = "#"; return false; });
|
||||||
|
byId("compose").addEventListener("keydown", e => {
|
||||||
|
if (checkKeyPress(e)) {
|
||||||
|
e.stopPropagation(); e.preventDefault();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
updateComposeHeight();
|
updateComposeHeight();
|
||||||
checkScrolledToBottom();
|
checkScrolledToBottom();
|
||||||
|
|
|
@ -11,21 +11,24 @@ class MattermostClient {
|
||||||
console.info(`Created MattermostClient for ${this.endpoint}, ${this.token ? "found token" : "did not find token"}`);
|
console.info(`Created MattermostClient for ${this.endpoint}, ${this.token ? "found token" : "did not find token"}`);
|
||||||
|
|
||||||
if (this.token) {
|
if (this.token) {
|
||||||
this.websocket();
|
this.userMe().then(data => {
|
||||||
|
this.me = data;
|
||||||
|
this.websocket();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async get(path, token, queryParams) {
|
async get(path, queryParams) {
|
||||||
const headers = token ? {"Authorization": `Bearer ${token}`} : {};
|
const headers = this.token ? {"Authorization": `Bearer ${this.token}`} : {};
|
||||||
const response = await ajax.getJson(`${this.endpoint}${path}`, {headers, queryParams});
|
const response = await ajax.getJson(`${this.endpoint}${path}`, {headers, queryParams});
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw response;
|
throw response;
|
||||||
}
|
}
|
||||||
return response;
|
return response.responseJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
async post(path, token, data) {
|
async post(path, data) {
|
||||||
const headers = token ? {"Authorization": `Bearer ${token}`} : {};
|
const headers = this.token ? {"Authorization": `Bearer ${this.token}`} : {};
|
||||||
const response = await ajax.postJson(`${this.endpoint}${path}`, data, {headers});
|
const response = await ajax.postJson(`${this.endpoint}${path}`, data, {headers});
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw response;
|
throw response;
|
||||||
|
@ -33,14 +36,7 @@ class MattermostClient {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
async authedGet(url, queryParams) {
|
async paginatedGet(url, queryParams, perPage=200) {
|
||||||
assert(this.token, "logged in");
|
|
||||||
const response = await this.get(url, this.token, queryParams);
|
|
||||||
return response.responseJson;
|
|
||||||
}
|
|
||||||
|
|
||||||
async authedPaginatedGet(url, queryParams, perPage=200) {
|
|
||||||
assert(this.token, "logged in");
|
|
||||||
let data = [];
|
let data = [];
|
||||||
|
|
||||||
let params = {page: 0, per_page: perPage};
|
let params = {page: 0, per_page: perPage};
|
||||||
|
@ -51,13 +47,13 @@ class MattermostClient {
|
||||||
let loadMore = true;
|
let loadMore = true;
|
||||||
while (loadMore) {
|
while (loadMore) {
|
||||||
if (params.page > 100) {
|
if (params.page > 100) {
|
||||||
throw new Error("Requesting more than 100 pages, something looks wrong");
|
throw new Error("Requesting more than 100 pages, something looks wrong or the response is massive (>20,000 items)");
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await this.get(url, this.token, params);
|
const response = await this.get(url, params);
|
||||||
data = data.concat(response.responseJson);
|
data = data.concat(response);
|
||||||
|
|
||||||
loadMore = response.responseJson.length > 0;
|
loadMore = response.length > 0;
|
||||||
params.page++;
|
params.page++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +89,10 @@ class MattermostClient {
|
||||||
this.credentials.store(this.endpoint, login_id, token);
|
this.credentials.store(this.endpoint, login_id, token);
|
||||||
this.token = token;
|
this.token = token;
|
||||||
let _ = this.getUsers();
|
let _ = this.getUsers();
|
||||||
this.websocket();
|
this.userMe().then(data => {
|
||||||
|
this.me = data;
|
||||||
|
this.websocket();
|
||||||
|
});
|
||||||
return response.responseJson;
|
return response.responseJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,28 +118,35 @@ class MattermostClient {
|
||||||
|
|
||||||
user(user_id) {
|
user(user_id) {
|
||||||
assertIsMattermostId(user_id);
|
assertIsMattermostId(user_id);
|
||||||
return this.authedGet(`/users/${user_id}`);
|
return this.get(`/users/${user_id}`);
|
||||||
}
|
}
|
||||||
userMe() { return this.authedGet("/users/me"); }
|
userMe() { return this.get("/users/me"); }
|
||||||
myTeams() { return this.authedGet("/users/me/teams"); }
|
myTeams() { return this.get("/users/me/teams"); }
|
||||||
|
|
||||||
myChannels(team_id) {
|
myChannels(team_id) {
|
||||||
assertIsMattermostId(team_id);
|
assertIsMattermostId(team_id);
|
||||||
return this.authedGet(`/users/me/teams/${team_id}/channels`);
|
return this.get(`/users/me/teams/${team_id}/channels`);
|
||||||
}
|
}
|
||||||
|
|
||||||
channelPosts(channel_id, beforePost=null, afterPost=null, since=null) {
|
channelPosts(channel_id, beforePost=null, afterPost=null, since=null) {
|
||||||
assertIsMattermostId(channel_id);
|
assertIsMattermostId(channel_id);
|
||||||
assertIsNullOrMattermostId(beforePost);
|
assertIsNullOrMattermostId(beforePost);
|
||||||
assertIsNullOrMattermostId(afterPost);
|
assertIsNullOrMattermostId(afterPost);
|
||||||
return this.authedGet(`/channels/${channel_id}/posts`, {
|
return this.get(`/channels/${channel_id}/posts`, {
|
||||||
before: beforePost, after: afterPost, since
|
before: beforePost, after: afterPost, since
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writePost(channel_id, message) {
|
||||||
|
return this.post("/posts", {
|
||||||
|
"channel_id": channel_id,
|
||||||
|
"message": message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
getUsers() {
|
getUsers() {
|
||||||
if (!this.users) {
|
if (!this.users) {
|
||||||
this.users = this.authedPaginatedGet("/users", {}).then(users => {
|
this.users = this.paginatedGet("/users", {}).then(users => {
|
||||||
const newUsers = Object.create(null);
|
const newUsers = Object.create(null);
|
||||||
for (let user_data of users) {
|
for (let user_data of users) {
|
||||||
const user = user_data;
|
const user = user_data;
|
||||||
|
@ -153,7 +159,7 @@ class MattermostClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
async filePublicLink(file_id) {
|
async filePublicLink(file_id) {
|
||||||
const response = await this.authedGet(`/files/${file_id}/link`, {});
|
const response = await this.get(`/files/${file_id}/link`, {});
|
||||||
return response.link;
|
return response.link;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ async function createMessageElement(client, post, lastTime, lastAuthor) {
|
||||||
postDiv.appendChild(createAtDiv);
|
postDiv.appendChild(createAtDiv);
|
||||||
postDiv.appendChild(messageDiv);
|
postDiv.appendChild(messageDiv);
|
||||||
|
|
||||||
if ((post.metadata.files || []).length > 0) {
|
if (post.metadata && (post.metadata.files || []).length > 0) {
|
||||||
const attachmentsUl = document.createElement("ul");
|
const attachmentsUl = document.createElement("ul");
|
||||||
attachmentsUl.className = "attachments";
|
attachmentsUl.className = "attachments";
|
||||||
for (let file of post.metadata.files || []) {
|
for (let file of post.metadata.files || []) {
|
||||||
|
|
Loading…
Reference in a new issue