refactor: some work to get initial page load working a bit better
This commit is contained in:
parent
200b89954b
commit
f276fe74da
3 changed files with 98 additions and 41 deletions
33
README.md
33
README.md
|
@ -26,22 +26,31 @@
|
|||
|
||||
## TODO
|
||||
|
||||
- [ ] should everything be an event in a room?
|
||||
- [X] sign up
|
||||
- [X] check for logged in user session
|
||||
- [X] log in
|
||||
- [X] chat rooms
|
||||
- [ ] gif support
|
||||
- [ ] media uploads
|
||||
- [ ] local upload support (keep it simple for small instances)
|
||||
- [ ] S3 support (then self-host with your friends: https://garagehq.deuxfleurs.fr/)
|
||||
- [ ] try to select immediate sibling messages from the same user and hide mulitple avatars
|
||||
- [X] chat messages
|
||||
- [ ] bulletin board instead of exchange/work?
|
||||
- [ ] should everything be an event in a room?
|
||||
- [ ] post-it style notes with tag and keyword filtering?
|
||||
- [X] user profile page
|
||||
- [ ] profile editing
|
||||
- [ ] avatar uploads
|
||||
- [ ] local upload support (keep it simple for small instances)
|
||||
- [ ] S3 support (then self-host with your friends: https://garagehq.deuxfleurs.fr/)
|
||||
- [ ] admin panel
|
||||
- [ ] add invite code generation
|
||||
- [ ] AC_REQUIRE_INVITE_CODE: boolean env var/setting
|
||||
- [ ] AC_DIRECTORY_SERVERS: |-separated list of directory servers to report to
|
||||
these central servers could be distributed directories - your town might run one,
|
||||
your state, your country, or you could publish to a public one that is organized
|
||||
around interests
|
||||
- [ ] combined "bulletin board" instead of exchange/work?
|
||||
- [ ] post-it style notes with tag and keyword filtering?
|
||||
- [ ] simple wiki for resources
|
||||
- [ ] simple calendar with public/private event tracking
|
||||
- [ ] caldav support?
|
||||
- [ ] add an optional env var where you can specify a list of
|
||||
"directory servers" (;-separated urls?) to ping with this
|
||||
server's existence - the idea being these central servers
|
||||
could be distributed directories - your town might run one,
|
||||
your state, your country, or you could publish to a public
|
||||
one that is organized around interests
|
||||
- [X] user profile page
|
||||
- [ ] user profile editing
|
||||
- [ ] caldav support
|
||||
|
|
|
@ -2,7 +2,13 @@
|
|||
window.addEventListener("locationchange", () => {
|
||||
const hash = window.location.hash?.slice(1);
|
||||
if (hash) {
|
||||
const target_tab = document.querySelector(`[data-hash="${hash}"]`);
|
||||
const target_tab_url = hash.slice(0, hash.slice(1).indexOf("/"));
|
||||
const target_tab = document.querySelector(`[data-hash="${target_tab_url}"]`);
|
||||
console.dir({
|
||||
hash,
|
||||
target_tab_url,
|
||||
target_tab,
|
||||
});
|
||||
if (target_tab) {
|
||||
target_tab.click();
|
||||
}
|
||||
|
|
|
@ -193,7 +193,22 @@
|
|||
async function append_room_events(events) {
|
||||
const room_chat_content = document.getElementById("room-chat-content");
|
||||
const users = {};
|
||||
let last_message_id = undefined;
|
||||
for (const event of events) {
|
||||
// if the last message is undefined, it becomes this event, otherwise, if this event's id is newer,
|
||||
// it becomes the latest message
|
||||
last_message_id =
|
||||
last_message_id === undefined
|
||||
? event.id
|
||||
: event.id > last_message_id
|
||||
? event.id
|
||||
: last_message_id;
|
||||
|
||||
// if the last message has been updated, update the content's dataset to reflect that
|
||||
if (last_message_id !== room_chat_content.dataset.last_message_id) {
|
||||
room_chat_content.dataset.last_message_id = last_message_id;
|
||||
}
|
||||
|
||||
users[event.creator_id] =
|
||||
users[event.creator_id] ??
|
||||
(await api.fetch(`/users/${event.creator_id}`));
|
||||
|
@ -203,13 +218,11 @@
|
|||
render_text_event(event, users[event.creator_id]),
|
||||
);
|
||||
}
|
||||
console.dir({
|
||||
users,
|
||||
events,
|
||||
room_chat_content,
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: we need some abortcontroller handling here or something
|
||||
// similar for when we change rooms, this is the most basic
|
||||
// first pass outline
|
||||
let room_polling_request_abort_controller = null;
|
||||
async function poll_for_new_events() {
|
||||
const room_chat_content = document.getElementById("room-chat-content");
|
||||
|
@ -222,7 +235,6 @@
|
|||
signal: room_polling_request_abort_controller.signal,
|
||||
})
|
||||
.then((new_events) => {
|
||||
const room;
|
||||
append_room_events(new_events);
|
||||
poll_for_new_events(room_id);
|
||||
})
|
||||
|
@ -236,7 +248,7 @@
|
|||
if (room_polling_request_abort_controller) {
|
||||
room_polling_request_abort_controller.abort();
|
||||
room_polling_request_abort_controller = null;
|
||||
last_message_id = null;
|
||||
delete room_chat_content.dataset.last_message_id;
|
||||
}
|
||||
|
||||
const room_response = await api.fetch(`/rooms/${room_id}`);
|
||||
|
@ -249,8 +261,17 @@
|
|||
const room = await room_response.json();
|
||||
const room_chat_content = document.getElementById("room-chat-content");
|
||||
|
||||
room_chat_content.dataset.room_id = room.id;
|
||||
room_chat_content.innerHTML = "";
|
||||
|
||||
const room_selectors = document.querySelectorAll("li.room");
|
||||
for (const room_selector of room_selectors) {
|
||||
room_selector.classList.remove("active");
|
||||
if (room_selector.id === `room-selector-${room_id}`) {
|
||||
room_selector.classList.add("active");
|
||||
}
|
||||
}
|
||||
|
||||
const events_response = await api.fetch(
|
||||
`/rooms/${room_id}/events?type=chat&limit=100&sort=newest`,
|
||||
);
|
||||
|
@ -265,32 +286,17 @@
|
|||
append_room_events(events);
|
||||
last_message_id = events.length ? events[events.length - 1].id : null;
|
||||
|
||||
room_polling_request_abort_controller = new AbortController();
|
||||
poll_for_new_events(room_id);
|
||||
}
|
||||
|
||||
// TODO: one place to handle switching rooms
|
||||
// TODO: load events when we switch rooms and clear and update the chat
|
||||
// TODO: try to select immediate siblings from the same user and hide avatars
|
||||
function check_for_room_in_url() {
|
||||
const hash = window.location.hash;
|
||||
const room_id =
|
||||
hash.indexOf("#/talk/room/") === 0 ? hash.substring(12) : "";
|
||||
const room_chat_container = document.getElementById("room-chat-container");
|
||||
room_chat_container.dataset.room_id = room_id;
|
||||
|
||||
const room_selectors = document.querySelectorAll("li.room");
|
||||
for (const room_selector of room_selectors) {
|
||||
room_selector.classList.remove("active");
|
||||
let last_room_update = undefined;
|
||||
async function update_chat_rooms() {
|
||||
const now = new Date();
|
||||
const time_since_last_update = now - (last_room_update ?? 0);
|
||||
if (time_since_last_update < 5_000) {
|
||||
return;
|
||||
}
|
||||
|
||||
const room_selector = document.getElementById(`room-selector-${room_id}`);
|
||||
room_selector.classList.add("active");
|
||||
load_room(room_id);
|
||||
}
|
||||
window.addEventListener("locationchange", check_for_room_in_url);
|
||||
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
const rooms_response = await api.fetch("/rooms");
|
||||
if (rooms_response.ok) {
|
||||
const room_list = document.getElementById("room-list");
|
||||
|
@ -302,8 +308,44 @@
|
|||
`<li id="room-selector-${room.id}" class="room"><a href="#/talk/room/${room.id}">${room.name}</a></li>`,
|
||||
);
|
||||
}
|
||||
|
||||
last_room_update = now;
|
||||
}
|
||||
}
|
||||
window.addEventListener("locationchange", update_chat_rooms);
|
||||
|
||||
function check_for_room_in_url() {
|
||||
const hash = window.location.hash;
|
||||
const talk_in_url = hash.indexOf("#/talk") === 0;
|
||||
if (!talk_in_url) {
|
||||
return;
|
||||
}
|
||||
|
||||
const first_room_id = document.querySelector("li.room")?.id.substring(14);
|
||||
|
||||
// #/talk/room/{room_id}
|
||||
// ^ 12
|
||||
const room_id = hash.substring(12) || first_room_id;
|
||||
|
||||
if (!room_id) {
|
||||
alert("failed to load chat room!");
|
||||
return;
|
||||
}
|
||||
|
||||
const room_chat_container = document.getElementById("room-chat-container");
|
||||
room_chat_container.dataset.room_id = room_id;
|
||||
|
||||
load_room(room_id);
|
||||
}
|
||||
window.addEventListener("locationchange", check_for_room_in_url);
|
||||
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
await update_chat_rooms();
|
||||
check_for_room_in_url();
|
||||
});
|
||||
|
||||
// TODO: this should be moved to be handled by a smartform
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
const chat_input = document.getElementById("room-chat-input");
|
||||
async function on_send_message(event) {
|
||||
event.preventDefault();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue