feat: window title syncs with active tab / streamer

document.title was stamped once during app boot with the static
"Twitch VOD Manager vX.Y.Z" string. After that, the H1 page-title
in the header updated as the user navigated tabs and selected
streamers, but the OS-level window title — the string shown in the
taskbar, Alt+Tab switcher, and OS notifications — never changed.

Multitasking suffered: a user with three Electron windows pinned
to taskbar all read identical "Twitch VOD Manager v4.6.x", with
no clue which window had what tab or streamer loaded.

Added a setPageTitle(text) helper in renderer.ts that:
- Updates the H1 #pageTitle textContent (the visible header)
- Updates document.title with `${text} - ${appName} v${version}`
  for non-default text, or just `${appName} v${version}` for the
  default app-name fallback
- Exposed on window so the renderer-streamers.ts and
  renderer-settings.ts modules can reach it without crossing the
  module-vs-bundle boundary

Three call sites updated to use the helper:
- showTab → uses for tab-derived titles
- selectStreamer → uses for "xrohat" style streamer titles
- the renderer-settings language-switch refresh path

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
xRangerDE 2026-05-11 05:29:04 +02:00
parent 4489319d70
commit bdf6bac602
3 changed files with 31 additions and 4 deletions

View File

@ -194,9 +194,14 @@ function changeLanguage(lang: string): void {
const activeTabId = document.querySelector('.tab-content.active')?.id || 'vodsTab';
const activeTab = activeTabId.replace('Tab', '');
if (activeTab === 'vods' && currentStreamer) {
byId('pageTitle').textContent = currentStreamer;
const setTitle = (window as unknown as { setPageTitle?: (text: string) => void }).setPageTitle;
if (typeof setTitle === 'function') setTitle(currentStreamer);
else byId('pageTitle').textContent = currentStreamer;
} else {
byId('pageTitle').textContent = (UI_TEXT.tabs as Record<string, string>)[activeTab] || UI_TEXT.appName;
const setTitle = (window as unknown as { setPageTitle?: (text: string) => void }).setPageTitle;
const text = (UI_TEXT.tabs as Record<string, string>)[activeTab] || UI_TEXT.appName;
if (typeof setTitle === 'function') setTitle(text);
else byId('pageTitle').textContent = text;
}
void refreshRuntimeMetrics();

View File

@ -751,7 +751,9 @@ async function selectStreamer(name: string, forceRefresh = false): Promise<void>
const savedY = vodScrollPositions[name];
pendingScrollRestore = (typeof savedY === 'number' && savedY > 0) ? { streamer: name, y: savedY } : null;
renderStreamers();
byId('pageTitle').textContent = name;
const setTitle = (window as unknown as { setPageTitle?: (text: string) => void }).setPageTitle;
if (typeof setTitle === 'function') setTitle(name);
else byId('pageTitle').textContent = name;
// Kick off the profile header load in parallel with VOD fetching.
// It's a separate request stream and not strictly needed for the VOD

View File

@ -20,6 +20,7 @@ async function init(): Promise<void> {
byId('versionText').textContent = `v${version}`;
byId('versionInfo').textContent = `Version: v${version}`;
appVersion = version;
document.title = `${UI_TEXT.appName} v${version}`;
byId<HTMLInputElement>('clientId').value = config.client_id ?? '';
@ -636,6 +637,24 @@ async function updateStatsBar(): Promise<void> {
let toastHideTimer: number | null = null;
let queueSyncTimer: number | null = null;
let appVersion = '';
// Single source of truth for what the user is looking at — keeps the
// visible H1, the document title (which drives the OS task bar / Alt+Tab
// label), and the app version pill in sync. Previously document.title was
// stamped once at boot, so the OS task bar always read "Twitch VOD
// Manager v4.6.76" no matter what tab or streamer was active.
(window as unknown as { setPageTitle: (text: string) => void }).setPageTitle = setPageTitle;
function setPageTitle(text: string): void {
const titleEl = document.getElementById('pageTitle');
if (titleEl) titleEl.textContent = text;
const appName = UI_TEXT.appName;
const versionSuffix = appVersion ? ` v${appVersion}` : '';
document.title = text && text !== appName
? `${text} - ${appName}${versionSuffix}`
: `${appName}${versionSuffix}`;
}
let queueSyncInFlight = false;
let lastQueueActivityAt = Date.now();
@ -850,9 +869,10 @@ function showTab(tab: string): void {
// Only show the streamer name on the VODs tab — otherwise the title would
// mismatch the tab content (e.g. "streamer X" while on Settings)
byId('pageTitle').textContent = (tab === 'vods' && currentStreamer)
const pageTitleText = (tab === 'vods' && currentStreamer)
? currentStreamer
: (titles[tab] || UI_TEXT.appName);
setPageTitle(pageTitleText);
persistActiveTab(tab);