227 lines
6.4 KiB
Common Lisp
227 lines
6.4 KiB
Common Lisp
(text "{% extends \"root.html\" %} {% block head %}")
|
|
(title
|
|
(text "{{ config.name }}"))
|
|
|
|
(text "{% endblock %} {% block body %}")
|
|
(div
|
|
("id" "panel")
|
|
("class" "flex flex-row gap-2")
|
|
(a
|
|
("class" "button camo")
|
|
("href" "/")
|
|
(icon (text "house")))
|
|
|
|
(button
|
|
("class" "lowered")
|
|
("onclick" "back()")
|
|
(icon (text "arrow-left")))
|
|
|
|
(button
|
|
("class" "lowered")
|
|
("onclick" "forward()")
|
|
(icon (text "arrow-right")))
|
|
|
|
(button
|
|
("class" "lowered")
|
|
("onclick" "reload()")
|
|
(icon (text "rotate-cw")))
|
|
|
|
(form
|
|
("class" "w-full flex gap-1 flex-row")
|
|
("onsubmit" "event.preventDefault(); littleweb_navigate(event.target.uri.getAttribute('true_value'))")
|
|
(input
|
|
("type" "uri")
|
|
("class" "w-full")
|
|
("true_value" "")
|
|
("name" "uri")
|
|
("id" "uri"))
|
|
|
|
(button ("class" "lowered small square") (icon (text "arrow-right"))))
|
|
|
|
(text "{% if user -%}")
|
|
(div
|
|
("class" "dropdown")
|
|
(button
|
|
("class" "flex-row camo")
|
|
("onclick" "trigger('atto::hooks::dropdown', [event])")
|
|
("exclude" "dropdown")
|
|
("style" "gap: var(--pad-1) !important")
|
|
(text "{{ components::avatar(username=user.username, size=\"24px\") }}")
|
|
(icon_class (text "chevron-down") (text "dropdown_arrow")))
|
|
|
|
(text "{{ components::user_menu() }}"))
|
|
(text "{%- endif %}"))
|
|
|
|
(iframe
|
|
("id" "browser_iframe")
|
|
("frameborder" "0")
|
|
("src" "{% if path -%} {{ config.lw_host }}/api/v1/net/{{ path }}?s={{ session }} {%- endif %}"))
|
|
|
|
(style
|
|
("data-turbo-temporary" "true")
|
|
(text ":root {
|
|
--panel-height: 45px;
|
|
}
|
|
|
|
html,
|
|
body {
|
|
padding: 0;
|
|
margin: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
#panel {
|
|
width: 100dvw;
|
|
height: var(--panel-height);
|
|
padding: var(--pad-2);
|
|
}
|
|
|
|
#panel input {
|
|
border: none;
|
|
background: var(--color-lowered);
|
|
transition: background 0.15s;
|
|
}
|
|
|
|
#panel input:focus {
|
|
background: var(--color-super-lowered);
|
|
}
|
|
|
|
@media screen and (max-width: 900px) {
|
|
#panel input:focus {
|
|
position: fixed;
|
|
width: calc(100dvw - (62px + var(--pad-2) * 2)) !important;
|
|
left: var(--pad-2);
|
|
z-index: 2;
|
|
}
|
|
}
|
|
|
|
#panel button:not(.inner *),
|
|
#panel a.button:not(.inner *),
|
|
#panel input {
|
|
--h: 28.2px;
|
|
height: var(--h);
|
|
min-height: var(--h);
|
|
max-height: var(--h);
|
|
font-size: 16px;
|
|
}
|
|
|
|
#panel button:not(.inner *),
|
|
#panel a.button:not(.inner *) {
|
|
padding: var(--pad-1) var(--pad-2);
|
|
}
|
|
|
|
iframe {
|
|
width: 100dvw;
|
|
height: calc(100dvh - var(--panel-height));
|
|
}"))
|
|
|
|
(script
|
|
(text "globalThis.SECRET_SESSION = \"{{ session }}\";
|
|
function littleweb_navigate(uri) {
|
|
if (!uri.includes(\".html\")) {
|
|
uri = `${uri}/index.html`;
|
|
}
|
|
|
|
// ...
|
|
console.log(\"navigate\", uri);
|
|
document.getElementById(\"browser_iframe\").src = `{{ config.lw_host|safe }}/api/v1/net/${uri}?s={{ session }}`;
|
|
|
|
if (!uri.includes(\"atto://\")) {
|
|
document.getElementById(\"uri\").setAttribute(\"true_value\", `atto://${uri}`);
|
|
} else {
|
|
document.getElementById(\"uri\").setAttribute(\"true_value\", uri);
|
|
}
|
|
|
|
document.getElementById(\"uri\").value = uri.replace(\"atto://\", \"\").split(\"/\")[0];
|
|
}
|
|
|
|
document.getElementById(\"browser_iframe\").addEventListener(\"load\", (e) => {
|
|
console.log(\"web content loaded\");
|
|
});
|
|
|
|
window.addEventListener(\"message\", (e) => {
|
|
if (typeof e.data !== \"string\") {
|
|
console.log(\"refuse message (bad type)\");
|
|
return;
|
|
}
|
|
|
|
const data = JSON.parse(e.data);
|
|
|
|
if (!data.t) {
|
|
console.log(\"refuse message (not for tetratto)\");
|
|
return;
|
|
}
|
|
|
|
console.log(\"received message\");
|
|
|
|
if (data.event === \"change_url\") {
|
|
const uri = new URL(data.target).pathname.slice(\"/api/v1/net/\".length);
|
|
window.history.pushState(null, null, `/net/${uri.replace(\"atto://\", \"\")}`);
|
|
|
|
if (!uri.includes(\"atto://\")) {
|
|
document.getElementById(\"uri\").setAttribute(\"true_value\", `atto://${uri}`);
|
|
} else {
|
|
document.getElementById(\"uri\").setAttribute(\"true_value\", uri);
|
|
}
|
|
|
|
document.getElementById(\"uri\").value = uri.replace(\"atto://\", \"\").split(\"/\")[0];
|
|
}
|
|
});
|
|
|
|
function back() {
|
|
post_message({ t: true, event: \"back\" });
|
|
}
|
|
|
|
function forward() {
|
|
post_message({ t: true, event: \"forward\" });
|
|
}
|
|
|
|
function reload() {
|
|
post_message({ t: true, event: \"reload\" });
|
|
}
|
|
|
|
function post_message(data) {
|
|
const origin = new URL(document.getElementById(\"browser_iframe\").src).origin;
|
|
document.getElementById(\"browser_iframe\").contentWindow.postMessage(JSON.stringify(data), origin);
|
|
}
|
|
|
|
// handle dropdowns
|
|
window.addEventListener(\"blur\", () => {
|
|
trigger(\"atto::hooks::dropdown.close\");
|
|
});
|
|
|
|
// url bar focus
|
|
document.getElementById(\"uri\").addEventListener(\"input\", (e) => {
|
|
e.target.setAttribute(\"true_value\", e.target.value);
|
|
});
|
|
|
|
let is_focused = false;
|
|
|
|
document.getElementById(\"uri\").addEventListener(\"mouseenter\", (e) => {
|
|
e.target.value = e.target.getAttribute(\"true_value\").replace(\"/index.html\", \"\");
|
|
});
|
|
|
|
document.getElementById(\"uri\").addEventListener(\"mouseleave\", (e) => {
|
|
if (is_focused) {
|
|
return;
|
|
}
|
|
|
|
e.target.value = e.target.getAttribute(\"true_value\").replace(\"atto://\", \"\").split(\"/\")[0];
|
|
});
|
|
|
|
document.getElementById(\"uri\").addEventListener(\"focus\", (e) => {
|
|
e.target.value = e.target.getAttribute(\"true_value\").replace(\"/index.html\", \"\");
|
|
is_focused = true;
|
|
});
|
|
|
|
document.getElementById(\"uri\").addEventListener(\"blur\", (e) => {
|
|
e.target.value = e.target.getAttribute(\"true_value\").replace(\"atto://\", \"\").split(\"/\")[0];
|
|
is_focused = false;
|
|
});
|
|
|
|
// navigate
|
|
if ({{ path|length }} > 0) {
|
|
littleweb_navigate(\"{{ path|safe }}\");
|
|
}"))
|
|
|
|
(text "{% endblock %}")
|