239 lines
6.5 KiB
HTML
239 lines
6.5 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>autonomous.contact</title>
|
|
|
|
<link rel="apple-touch-icon" sizes="180x180" href="./icons/apple-touch-icon.png" ></link>
|
|
<link rel="icon" type="image/png" sizes="32x32" href="./icons/favicon-32x32.png" ></link>
|
|
<link rel="icon" type="image/png" sizes="16x16" href="./icons/favicon-16x16.png" ></link>
|
|
|
|
<link rel="stylesheet" href="./base.css"></link>
|
|
|
|
<script src="./js/audioplayer.js" type="text/javascript"></script>
|
|
<script src="./js/datetimeutils.js" type="text/javascript"></script>
|
|
|
|
<script src="./js/embeds/audio.js" type="text/javascript"></script>
|
|
<script src="./js/embeds/gif.js" type="text/javascript"></script>
|
|
<script src="./js/embeds/image.js" type="text/javascript"></script>
|
|
<script src="./js/embeds/link.js" type="text/javascript"></script>
|
|
<script src="./js/embeds/mp4.js" type="text/javascript"></script>
|
|
<script src="./js/embeds/spotify.js" type="text/javascript"></script>
|
|
<script src="./js/embeds/tidal.js" type="text/javascript"></script>
|
|
<script src="./js/embeds/vimeo.js" type="text/javascript"></script>
|
|
<script src="./js/embeds/youtube.js" type="text/javascript"></script>
|
|
|
|
<script src="./js/htmlify.js" type="text/javascript"></script>
|
|
|
|
<script src="./js/locationchange.js" type="text/javascript"></script>
|
|
<script src="./js/notifications.js" type="text/javascript"></script>
|
|
<script src="./js/totp.js" type="text/javascript"></script>
|
|
<script src="./js/api.js" type="text/javascript"></script>
|
|
<script src="./js/smartforms.js" type="text/javascript"></script>
|
|
<script src="./js/textareaenhancements.js" type="text/javascript"></script>
|
|
</head>
|
|
<body>
|
|
<!-- #include file="./signup_login_wall.html" -->
|
|
|
|
<main>
|
|
<!-- #include file="./sidebar/sidebar.html" -->
|
|
|
|
<!-- #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 );
|
|
|
|
document.addEventListener( 'user_logged_in', () => {
|
|
const user = document.body.dataset.user && JSON.parse( document.body.dataset.user );
|
|
if ( !user ) {
|
|
return;
|
|
}
|
|
});
|
|
|
|
/* 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>
|