feat: Refactor session management UI and enhance accessibility features
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
|
const sessionSectionEl = document.querySelector("#session-section");
|
||||||
const sessionStatusEl = document.querySelector("#session-status");
|
const sessionStatusEl = document.querySelector("#session-status");
|
||||||
const sessionUserEl = document.querySelector("#session-user");
|
const sessionUserEl = document.querySelector("#session-user");
|
||||||
const loginFeedbackEl = document.querySelector("#login-feedback");
|
const loginFeedbackEl = document.querySelector("#login-feedback");
|
||||||
const sessionSummaryTextEl = document.querySelector("#session-summary-text");
|
const sessionSummaryTextEl = document.querySelector("#session-summary-text");
|
||||||
const sessionDetailsEl = document.querySelector("#session-details");
|
|
||||||
const toggleSessionBtn = document.querySelector("#toggle-session");
|
const toggleSessionBtn = document.querySelector("#toggle-session");
|
||||||
|
const sessionCardToggleBtn = document.querySelector("#session-card-toggle");
|
||||||
const startLoginForm = document.querySelector("#start-login-form");
|
const startLoginForm = document.querySelector("#start-login-form");
|
||||||
const verifyLoginForm = document.querySelector("#verify-login-form");
|
const verifyLoginForm = document.querySelector("#verify-login-form");
|
||||||
const logoutButton = document.querySelector("#logout-button");
|
const logoutButton = document.querySelector("#logout-button");
|
||||||
@@ -18,8 +19,8 @@ const recentChatsListEl = document.querySelector("#recent-chats-list");
|
|||||||
const closeRecentChatsBtn = document.querySelector("#close-recent-chats");
|
const closeRecentChatsBtn = document.querySelector("#close-recent-chats");
|
||||||
const recentChatsSearchEl = document.querySelector("#recent-chats-search");
|
const recentChatsSearchEl = document.querySelector("#recent-chats-search");
|
||||||
|
|
||||||
let sessionDetailsVisible = false;
|
let sessionCardVisible = false;
|
||||||
let sessionDetailsTouched = false;
|
let sessionCardTouched = false;
|
||||||
let createFormVisible = false;
|
let createFormVisible = false;
|
||||||
let createFormTouched = false;
|
let createFormTouched = false;
|
||||||
let lastFocusedElement = null;
|
let lastFocusedElement = null;
|
||||||
@@ -39,15 +40,37 @@ if (recentChatsSearchEl) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSessionDetailsVisibility(show, { fromUser = false } = {}) {
|
function setSessionCardVisibility(show, { fromUser = false } = {}) {
|
||||||
if (!toggleSessionBtn || !sessionDetailsEl) return;
|
if (!sessionSectionEl || !sessionCardToggleBtn) return;
|
||||||
sessionDetailsVisible = show;
|
sessionCardVisible = show;
|
||||||
if (fromUser) {
|
if (fromUser) {
|
||||||
sessionDetailsTouched = true;
|
sessionCardTouched = true;
|
||||||
}
|
}
|
||||||
sessionDetailsEl.classList.toggle("hidden", !show);
|
sessionSectionEl.classList.toggle("hidden", !show);
|
||||||
toggleSessionBtn.setAttribute("aria-expanded", String(show));
|
sessionCardToggleBtn.setAttribute("aria-expanded", String(show));
|
||||||
toggleSessionBtn.textContent = show ? "Hide session controls" : "Manage session";
|
sessionCardToggleBtn.setAttribute("aria-label", show ? "Hide session controls" : "Show session controls");
|
||||||
|
if (show && fromUser && toggleSessionBtn) {
|
||||||
|
toggleSessionBtn.focus({ preventScroll: true });
|
||||||
|
} else if (!show && fromUser) {
|
||||||
|
sessionCardToggleBtn.focus({ preventScroll: true });
|
||||||
|
}
|
||||||
|
updateSessionCardToggleLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSessionCardToggleLabel(status) {
|
||||||
|
if (!sessionCardToggleBtn) return;
|
||||||
|
const statusText = status?.authorized
|
||||||
|
? "Authorized"
|
||||||
|
: status?.code_sent
|
||||||
|
? "Awaiting code"
|
||||||
|
: status?.phone_number
|
||||||
|
? "Phone pending"
|
||||||
|
: status?.authorized === false
|
||||||
|
? "Not authorized"
|
||||||
|
: sessionStatusEl?.textContent?.trim() || "Status";
|
||||||
|
const statusColor = sessionStatusEl?.style?.color || "inherit";
|
||||||
|
|
||||||
|
sessionCardToggleBtn.innerHTML = `<span class="session-card-toggle-status" style="color: ${statusColor}">${statusText}</span><span class="session-card-toggle-text">Manage</span>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setCreateFormVisibility(show, { fromUser = false } = {}) {
|
function setCreateFormVisibility(show, { fromUser = false } = {}) {
|
||||||
@@ -74,11 +97,17 @@ if (toggleCreateBtn) {
|
|||||||
setCreateFormVisibility(false);
|
setCreateFormVisibility(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sessionCardToggleBtn) {
|
||||||
|
sessionCardToggleBtn.addEventListener("click", () => {
|
||||||
|
setSessionCardVisibility(!sessionCardVisible, { fromUser: true });
|
||||||
|
});
|
||||||
|
updateSessionCardToggleLabel();
|
||||||
|
}
|
||||||
|
|
||||||
if (toggleSessionBtn) {
|
if (toggleSessionBtn) {
|
||||||
toggleSessionBtn.addEventListener("click", () => {
|
toggleSessionBtn.addEventListener("click", () => {
|
||||||
setSessionDetailsVisibility(!sessionDetailsVisible, { fromUser: true });
|
setSessionCardVisibility(false, { fromUser: true });
|
||||||
});
|
});
|
||||||
setSessionDetailsVisibility(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchJSON(url, options = {}) {
|
async function fetchJSON(url, options = {}) {
|
||||||
@@ -150,12 +179,13 @@ function updateSessionUI(status) {
|
|||||||
startLoginForm.classList.remove("hidden");
|
startLoginForm.classList.remove("hidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
const shouldShowDetails = !status.authorized || status.code_sent;
|
if (!status.authorized || status.code_sent) {
|
||||||
if (!sessionDetailsTouched) {
|
if (!sessionCardVisible) {
|
||||||
setSessionDetailsVisibility(shouldShowDetails);
|
setSessionCardVisibility(true);
|
||||||
} else if (shouldShowDetails && !sessionDetailsVisible) {
|
|
||||||
setSessionDetailsVisibility(true);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSessionCardToggleLabel(status);
|
||||||
setRecentChatsAvailability(status.authorized);
|
setRecentChatsAvailability(status.authorized);
|
||||||
if (!status.authorized) {
|
if (!status.authorized) {
|
||||||
closeRecentChatsDialog();
|
closeRecentChatsDialog();
|
||||||
|
|||||||
@@ -73,11 +73,28 @@ main {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.helper-button {
|
.helper-button {
|
||||||
min-width: 14rem;
|
min-width: 14rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.45rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-card-toggle-status {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-card-toggle-text {
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
@@ -143,8 +160,7 @@ main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.session-toggle {
|
.session-toggle {
|
||||||
align-self: center;
|
align-self: flex-start;
|
||||||
white-space: nowrap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.session-details {
|
.session-details {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<section id="session-section" class="card" aria-label="Telegram session">
|
<section id="session-section" class="card hidden" aria-label="Telegram session">
|
||||||
<div class="session-summary">
|
<div class="session-summary">
|
||||||
<div class="session-summary-main">
|
<div class="session-summary-main">
|
||||||
<div class="session-status-row">
|
<div class="session-status-row">
|
||||||
@@ -27,11 +27,19 @@
|
|||||||
<p id="session-summary-text" class="session-summary-text">Preparing session details…</p>
|
<p id="session-summary-text" class="session-summary-text">Preparing session details…</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" id="toggle-session" class="secondary session-toggle" aria-expanded="false">
|
<button
|
||||||
Manage session
|
type="button"
|
||||||
|
id="toggle-session"
|
||||||
|
class="secondary icon-button session-toggle"
|
||||||
|
aria-label="Hide session controls"
|
||||||
|
>
|
||||||
|
<svg class="icon icon-close" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
|
<path d="M18.3 5.71 12 12l6.3 6.29-1.41 1.42L10.59 13.4 4.3 19.71 2.89 18.3 9.17 12 2.89 5.71 4.3 4.3l6.3 6.29 6.29-6.3z" />
|
||||||
|
</svg>
|
||||||
|
<span class="sr-only">Hide session controls</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="session-details" class="session-details hidden">
|
<div id="session-details" class="session-details">
|
||||||
<div id="session-user" class="user-info"></div>
|
<div id="session-user" class="user-info"></div>
|
||||||
<div id="login-forms">
|
<div id="login-forms">
|
||||||
<form id="start-login-form" class="form-grid">
|
<form id="start-login-form" class="form-grid">
|
||||||
@@ -54,6 +62,14 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div class="helper-row">
|
<div class="helper-row">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
id="session-card-toggle"
|
||||||
|
class="secondary helper-button"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
|
Manage session
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
id="recent-chats-btn"
|
id="recent-chats-btn"
|
||||||
|
|||||||
Reference in New Issue
Block a user