feature: watches on the backend, need frontend implementation for
notifications and unread indicators
This commit is contained in:
parent
7046bb0389
commit
6293374bb7
28 changed files with 1405 additions and 608 deletions
|
|
@ -11,8 +11,12 @@
|
|||
|
||||
<link rel="stylesheet" href="./base.css"></link>
|
||||
|
||||
<script src="./js/_utils.js" type="text/javascript"></script>
|
||||
<script src="./js/api.js" type="text/javascript"></script>
|
||||
<!-- inlining these to force them to be scoped for everything else -->
|
||||
<script type="text/javascript"><!-- #include file="./js/_utils.js" --></script>
|
||||
<script type="text/javascript"><!-- #include file="./js/api.js" --></script>
|
||||
<script type="text/javascript"><!-- #include file="./js/app.js" --></script>
|
||||
|
||||
<!-- everything else -->
|
||||
<script src="./js/audioplayer.js" type="text/javascript"></script>
|
||||
<script src="./js/datetimeutils.js" type="text/javascript"></script>
|
||||
<script src="./js/debounce.js" type="text/javascript"></script>
|
||||
|
|
@ -49,191 +53,4 @@
|
|||
<!-- #include file="./tabs/tabs.html" -->
|
||||
</main>
|
||||
</body>
|
||||
<script>
|
||||
/* globals - sue me */
|
||||
const USERS = {
|
||||
_evict_timeouts: {},
|
||||
_update_timeouts: {},
|
||||
get: async (id, force) => {
|
||||
if ( force || !USERS[ id ] ) {
|
||||
USERS[ id ] = (await (await api.fetch(`/api/users/${id}`)).json());
|
||||
}
|
||||
|
||||
if ( !USERS._update_timeouts[ id ] ) {
|
||||
USERS._update_timeouts[ id ] = setInterval( () => {
|
||||
USERS.get( id, true );
|
||||
}, 1 * 60_000 );
|
||||
}
|
||||
|
||||
if ( !force ) {
|
||||
if ( USERS._evict_timeouts[ id ] ) {
|
||||
clearTimeout( USERS._evict_timeouts[ id ] );
|
||||
}
|
||||
|
||||
USERS._evict_timeouts[id] = setTimeout( () => {
|
||||
if ( USERS._update_timeouts[ id ] ) {
|
||||
clearTimeout( USERS._update_timeouts[ id ] );
|
||||
delete USERS._update_timeouts[ id ];
|
||||
}
|
||||
|
||||
delete USERS[ id ];
|
||||
}, 10 * 60_000 );
|
||||
}
|
||||
|
||||
return USERS[ id ];
|
||||
}
|
||||
};
|
||||
|
||||
const HASH_EXTRACTOR = /^\#\/topic\/(?<topic_id>[A-Za-z\-]+)\/?(?<view>\w+)?/gm;
|
||||
|
||||
function extract_url_hash_info() {
|
||||
HASH_EXTRACTOR.lastIndex = 0; // ugh, need this to have this work on multiple exec calls
|
||||
const {
|
||||
groups: { topic_id, view },
|
||||
} = HASH_EXTRACTOR.exec(window.location.hash ?? "") ?? {
|
||||
groups: {},
|
||||
};
|
||||
|
||||
console.dir({
|
||||
url: window.location.href,
|
||||
hash: window.location.hash,
|
||||
topic_id,
|
||||
view,
|
||||
});
|
||||
|
||||
if ( !document.body.dataset.topic || document.body.dataset.topic !== topic_id ) {
|
||||
const previous = document.body.dataset.topic;
|
||||
|
||||
console.dir( {
|
||||
topic_changed: {
|
||||
detail: {
|
||||
previous,
|
||||
topic_id
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
document.dispatchEvent(new CustomEvent( "topic_changed", {
|
||||
detail: {
|
||||
previous,
|
||||
topic_id
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
if ( !document.body.dataset.view || document.body.dataset.view !== view ) {
|
||||
const previous = document.body.dataset.view;
|
||||
document.body.dataset.view = view;
|
||||
|
||||
console.dir( {
|
||||
view_changed: {
|
||||
detail: {
|
||||
previous,
|
||||
view
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
document.dispatchEvent(new CustomEvent( "view_changed", {
|
||||
detail: {
|
||||
previous,
|
||||
view
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
window.addEventListener("locationchange", extract_url_hash_info);
|
||||
document.addEventListener( 'topic_changed', ( {detail: { topic_id }}) => {
|
||||
if ( !topic_id ) {
|
||||
const first_topic_id = TOPICS?.[0]?.id;
|
||||
if ( first_topic_id ) {
|
||||
window.location.hash = `/topic/${ first_topic_id }/chat`;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
document.body.dataset.topic = topic_id;
|
||||
});
|
||||
|
||||
let TOPICS = [];
|
||||
let last_topic_update = undefined;
|
||||
let update_topics_timeout = undefined;
|
||||
const UPDATE_TOPICS_FREQUENCY = 60_000;
|
||||
async function update_topics() {
|
||||
const now = new Date();
|
||||
const time_since_last_update = now - (last_topic_update ?? 0);
|
||||
if (time_since_last_update < UPDATE_TOPICS_FREQUENCY / 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( update_topics_timeout ) {
|
||||
clearTimeout( update_topics_timeout );
|
||||
update_topics_timeout = undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
const topics_response = await api.fetch("/api/topics");
|
||||
if (topics_response.ok) {
|
||||
const new_topics = await topics_response.json();
|
||||
const has_differences = TOPICS.length !== new_topics.length || new_topics.some( (topic, index) => {
|
||||
return ( TOPICS[ index ]?.id !== topic.id || TOPICS[ index ]?.name !== topic.name );
|
||||
});
|
||||
|
||||
if ( has_differences ) {
|
||||
TOPICS = new_topics;
|
||||
|
||||
document.dispatchEvent(new CustomEvent("topics_updated", { detail: { topics: TOPICS } }));
|
||||
}
|
||||
|
||||
last_topic_update = now;
|
||||
}
|
||||
}
|
||||
catch( error ) {
|
||||
console.error( error );
|
||||
}
|
||||
|
||||
update_topics_timeout = setTimeout( update_topics, UPDATE_TOPICS_FREQUENCY);
|
||||
|
||||
// now that we have topics, make sure our url is all good
|
||||
extract_url_hash_info();
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
window.addEventListener( 'locationchange', update_topics);
|
||||
document.addEventListener( 'user_logged_in', update_topics );
|
||||
|
||||
/* check if we are logged in */
|
||||
(async () => {
|
||||
try {
|
||||
const session_response = await api.fetch("/api/users/me");
|
||||
|
||||
if (!session_response.ok) {
|
||||
const error_body = await session_response.json();
|
||||
const error = error_body?.error;
|
||||
|
||||
console.dir({
|
||||
error_body,
|
||||
error,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const user = await session_response.json();
|
||||
|
||||
document.body.dataset.user = JSON.stringify( user );
|
||||
document.body.dataset.perms = user.permissions.join(":");
|
||||
|
||||
document.dispatchEvent(new CustomEvent("user_logged_in", { detail: { user } }));
|
||||
|
||||
} catch (error) {
|
||||
console.dir({
|
||||
error,
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
extract_url_hash_info();
|
||||
});
|
||||
|
||||
</script>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue