Fix account tab persistence and viewer fallback

This commit is contained in:
2026-06-27 19:09:07 +02:00
parent 3eb6bdf534
commit 59cdad220a
3 changed files with 85 additions and 17 deletions
+38 -7
View File
@@ -10,6 +10,8 @@ const state = {
authStates: {},
};
const ACTIVE_ACCOUNT_STORAGE_KEY = "telegramScraper.activeAccount";
/* ── API helper ─────────────────────────────────────── */
async function api(path, options = {}) {
@@ -78,6 +80,33 @@ function isAccountAuthorized(auth) {
);
}
function saveActiveAccount(accountId) {
if (accountId) {
localStorage.setItem(ACTIVE_ACCOUNT_STORAGE_KEY, accountId);
}
}
function loadSavedActiveAccount(accounts) {
let savedId = localStorage.getItem(ACTIVE_ACCOUNT_STORAGE_KEY);
if (!savedId) {
savedId = localStorage.getItem("activeAccount");
if (savedId) {
localStorage.setItem(ACTIVE_ACCOUNT_STORAGE_KEY, savedId);
localStorage.removeItem("activeAccount");
}
}
if (savedId && accounts.some((account) => account.id === savedId)) {
return savedId;
}
if (savedId) {
localStorage.removeItem(ACTIVE_ACCOUNT_STORAGE_KEY);
}
if (state.activeAccount && accounts.some((account) => account.id === state.activeAccount)) {
return state.activeAccount;
}
return accounts[0]?.id || null;
}
/* ── Account tab management ─────────────────────────── */
function renderAccountTabs(accounts) {
@@ -175,9 +204,8 @@ function renderAccountPanel(accountId) {
}
function switchAccount(accountId) {
if (state.activeAccount === accountId) return;
state.activeAccount = accountId;
localStorage.setItem("activeAccount", accountId);
saveActiveAccount(accountId);
// Update tabs
document.querySelectorAll(".account-tab").forEach((tab) => {
@@ -490,9 +518,10 @@ async function loadAccounts() {
accounts.forEach((acc) => renderAccountPanel(acc.id));
// Determine active account (persisted across reloads)
const savedId = localStorage.getItem("activeAccount");
const activeId = (savedId && accounts.some(a => a.id === savedId)) ? savedId : (state.activeAccount || accounts[0].id);
switchAccount(activeId);
const activeId = loadSavedActiveAccount(accounts);
if (activeId) {
switchAccount(activeId);
}
// Update settings
renderSettingsAccounts();
@@ -524,11 +553,13 @@ function renderSettingsAccounts() {
node.querySelector(".account-remove-btn").addEventListener("click", async () => {
if (!confirmAction(`Remove account "${acc.label || acc.id}"? All its data will be deleted.`)) return;
try {
const removingActive = state.activeAccount === acc.id;
await api(`/api/accounts/${acc.id}`, { method: "DELETE" });
await loadAccounts();
if (state.activeAccount === acc.id) {
if (removingActive) {
state.activeAccount = null;
localStorage.removeItem(ACTIVE_ACCOUNT_STORAGE_KEY);
}
await loadAccounts();
} catch (err) {
alert(`Failed to remove account: ${err.message}`);
}
+46 -9
View File
@@ -87,6 +87,25 @@ function scrollToBottom() {
setTimeout(go, 150);
}
function makeScrollSentinel() {
const sentinel = document.createElement("div");
sentinel.id = "scroll-sentinel";
sentinel.className = "scroll-sentinel";
return sentinel;
}
function resetMessageView(title = "Select a channel", subtitle = "Reading messages from the local SQLite database.") {
const root = document.getElementById("messages-list");
if (root) {
root.innerHTML = "";
root.appendChild(makeScrollSentinel());
}
document.getElementById("viewer-title").textContent = title;
document.getElementById("viewer-subtitle").textContent = subtitle;
viewerState.oldestMessageId = null;
viewerState.newestMessageId = null;
}
function renderChannelList() {
const root = document.getElementById("viewer-channel-list");
if (!root) return;
@@ -179,6 +198,13 @@ async function switchViewerAccount(accountId) {
renderChannelList();
if (viewerState.channelId) {
await loadChannel(viewerState.channelId);
} else {
resetMessageView(
"No channels",
viewerState.accountId
? "This account has no tracked channels yet."
: "No local legacy channels found."
);
}
}
@@ -190,10 +216,10 @@ async function loadViewerAccount(params) {
} catch {
viewerState.accounts = [];
}
viewerState.accountId =
requested ||
viewerState.accounts[0]?.id ||
null;
const requestedExists = requested && viewerState.accounts.some((acc) => acc.id === requested);
viewerState.accountId = requestedExists
? requested
: viewerState.accounts[0]?.id || null;
renderAccountSelector();
@@ -289,8 +315,9 @@ function makeDateSep(text) {
function renderMessages(payload, append = false) {
const root = document.getElementById("messages-list");
const sentinel = document.getElementById("scroll-sentinel");
if (!root) return;
let sentinel = document.getElementById("scroll-sentinel");
if (!sentinel) sentinel = makeScrollSentinel();
const channel = payload.channel;
document.getElementById("viewer-title").textContent =
@@ -408,14 +435,24 @@ async function main() {
const params = new URLSearchParams(window.location.search);
await loadViewerAccount(params);
viewerState.channels = await api(channelsEndpoint());
viewerState.channelId =
params.get("channel") ||
viewerState.channels[0]?.channel_id ||
null;
const requestedChannel = params.get("channel");
const requestedChannelExists =
requestedChannel &&
viewerState.channels.some((channel) => channel.channel_id === requestedChannel);
viewerState.channelId = requestedChannelExists
? requestedChannel
: viewerState.channels[0]?.channel_id || null;
renderChannelList();
if (viewerState.channelId) {
await loadChannel(viewerState.channelId);
} else {
resetMessageView(
"No channels",
viewerState.accountId
? "This account has no tracked channels yet."
: "No local legacy channels found."
);
}
setupInfiniteScroll();