fix: track Laya language batches and normalize labels (#22)
Report post-projection Laya language detection as a busy analysis phase and normalize Laya language labels before caching and display. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -344,7 +344,7 @@ class ChannelList {
|
||||
}
|
||||
}
|
||||
|
||||
async refreshLayaLanguages(mode = window.app?.player?.settings?.languageDetectionMode || 'algo') {
|
||||
async refreshLayaLanguages(mode = window.app?.player?.settings?.languageDetectionMode || 'algo', options = {}) {
|
||||
const requestId = ++this._languageDetectionRequest;
|
||||
if (mode === 'algo') {
|
||||
const hadWarning = Boolean(this.languageDetectionNotice || this.languageDetectionFallback);
|
||||
@ -364,6 +364,7 @@ class ChannelList {
|
||||
);
|
||||
});
|
||||
const results = new Map();
|
||||
const totalBatches = Math.ceil(descriptors.length / 64);
|
||||
try {
|
||||
const status = await API.laya.getStatus();
|
||||
const statusWarning = LayaStatusPresentation.channelListWarning(mode, status);
|
||||
@ -379,9 +380,15 @@ class ChannelList {
|
||||
this.languageDetectionNotice = '';
|
||||
this.languageDetectionFallback = false;
|
||||
this.render();
|
||||
options.onProgress?.({ processed: 0, total: totalBatches });
|
||||
for (let index = 0; index < descriptors.length; index += 64) {
|
||||
const response = await API.laya.detectLanguages(descriptors.slice(index, index + 64));
|
||||
(response.results || []).forEach(result => results.set(String(result.id), result));
|
||||
if (requestId !== this._languageDetectionRequest) return;
|
||||
options.onProgress?.({
|
||||
processed: Math.floor(index / 64) + 1,
|
||||
total: totalBatches
|
||||
});
|
||||
}
|
||||
if (requestId !== this._languageDetectionRequest) return;
|
||||
if (descriptors.length > 0 && results.size === 0) {
|
||||
@ -904,7 +911,7 @@ class ChannelList {
|
||||
/**
|
||||
* Load channels from selected source
|
||||
*/
|
||||
async loadChannels() {
|
||||
async loadChannels({ refreshLanguages = true } = {}) {
|
||||
if (this.isLoading) return;
|
||||
this.isLoading = true;
|
||||
this.currentRenderId = null; // Reset render tracking
|
||||
@ -921,7 +928,7 @@ class ChannelList {
|
||||
|
||||
if (!sourceValue) {
|
||||
// Load from all sources
|
||||
await this.loadAllChannels();
|
||||
await this.loadAllChannels({ refreshLanguages });
|
||||
this.isLoading = false;
|
||||
return;
|
||||
}
|
||||
@ -933,7 +940,7 @@ class ChannelList {
|
||||
|
||||
if (await this.loadProjectedChannels(parseInt(id, 10))) {
|
||||
this.render();
|
||||
void this.refreshLayaLanguages();
|
||||
if (refreshLanguages) void this.refreshLayaLanguages();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -950,7 +957,7 @@ class ChannelList {
|
||||
]);
|
||||
|
||||
this.render();
|
||||
void this.refreshLayaLanguages();
|
||||
if (refreshLanguages) void this.refreshLayaLanguages();
|
||||
} catch (err) {
|
||||
console.error('Error loading channels:', err);
|
||||
if (previousState.channels.length > 0) {
|
||||
@ -970,7 +977,7 @@ class ChannelList {
|
||||
/**
|
||||
* Load channels from all enabled sources
|
||||
*/
|
||||
async loadAllChannels() {
|
||||
async loadAllChannels({ refreshLanguages = true } = {}) {
|
||||
const previousState = {
|
||||
channels: this.channels,
|
||||
groups: this.groups,
|
||||
@ -985,7 +992,7 @@ class ChannelList {
|
||||
|
||||
if (await this.loadProjectedChannels()) {
|
||||
this.render();
|
||||
void this.refreshLayaLanguages();
|
||||
if (refreshLanguages) void this.refreshLayaLanguages();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1006,7 +1013,7 @@ class ChannelList {
|
||||
this.loadFavorites()
|
||||
]);
|
||||
this.render();
|
||||
void this.refreshLayaLanguages();
|
||||
if (refreshLanguages) void this.refreshLayaLanguages();
|
||||
} catch (err) {
|
||||
console.error('Error loading all channels:', err);
|
||||
if (previousState.channels.length > 0) {
|
||||
|
||||
@ -197,11 +197,32 @@ class SettingsPage {
|
||||
clearInterval(this.liveAnalysisPollTimer);
|
||||
this.liveAnalysisPollTimer = null;
|
||||
if (presentation.complete) {
|
||||
await this.app.channelList?.loadChannels();
|
||||
const mode = this.app.player?.settings?.languageDetectionMode || 'algo';
|
||||
await this.app.channelList?.loadChannels({
|
||||
refreshLanguages: mode !== 'laya' && mode !== 'hybrid'
|
||||
});
|
||||
if (mode === 'laya' || mode === 'hybrid') {
|
||||
await this.app.channelList?.refreshLayaLanguages(mode);
|
||||
this.liveAnalysisStatus = {
|
||||
status: 'building',
|
||||
phase: 'laya_language',
|
||||
languageProcessed: null,
|
||||
languageTotal: null
|
||||
};
|
||||
this.renderLiveAnalysisStatus(this.liveAnalysisStatus);
|
||||
await this.app.channelList?.refreshLayaLanguages(mode, {
|
||||
onProgress: ({ processed, total }) => {
|
||||
this.liveAnalysisStatus = {
|
||||
status: 'building',
|
||||
phase: 'laya_language',
|
||||
languageProcessed: processed,
|
||||
languageTotal: total
|
||||
};
|
||||
this.renderLiveAnalysisStatus(this.liveAnalysisStatus);
|
||||
}
|
||||
});
|
||||
}
|
||||
this.liveAnalysisStatus = status;
|
||||
this.renderLiveAnalysisStatus(status);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
||||
@ -10,9 +10,19 @@
|
||||
return Math.max(0, Math.min(100, Math.round(number <= 1 ? number * 100 : number)));
|
||||
}
|
||||
|
||||
function normalizeLanguageCode(value) {
|
||||
const normalized = String(value || '').trim().toLowerCase();
|
||||
const aliases = {
|
||||
fr: 'fr', french: 'fr', français: 'fr', francais: 'fr',
|
||||
en: 'en', english: 'en', anglais: 'en',
|
||||
es: 'es', spanish: 'es', español: 'es', espanol: 'es'
|
||||
};
|
||||
return aliases[normalized] || 'unknown';
|
||||
}
|
||||
|
||||
function layaDetection(result) {
|
||||
const rawCode = result?.language?.code || result?.language || 'unknown';
|
||||
const code = ['fr', 'en', 'es'].includes(rawCode) ? rawCode : 'unknown';
|
||||
const rawCode = result?.language?.code || result?.language?.label || result?.language || 'unknown';
|
||||
const code = normalizeLanguageCode(rawCode);
|
||||
const confidence = normalizeConfidence(result?.language?.confidence ?? result?.confidence);
|
||||
return {
|
||||
language: {
|
||||
@ -79,5 +89,5 @@
|
||||
};
|
||||
}
|
||||
|
||||
return { applyLanguageMode, buildLayaDescriptor, layaDetection, mergeHybrid, normalizeConfidence };
|
||||
return { applyLanguageMode, buildLayaDescriptor, layaDetection, mergeHybrid, normalizeConfidence, normalizeLanguageCode };
|
||||
});
|
||||
|
||||
@ -14,6 +14,13 @@
|
||||
prefix: 'AI batch'
|
||||
};
|
||||
}
|
||||
if (phase === 'laya_language') {
|
||||
return {
|
||||
processed: status.languageProcessed,
|
||||
total: status.languageTotal,
|
||||
prefix: 'Language batch'
|
||||
};
|
||||
}
|
||||
return { processed: status.processed, total: status.total, prefix: '', suffix: ' channels' };
|
||||
}
|
||||
|
||||
@ -37,6 +44,8 @@
|
||||
const statusLabel = busy
|
||||
? phase === 'laya_identity'
|
||||
? 'Analyzing with local AI…'
|
||||
: phase === 'laya_language'
|
||||
? 'Detecting stream languages…'
|
||||
: phase === 'projecting'
|
||||
? 'Building channel catalog…'
|
||||
: phase === 'writing'
|
||||
|
||||
Reference in New Issue
Block a user