first commit
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
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: '🕒' },
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user