Files
NewTube/src/services/themes.service.ts
T
2025-09-14 23:05:30 -04:00

82 lines
2.5 KiB
TypeScript

import { Injectable, computed, signal } from '@angular/core';
import { ThemeDef, THEMES } from '../models/theme.model';
import { I18nService } from './i18n.service';
export interface ThemeCategory {
key: string;
label: string;
emoji?: string;
}
@Injectable({ providedIn: 'root' })
export class ThemesService {
private readonly list = signal<ThemeDef[]>(THEMES);
// Active theme slug derived from router (set externally by the theme bar)
readonly activeSlug = signal<string>('trending');
// Controls whether the themes nav should show all themes or only a subset (e.g., 8)
readonly showAll = signal<boolean>(false);
constructor(private i18n: I18nService) {}
themes() { return this.list(); }
setShowAll(v: boolean) { this.showAll.set(!!v); }
toggleShowAll() { this.showAll.update(x => !x); }
bySlug(slug: string | null | undefined): ThemeDef | undefined {
if (!slug) return undefined;
const s = String(slug).toLowerCase();
return this.list().find(t => t.slug === s);
}
label(t: ThemeDef): string {
// Full label including emoji
const v = this.i18nLabel(t);
return `${t.emoji} ${v}`;
}
// Label without emoji, i18n-aware
i18nLabel(t: ThemeDef): string {
const key = `theme.${t.slug}`;
const v = this.i18n.t(key);
return v && v !== key ? v : t.label;
}
tokensFor(slug: string): string[] {
const t = this.bySlug(slug);
if (!t) return [];
const base = t.tokens && t.tokens.length ? t.tokens : [t.label];
return base;
}
// Best-effort suggested categories per theme (static for now)
categoriesFor(slug: string): ThemeCategory[] {
switch (slug) {
case 'finance-crypto':
return [
{ key: 'stock-market', label: 'Stock Market', emoji: '📈' },
{ key: 'crypto', label: 'Crypto', emoji: '🪙' },
{ key: 'economy', label: 'Economy', emoji: '🏦' },
];
case 'gaming':
return [
{ key: 'esports', label: 'Esports', emoji: '🎮' },
{ key: 'retro', label: 'Retro', emoji: '🕹️' },
{ key: 'fps', label: 'FPS', emoji: '🎯' },
];
case 'news':
return [
{ key: 'politics', label: 'Politics', emoji: '🏛️' },
{ key: 'world', label: 'World', emoji: '🌍' },
{ key: 'tech', label: 'Tech', emoji: '🧠' },
];
default:
return [
{ key: 'featured', label: 'Featured', emoji: '⭐' },
{ key: 'popular', label: 'Popular', emoji: '🔥' },
{ key: 'recent', label: 'Recent', emoji: '🕒' },
];
}
}
}