feat: split live analysis actions and page catalog loading

Separate incremental live checks from full catalog rebuilds and page projected channel/variant loading so first live-list display stays bounded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
blomios
2026-10-07 23:45:42 +02:00
parent bbb1afb238
commit 4cca030afa
12 changed files with 434 additions and 35 deletions

View File

@ -107,7 +107,12 @@ class SettingsPage {
}
initLiveAnalysis() {
document.getElementById('live-analysis-button')?.addEventListener('click', () => void this.runLiveAnalysis());
document.getElementById('live-check-new-button')?.addEventListener('click', () => void this.runLiveAnalysis('check-new'));
document.getElementById('live-rebuild-catalog-button')?.addEventListener('click', () => {
if (confirm('Rebuild the entire channel catalog? This can take a while.')) void this.runLiveAnalysis('rebuild');
});
// Compatibility with pages cached before the actions were split.
document.getElementById('live-analysis-button')?.addEventListener('click', () => void this.runLiveAnalysis('rebuild'));
document.getElementById('live-analysis-details-toggle')?.addEventListener('click', () => {
const button = document.getElementById('live-analysis-details-toggle');
const details = document.getElementById('live-analysis-error-details');
@ -131,7 +136,11 @@ class SettingsPage {
}
renderLiveAnalysisStatus(status = {}) {
const button = document.getElementById('live-analysis-button');
const buttons = [
document.getElementById('live-check-new-button'),
document.getElementById('live-rebuild-catalog-button'),
document.getElementById('live-analysis-button')
].filter(Boolean);
const statusElement = document.getElementById('live-analysis-status');
const progress = document.getElementById('live-analysis-progress');
const track = document.getElementById('live-analysis-progress-track');
@ -140,11 +149,10 @@ class SettingsPage {
const fallback = document.getElementById('live-analysis-fallback');
const detailsButton = document.getElementById('live-analysis-details-toggle');
const details = document.getElementById('live-analysis-error-details');
if (!button || !statusElement) return;
if (!buttons.length || !statusElement) return;
const presentation = LiveAnalysisPresentation.present(status);
button.textContent = presentation.buttonLabel;
button.disabled = presentation.busy;
buttons.forEach(button => { button.disabled = presentation.busy; });
statusElement.textContent = presentation.statusLabel;
progress.hidden = !presentation.busy;
track.classList.toggle('indeterminate', presentation.progressIndeterminate);
@ -169,14 +177,19 @@ class SettingsPage {
details.textContent = presentation.errorDetail;
}
async runLiveAnalysis() {
const button = document.getElementById('live-analysis-button');
if (button?.disabled) return;
async runLiveAnalysis(action = 'rebuild') {
const buttons = ['live-check-new-button', 'live-rebuild-catalog-button', 'live-analysis-button']
.map(id => document.getElementById(id)).filter(Boolean);
if (buttons.some(button => button.disabled)) return;
this.liveAnalysisStatus = { ...(this.liveAnalysisStatus || {}), status: 'queued', processed: 0 };
this.renderLiveAnalysisStatus(this.liveAnalysisStatus);
try {
const response = await API.live.rebuildProjection();
this.liveAnalysisStatus = response.projection || response;
const response = action === 'check-new'
? await API.live.checkNewStreams()
: await API.live.rebuildProjection();
this.liveAnalysisStatus = response.projection || (response.started
? { status: 'queued', processed: 0 }
: response);
this.renderLiveAnalysisStatus(this.liveAnalysisStatus);
this.startLiveAnalysisPolling();
} catch (err) {