sponsors.ts 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. import type { Sponsor } from '@/generated/types';
  2. export type SponsorSlot = 'dashboard' | 'page' | 'login';
  3. const DISMISS_KEY = 'xui.sponsor.dismissed';
  4. export const SPONSOR_DISMISS_MS = 24 * 60 * 60 * 1000;
  5. export function pickLocale(map: Record<string, string> | undefined, lang: string): string {
  6. if (!map) return '';
  7. const short = lang.split('-')[0].toLowerCase();
  8. return map[lang] || map[short] || map.en || '';
  9. }
  10. export function sponsorsForSlot(sponsors: Sponsor[], slot: SponsorSlot): Sponsor[] {
  11. return sponsors.filter((s) => s.slots.includes(slot));
  12. }
  13. function readDismissed(): Record<string, number> {
  14. try {
  15. const parsed: unknown = JSON.parse(localStorage.getItem(DISMISS_KEY) || '{}');
  16. return parsed && typeof parsed === 'object' ? (parsed as Record<string, number>) : {};
  17. } catch {
  18. return {};
  19. }
  20. }
  21. export function isSponsorDismissed(id: string, slot: SponsorSlot, now = Date.now()): boolean {
  22. const at = readDismissed()[`${id}:${slot}`];
  23. return typeof at === 'number' && now - at < SPONSOR_DISMISS_MS;
  24. }
  25. export function dismissSponsor(id: string, slot: SponsorSlot, now = Date.now()) {
  26. const next = Object.fromEntries(
  27. Object.entries(readDismissed()).filter(([, at]) => now - at < SPONSOR_DISMISS_MS),
  28. );
  29. next[`${id}:${slot}`] = now;
  30. try {
  31. localStorage.setItem(DISMISS_KEY, JSON.stringify(next));
  32. } catch {}
  33. }