add: user account switcher

This commit is contained in:
trisua 2025-04-03 22:36:58 -04:00
parent 48e0b02198
commit 20aae5570b
13 changed files with 172 additions and 34 deletions

View file

@ -48,6 +48,12 @@
]);
if (res.ok) {
// update tokens
const new_tokens = ns("me").LOGIN_ACCOUNT_TOKENS;
new_tokens[e.target.username.value] = res.message;
trigger("me::set_login_account_tokens", [new_tokens]);
// redirect
setTimeout(() => {
window.location.href = "/";
}, 150);

View file

@ -100,6 +100,12 @@
]);
if (res.ok) {
// update tokens
const new_tokens = ns("me").LOGIN_ACCOUNT_TOKENS;
new_tokens[e.target.username.value] = res.message;
trigger("me::set_login_account_tokens", [new_tokens]);
// redirect
setTimeout(() => {
window.location.href = "/";
}, 150);

View file

@ -107,6 +107,11 @@ show_lhs=true) -%}
</a>
<div class="title"></div>
<button onclick="trigger('me::switch_account')">
{{ icon "ellipsis" }}
<span>{{ text "general:action.switch_account" }}</span>
</button>
<button class="red" onclick="trigger('me::logout')">
{{ icon "log-out" }}
<span>{{ text "auth:action.logout" }}</span>

View file

@ -1,5 +1,5 @@
{% import "macros.html" as macros %} {% extends "profile/base.html" %} {% block
content %} {% if config.town_square %}
content %} {% if config.town_square and is_self %}
<div class="card-nest">
<div class="card small flex flex-col">
<div class="flex items-center gap-2">

View file

@ -109,6 +109,12 @@
atto["hooks::check_reactions"]();
atto["hooks::tabs"]();
atto["hooks::partial_embeds"]();
if (document.getElementById("tokens")) {
trigger("me::render_token_picker", [
document.getElementById("tokens"),
]);
}
});
</script>
@ -257,5 +263,38 @@
</form>
</div>
</dialog>
{% 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>
<a href="/auth/login" class="button" data-turbo="false">
{{ icon "plus" }}
<span>{{ text "general:action.add_account" }}</span>
</a>
<div class="flex justify-between">
<div></div>
<div class="flex gap-2">
<button
class="quaternary"
onclick="document.getElementById('tokens_dialog').close()"
type="button"
>
{{ icon "check" }}
<span>{{ text "dialog:action.okay" }}</span>
</button>
</div>
</div>
</form>
</div>
</dialog>
{% endif %}
</body>
</html>

View file

@ -1,6 +1,10 @@
(() => {
const self = reg_ns("me");
self.LOGIN_ACCOUNT_TOKENS = JSON.parse(
window.localStorage.getItem("atto:login_account_tokens") || "{}",
);
self.define("logout", async () => {
if (
!(await trigger("atto::confirm", [
@ -162,4 +166,48 @@
}
});
});
// token switcher
self.define(
"set_login_account_tokens",
({ $ }, value) => {
$.LOGIN_ACCOUNT_TOKENS = value;
window.localStorage.setItem(
"atto:login_account_tokens",
JSON.stringify(value),
);
},
["object"],
);
self.define("login", ({ $ }, username) => {
const token = self.LOGIN_ACCOUNT_TOKENS[username];
if (!token) {
return;
}
window.location.href = `/api/v1/auth/token?token=${token}`;
});
self.define("render_token_picker", ({ $ }, element) => {
element.innerHTML = "";
for (const token of Object.entries($.LOGIN_ACCOUNT_TOKENS)) {
element.innerHTML += `<button class="quaternary w-full justify-start" onclick="trigger('me::login', ['${token[0]}'])">
<img
title="${token[0]}'s avatar"
src="/api/v1/auth/profile/${token[0]}/avatar?selector_type=username"
alt="Avatar image"
class="avatar"
style="--size: 24px"
/>
<span>${token[0]}</span>
</button>`;
}
});
self.define("switch_account", () => {
document.getElementById("tokens_dialog").showModal();
});
})();