tetratto/crates/app/src/public/html/body.lisp

328 lines
11 KiB
Common Lisp
Raw Normal View History

(div ("id" "toast_zone"))
; templates
(template
("id" "loading_skeleton")
(div
("class" "flex flex-col gap-2")
("ui_ident" "loading_skel")
(div
("class" "card lowered green flex items-center gap-2")
(div ("class" "loader") (icon (text "loader-circle")))
(span (str (text "general:label.loading"))))
(div
("class" "card secondary flex gap-2")
(div ("class" "skel avatar"))
(div
("class" "flex flex-col gap-2 w-full")
(div ("class" "skel") ("style" "width: 25%; height: 25px;"))
(div ("class" "skel") ("style" "width: 100%; height: 150px"))))))
; random js
(text "<script data-turbo-permanent=\"true\" id=\"init-script\">
document.documentElement.addEventListener(\"turbo:load\", () => {
const atto = ns(\"atto\");
if (!atto) {
window.location.reload();
return;
}
atto.disconnect_observers();
atto.remove_false_options();
atto.clean_date_codes();
atto.clean_poll_date_codes();
atto.link_filter();
atto[\"hooks::scroll\"](document.body, document.documentElement);
atto[\"hooks::dropdown.init\"](window);
atto[\"hooks::character_counter.init\"]();
atto[\"hooks::long_text.init\"]();
atto[\"hooks::alt\"]();
atto[\"hooks::online_indicator\"]();
atto[\"hooks::ips\"]();
atto[\"hooks::check_reactions\"]();
atto[\"hooks::tabs\"]();
atto[\"hooks::spotify_time_text\"](); // spotify durations
atto[\"hooks::verify_emoji\"]();
if (document.getElementById(\"tokens\")) {
trigger(\"me::render_token_picker\", [
document.getElementById(\"tokens\"),
]);
}
setTimeout(() => {
trigger(\"me::notifications_stream\");
}, 250);
});
</script>")
(text "{% if user -%}
<script data-turbo-permanent=\"true\" id=\"update-seen-script\">
document.documentElement.addEventListener(\"turbo:load\", () => {
trigger(\"me::seen\");
trigger(\"streams::user\", [\"{{ user.id }}\"]);
if (!window.location.pathname.startsWith(\"/chats/\")) {
if (window.socket) {
window.socket.send(\"Close\");
window.socket = undefined;
console.log(\"socket disconnect\");
}
}
if (window.location.pathname.startsWith(\"/reference\")) {
window.location.reload();
}
});
</script>
{%- endif %}")
; dialogs
(dialog
("id" "link_filter")
(div
("class" "inner flex flex-col gap-2")
; warning stuff
(p (text "Pressing continue will bring you to the following URL:"))
(pre (code ("id" "link_filter_url")))
(p (text "Are sure you want to go there?"))
(hr ("class" "margin"))
(div
("class" "flex gap-2")
(a
("class" "button primary")
("id" "link_filter_continue")
("rel" "noopener noreferrer")
("target" "_blank")
("onclick", "document.getElementById('link_filter').close()")
(icon (text "external-link"))
(str (text "dialog:action.continue")))
(button
("class" "secondary")
("type" "button")
("onclick", "document.getElementById('link_filter').close()")
(icon (text "x"))
(str (text "dialog:action.cancel"))))))
(dialog
("id" "web_api_prompt")
(div
("class" "inner flex flex-col gap-2")
(form
("class" "flex gap-2 flex-col")
("onsubmit" "event.preventDefault()")
(label ("for" "prompt") ("id" "web_api_prompt:msg"))
(input ("id" "prompt") ("name" "prompt"))
(div
("class" "flex justify-between")
(div null?)
(div
("class" "flex gap-2")
(button
("class" "primary bold circle")
("onclick", "globalThis.web_api_prompt_submit(document.getElementById('prompt').value); document.getElementById('prompt').value = ''")
("type" "button")
(icon (text "check"))
(str (text "dialog:action.okay")))
(button
("class" "bold red camo")
("onclick", "globalThis.web_api_prompt_submit('')")
("type" "button")
(icon (text "x"))
(str (text "dialog:action.cancel"))))))))
(dialog
("id" "web_api_prompt_long")
(div
("class" "inner flex flex-col gap-2")
(form
("class" "flex gap-2 flex-col")
("onsubmit" "event.preventDefault()")
(label ("for" "prompt_long") ("id" "web_api_prompt_long:msg"))
(input ("id" "prompt_long") ("name" "prompt_long"))
(div
("class" "flex justify-between")
(div null?)
(div
("class" "flex gap-2")
(button
("class" "primary bold circle")
("onclick", "globalThis.web_api_prompt_long_submit(document.getElementById('prompt_long').value); document.getElementById('prompt_long').value = ''")
("type" "button")
(icon (text "check"))
(str (text "dialog:action.okay")))
(button
("class" "bold red camo")
("onclick", "globalThis.web_api_prompt_long_submit('')")
("type" "button")
(icon (text "x"))
(str (text "dialog:action.cancel"))))))))
(dialog
("id" "web_api_confirm")
(div
("class" "inner flex flex-col gap-2")
(form
("class" "flex gap-2 flex-col")
("onsubmit" "event.preventDefault()")
(span ("id" "web_api_confirm:msg"))
(div
("class" "flex justify-between")
(div null?)
(div
("class" "flex gap-2")
(button
("class" "primary bold circle")
("onclick", "globalThis.web_api_confirm_submit(true)")
("type" "button")
(icon (text "check"))
(str (text "dialog:action.yes")))
(button
("class" "bold red camo")
("onclick", "globalThis.web_api_confirm_submit(false)")
("type" "button")
(icon (text "x"))
(str (text "dialog:action.no"))))))))
(div
("class" "lightbox hidden")
("id" "lightbox")
(button
("class" "lightbox_exit small square lowered red")
("onclick" "trigger('ui::lightbox_close')")
(icon (text "x")))
(a
("href" "")
("id" "lightbox_img_a")
("target" "_blank")
(img ("id" "lightbox_img") ("loading" "lazy"))))
; tokens dialog
(text "{% if user -%}")
(dialog
("id" "tokens_dialog")
(div
("class" "inner flex flex-col gap-2")
(form
("class" "flex gap-2 flex-col")
("onsubmit" "event.preventDefault()")
(div ("id" "tokens") ("style" "display: contents"))
(div
("class" "flex justify-between")
(a
("href" "/auth/login")
("class" "button")
("data-turbo", "false")
(icon (text "plus"))
(span (str (text "general:action.add_account"))))
(button
("class" "lowered")
("onclick" "document.getElementById('tokens_dialog').close()")
("type" "button")
(icon (text "check")))))))
; user scripts
(text "{%- endif %} {% if user and use_user_theme -%} {{ components::theme(user=user, theme_preference=user.settings.theme_preference) }}
<script>
setTimeout(() => {
trigger(\"atto::use_theme_preference\");
}, 150);
</script>
{%- endif %} {% if user and user.connections.Spotify and config.connections.spotify_client_id and user.connections.Spotify[0].data.token and user.connections.Spotify[0].data.refresh_token %}
<script>
setTimeout(async () => {
if (window.spotify_init) {
return;
}
window.spotify_init = true;
const client_id = \"{{ config.connections.spotify_client_id }}\";
let token = \"{{ user.connections.Spotify[0].data.token }}\";
let refresh_token =
\"{{ user.connections.Spotify[0].data.refresh_token }}\";
if (token) {
// we already have a token
const pull_playing = async () => {
const playing = await trigger(\"spotify::get_playing\", [
token,
]);
if (playing.error) {
// refresh token
const [new_token, new_refresh_token, expires_in] =
await trigger(\"spotify::refresh_token\", [
client_id,
refresh_token,
]);
await trigger(\"connections::push_con_data\", [
\"Spotify\",
{
token: new_token,
expires_in: expires_in.toString(),
name: profile.display_name,
},
]);
token = new_token;
refresh_token = new_refresh_token;
return;
}
await trigger(\"spotify::publish_playing\", [playing]);
};
await pull_playing();
setInterval(pull_playing, 30_000);
} else {
window.spotify_needs_token = true;
}
}, 150);
</script>
{% elif user and user.connections.LastFm and config.connections.last_fm_key and user.connections.LastFm[0].data.session_token %}
<script>
setTimeout(async () => {
if (window.last_fm_init) {
return;
}
window.last_fm_init = true;
const user = \"{{ user.connections.LastFm[0].data.name }}\";
const session_token =
\"{{ user.connections.LastFm[0].data.session_token }}\";
if (session_token) {
// we already have a token
const pull_playing = async () => {
const playing = await trigger(\"last_fm::get_playing\", [
user,
session_token,
]);
await trigger(\"last_fm::publish_playing\", [playing]);
};
await pull_playing();
setInterval(pull_playing, 30_000);
} else {
window.last_fm_needs_token = true;
}
}, 150);
</script>
{%- endif %}")