feat(groups): anti-bruit prénoms, 4 thèmes, persistance analyse, fix filtre provider

This commit is contained in:
2026-09-27 14:34:47 -04:00
parent a2b4139887
commit ebfb39fec2
3 changed files with 64 additions and 19 deletions
@@ -52,7 +52,7 @@
type="button"
(click)="runDeepAnalysis()"
class="rounded-md border border-violet-500/50 bg-transparent px-3 py-1.5 text-sm text-violet-200 transition hover:bg-violet-600/20"
title="Lit les titres récents des chaînes sans groupe pour affiner les suggestions"
title="Lit les titres récents des chaînes sans groupe pour affiner les suggestions (résultat conservé entre les sessions)"
>
🔍 Analyse approfondie
</button>
@@ -102,7 +102,22 @@ export class SubscriptionsComponent {
private deepCancel = false;
deepAnalyzing = signal<boolean>(false);
deepProgress = signal<{ done: number; total: number } | null>(null);
private deepTexts = signal<Record<number, string>>({});
private static readonly DEEP_TEXTS_KEY = 'newtube.deepTexts.v1';
private deepTexts = signal<Record<number, string>>((() => {
try {
const raw = localStorage.getItem(SubscriptionsComponent.DEEP_TEXTS_KEY);
const parsed = raw ? JSON.parse(raw) : {};
return parsed && typeof parsed === 'object' ? parsed : {};
} catch {
return {};
}
})());
private persistDeepTexts(): void {
try {
localStorage.setItem(SubscriptionsComponent.DEEP_TEXTS_KEY, JSON.stringify(this.deepTexts()));
} catch {}
}
private suggestionBaseItems() {
const extra = this.deepTexts();
@@ -146,6 +161,7 @@ export class SubscriptionsComponent {
const workers = Array.from({ length: 4 }, () => this.deepWorker(queue, texts, counter, targets.length));
await Promise.all(workers);
this.deepTexts.set(texts);
this.persistDeepTexts();
this.deepProgress.set(null);
this.deepAnalyzing.set(false);
}
@@ -470,7 +486,22 @@ export class SubscriptionsComponent {
const q = this.searchQuery().trim().toLowerCase();
let filtered = list;
if (filter !== 'all') {
filtered = filtered.filter((item) => item.channel?.provider === filter);
// Normalise les codes courts ('yt') et longs ('youtube') : les imports
// mixtes stockent les deux formes.
const alias = (p: string | null | undefined): string => {
const v = String(p || '').toLowerCase();
return (
{
youtube: 'yt', yt: 'yt',
dailymotion: 'dm', dm: 'dm',
twitch: 'tw', tw: 'tw',
peertube: 'pt', pt: 'pt',
odysee: 'od', od: 'od',
rumble: 'ru', ru: 'ru',
} as Record<string, string>
)[v] || v;
};
filtered = filtered.filter((item) => alias(item.channel?.provider) === filter);
}
if (groupId !== 'all') {
const members = this.members();