chat page kinda sorta works, needs lots of polish
This commit is contained in:
parent
34f44cb5d5
commit
ee66563717
@ -85,26 +85,27 @@ const call = async (route, opts = {}) => {
|
|||||||
const ws = async (route, opts = {}) => {
|
const ws = async (route, opts = {}) => {
|
||||||
const {
|
const {
|
||||||
requiresPow = false,
|
requiresPow = false,
|
||||||
|
params = {},
|
||||||
} = opts;
|
} = opts;
|
||||||
|
|
||||||
const docURL = new URL(document.URL);
|
const docURL = new URL(document.URL);
|
||||||
const protocol = docURL.protocol == "http:" ? "ws:" : "wss:";
|
const protocol = docURL.protocol == "http:" ? "ws:" : "wss:";
|
||||||
|
|
||||||
const params = new URLSearchParams();
|
const fullParams = new URLSearchParams(params);
|
||||||
const csrfToken = utils.cookies[csrfTokenCookie];
|
const csrfToken = utils.cookies[csrfTokenCookie];
|
||||||
|
|
||||||
if (!csrfToken)
|
if (!csrfToken)
|
||||||
throw `${csrfTokenCookie} cookie not set, can't make api call`;
|
throw `${csrfTokenCookie} cookie not set, can't make api call`;
|
||||||
|
|
||||||
params.set("csrfToken", csrfToken);
|
fullParams.set("csrfToken", csrfToken);
|
||||||
|
|
||||||
if (requiresPow) {
|
if (requiresPow) {
|
||||||
const {seed, solution} = await solvePow();
|
const {seed, solution} = await solvePow();
|
||||||
params.set("powSeed", seed);
|
fullParams.set("powSeed", seed);
|
||||||
params.set("powSolution", solution);
|
fullParams.set("powSolution", solution);
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawConn = new WebSocket(`${protocol}//${docURL.host}${route}?${params.toString()}`);
|
const rawConn = new WebSocket(`${protocol}//${docURL.host}${route}?${fullParams.toString()}`);
|
||||||
|
|
||||||
const conn = {
|
const conn = {
|
||||||
next: () => new Promise((resolve, reject) => {
|
next: () => new Promise((resolve, reject) => {
|
||||||
|
@ -8,6 +8,7 @@ layout: page
|
|||||||
#messages {
|
#messages {
|
||||||
max-height: 65vh;
|
max-height: 65vh;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
padding-right: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#messages .message {
|
#messages .message {
|
||||||
@ -43,14 +44,17 @@ layout: page
|
|||||||
|
|
||||||
const messagesEl = document.getElementById("messages");
|
const messagesEl = document.getElementById("messages");
|
||||||
|
|
||||||
function renderMessages(msgs) {
|
let messagesScrolledToBottom = true;
|
||||||
|
messagesEl.onscroll = () => {
|
||||||
|
const el = messagesEl;
|
||||||
|
messagesScrolledToBottom = el.scrollHeight == el.scrollTop + el.clientHeight;
|
||||||
|
};
|
||||||
|
|
||||||
msgs = [...msgs].reverse();
|
function renderMessages(msgs) {
|
||||||
|
|
||||||
messagesEl.innerHTML = '';
|
messagesEl.innerHTML = '';
|
||||||
|
|
||||||
msgs.forEach((msg) => {
|
msgs.forEach((msg) => {
|
||||||
console.log(msg);
|
|
||||||
const el = document.createElement("div");
|
const el = document.createElement("div");
|
||||||
el.className = "row message"
|
el.className = "row message"
|
||||||
|
|
||||||
@ -97,15 +101,39 @@ function renderMessages(msgs) {
|
|||||||
(async () => {
|
(async () => {
|
||||||
|
|
||||||
const failEl = document.getElementById("fail");
|
const failEl = document.getElementById("fail");
|
||||||
|
|
||||||
setErr = (msg) => failEl.innerHTML = `${msg} (please refresh the page to retry)`;
|
setErr = (msg) => failEl.innerHTML = `${msg} (please refresh the page to retry)`;
|
||||||
|
|
||||||
const api = await import("/assets/api.js");
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
const api = await import("/assets/api.js");
|
||||||
|
|
||||||
const history = await api.call("/api/chat/global/history");
|
const history = await api.call("/api/chat/global/history");
|
||||||
renderMessages(history.messages);
|
const msgs = history.messages;
|
||||||
|
|
||||||
|
// history returns msgs in time descending, but we display them in time
|
||||||
|
// ascending.
|
||||||
|
msgs.reverse()
|
||||||
|
|
||||||
|
const sinceID = (msgs.length > 0) ? msgs[msgs.length-1].id : "";
|
||||||
|
|
||||||
|
const ws = await api.ws("/api/chat/global/listen", {
|
||||||
|
params: { sinceID },
|
||||||
|
});
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
renderMessages(msgs);
|
||||||
|
|
||||||
|
// If the user was previously scrolled to the bottom then keep them
|
||||||
|
// there.
|
||||||
|
if (messagesScrolledToBottom) {
|
||||||
|
messagesEl.scrollTop = messagesEl.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
const msg = await ws.next();
|
||||||
|
msgs.push(msg.message);
|
||||||
|
renderMessages(msgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
e = `Failed to fetch message history: ${e}`
|
e = `Failed to fetch message history: ${e}`
|
||||||
@ -114,13 +142,107 @@ function renderMessages(msgs) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//const ws = await api.ws("/api/chat/global/listen");
|
|
||||||
|
|
||||||
//while (true) {
|
|
||||||
// const msg = await ws.next();
|
|
||||||
// console.log("got msg", msg);
|
|
||||||
//}
|
|
||||||
|
|
||||||
})()
|
})()
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#append {
|
||||||
|
border: 1px dashed #AAA;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#append #appendBody {
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
#append #appendStatus {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<form id="append">
|
||||||
|
<h5>New Message</h5>
|
||||||
|
<div class="row">
|
||||||
|
<div class="columns four">
|
||||||
|
<input class="u-full-width" placeholder="Name" id="appendName" type="text" />
|
||||||
|
<input class="u-full-width" placeholder="Secret" id="appendSecret" type="password" />
|
||||||
|
</div>
|
||||||
|
<div class="columns eight">
|
||||||
|
<p>
|
||||||
|
Your name is displayed alongside your message.
|
||||||
|
|
||||||
|
Your name+secret is used to generate your userID, which is also
|
||||||
|
displayed alongside your message.
|
||||||
|
|
||||||
|
Other users can validate two messages are from the same person
|
||||||
|
by comparing the messages' userID.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="columns twelve">
|
||||||
|
<textarea
|
||||||
|
style="font-family: monospace"
|
||||||
|
id="appendBody"
|
||||||
|
class="u-full-width"
|
||||||
|
placeholder="Well thought out statement goes here..."
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="columns four">
|
||||||
|
<input class="u-full-width button-primary" id="appendSubmit" type="button" value="Submit" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span id="appendStatus"></span>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
const append = document.getElementById("append");
|
||||||
|
const appendName = document.getElementById("appendName");
|
||||||
|
const appendSecret = document.getElementById("appendSecret");
|
||||||
|
const appendBody = document.getElementById("appendBody");
|
||||||
|
const appendSubmit = document.getElementById("appendSubmit");
|
||||||
|
const appendStatus = document.getElementById("appendStatus");
|
||||||
|
|
||||||
|
appendSubmit.onclick = async () => {
|
||||||
|
|
||||||
|
const appendSubmitOrigValue = appendSubmit.value;
|
||||||
|
|
||||||
|
appendSubmit.disabled = true;
|
||||||
|
appendSubmit.className = "";
|
||||||
|
appendSubmit.value = "Please hold...";
|
||||||
|
|
||||||
|
appendStatus.innerHTML = '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
const api = await import("/assets/api.js");
|
||||||
|
|
||||||
|
await api.call('/api/chat/global/append', {
|
||||||
|
body: {
|
||||||
|
name: appendName.value,
|
||||||
|
password: appendSecret.value,
|
||||||
|
body: appendBody.value,
|
||||||
|
},
|
||||||
|
requiresPow: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
appendBody.value = '';
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
|
appendStatus.innerHTML = e;
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
appendSubmit.disabled = false;
|
||||||
|
appendSubmit.className = "button-primary";
|
||||||
|
appendSubmit.value = appendSubmitOrigValue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
Loading…
Reference in New Issue
Block a user