forked from ORGANISATION-KA-INTERNATIONALE/FEDIVERSE-OKI
76 lines
2.6 KiB
TypeScript
76 lines
2.6 KiB
TypeScript
|
|
import { resolve } from '$app/paths';
|
||
|
|
import type { Locale } from '$lib/types';
|
||
|
|
import fr from './fr.json';
|
||
|
|
import en from './en.json';
|
||
|
|
|
||
|
|
export type Bundle = typeof fr;
|
||
|
|
|
||
|
|
const bundles: Record<Locale, Bundle> = { fr, en: en as Bundle };
|
||
|
|
|
||
|
|
export const locales: Locale[] = ['fr', 'en'];
|
||
|
|
export const defaultLocale: Locale = 'fr';
|
||
|
|
|
||
|
|
export function getBundle(locale: Locale): Bundle {
|
||
|
|
return bundles[locale] ?? bundles[defaultLocale];
|
||
|
|
}
|
||
|
|
|
||
|
|
export function localeFromPath(pathname: string): Locale {
|
||
|
|
return pathname.split('/')[1] === 'en' ? 'en' : 'fr';
|
||
|
|
}
|
||
|
|
|
||
|
|
export function stripLocale(pathname: string): string {
|
||
|
|
if (pathname === '/en') return '/';
|
||
|
|
if (pathname.startsWith('/en/')) return pathname.slice(3);
|
||
|
|
return pathname;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function hrefFor(locale: Locale, path: string): string {
|
||
|
|
const clean = path.startsWith('/') ? path : `/${path}`;
|
||
|
|
const full = locale === 'en' ? `/en${clean === '/' ? '/' : clean}` : clean;
|
||
|
|
const [pathname, rest = ''] = full.split(/(?=[?#])/);
|
||
|
|
const withSlash = pathname.endsWith('/') ? pathname : `${pathname}/`;
|
||
|
|
// Chemin interne calculé (locale préfixée) : cast requis par le typage des routes
|
||
|
|
return resolve(`${withSlash}${rest}` as '/');
|
||
|
|
}
|
||
|
|
|
||
|
|
export function alternatePath(pathname: string, target: Locale): string {
|
||
|
|
const bare = stripLocale(pathname);
|
||
|
|
return hrefFor(target, bare);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function t(template: string, vars: Record<string, string | number> = {}): string {
|
||
|
|
return template.replace(/\{(\w+)\}/g, (_, key) => String(vars[key] ?? `{${key}}`));
|
||
|
|
}
|
||
|
|
|
||
|
|
export function formatDate(dateString: string, locale: Locale): string {
|
||
|
|
const date = new Date(dateString);
|
||
|
|
if (Number.isNaN(date.getTime())) return dateString;
|
||
|
|
return new Intl.DateTimeFormat(locale === 'en' ? 'en-GB' : 'fr-FR', {
|
||
|
|
day: 'numeric',
|
||
|
|
month: 'long',
|
||
|
|
year: 'numeric'
|
||
|
|
}).format(date);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function formatDuration(seconds: number): string {
|
||
|
|
const h = Math.floor(seconds / 3600);
|
||
|
|
const m = Math.floor((seconds % 3600) / 60);
|
||
|
|
const s = Math.floor(seconds % 60);
|
||
|
|
if (h > 0) return `${h}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`;
|
||
|
|
return `${m}:${String(s).padStart(2, '0')}`;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function formatViewCount(views: number): string {
|
||
|
|
if (views >= 1_000_000) return `${(views / 1_000_000).toFixed(1)}M`;
|
||
|
|
if (views >= 1_000) return `${(views / 1_000).toFixed(1)}K`;
|
||
|
|
return String(views);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function formatFileSize(bytes: number): string {
|
||
|
|
if (bytes <= 0) return '';
|
||
|
|
const units = ['o', 'Ko', 'Mo', 'Go'];
|
||
|
|
const exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);
|
||
|
|
const value = bytes / 1024 ** exponent;
|
||
|
|
return `${value.toFixed(value >= 10 || exponent === 0 ? 0 : 1)} ${units[exponent]}`;
|
||
|
|
}
|