173 lines
5.2 KiB
JavaScript
173 lines
5.2 KiB
JavaScript
// All user-facing strings live here.
|
|
// Stakes are phrased so they read naturally after "The chosen one has to…"
|
|
// (en, bare verb) / "De gekozene…" (nl, conjugated verb), and slot into
|
|
// "You {stake}!" / "Jij {stake}!" on the reveal.
|
|
|
|
export const translations = {
|
|
en: {
|
|
appTitle: 'Picker',
|
|
hint: 'Everyone put a finger on the screen',
|
|
needMore: 'Waiting for more fingers…',
|
|
holdStill: 'Hold still…',
|
|
chicken: [
|
|
'Someone chickened out! 🐔',
|
|
'Cold feet? Someone let go! 🐔',
|
|
'Bawk bawk! Who let go? 🐔',
|
|
],
|
|
chickenOut: 'Chickened out! 🐔',
|
|
eliminated: 'Knocked out!',
|
|
liftFinger: 'Lift your finger',
|
|
youreIt: "You're it!",
|
|
youStake: 'You {stake}!',
|
|
teamsReady: 'Teams are set!',
|
|
orderDone: "That's the order!",
|
|
lastStanding: 'Last one standing!',
|
|
tapRestart: 'Tap to play again',
|
|
desktopHint: 'On a computer? Add ?debug=1 to the address to test with a mouse.',
|
|
tapForSound: '🔈 Tap the screen once to turn on sound',
|
|
team: 'Team {name}',
|
|
|
|
modeLabel: 'Mode',
|
|
mode: {
|
|
one: 'Pick one',
|
|
pickN: 'Pick several',
|
|
teams: 'Teams',
|
|
order: 'Order',
|
|
elimination: 'Elimination',
|
|
},
|
|
modeDesc: {
|
|
one: 'One finger is chosen.',
|
|
pickN: 'Several fingers are chosen.',
|
|
teams: 'Everyone is split into teams.',
|
|
order: 'Everyone gets a number, one by one.',
|
|
elimination: 'One finger is knocked out each round until one remains.',
|
|
},
|
|
pickNLabel: 'How many to pick',
|
|
teamsLabel: 'Number of teams',
|
|
stakesLabel: 'The chosen one has to…',
|
|
stakesPlaceholder: 'e.g. pay the bill',
|
|
stakesClear: 'Clear',
|
|
stakePresets: {
|
|
bill: 'pay the bill',
|
|
dishes: 'do the dishes',
|
|
first: 'go first',
|
|
round: 'get the next round',
|
|
movie: 'pick the movie',
|
|
},
|
|
themeLabel: 'Theme',
|
|
theme: { neon: 'Neon', pastel: 'Pastel', contrast: 'High contrast' },
|
|
languageLabel: 'Language',
|
|
soundLabel: 'Sound',
|
|
hapticsLabel: 'Vibration',
|
|
on: 'On',
|
|
off: 'Off',
|
|
done: 'Done',
|
|
settings: 'Settings',
|
|
mute: 'Mute sound',
|
|
unmute: 'Unmute sound',
|
|
fullscreen: 'Full screen',
|
|
exitFullscreen: 'Exit full screen',
|
|
decrease: 'Fewer',
|
|
increase: 'More',
|
|
},
|
|
|
|
nl: {
|
|
appTitle: 'Picker',
|
|
hint: 'Iedereen een vinger op het scherm',
|
|
needMore: 'Wachten op meer vingers…',
|
|
holdStill: 'Stil houden…',
|
|
chicken: [
|
|
'Iemand is er tussenuit geknepen! 🐔',
|
|
'Koudwatervrees? Iemand liet los! 🐔',
|
|
'Tok tok! Wie liet er los? 🐔',
|
|
],
|
|
chickenOut: 'Laf losgelaten! 🐔',
|
|
eliminated: 'Uitgeschakeld!',
|
|
liftFinger: 'Haal je vinger weg',
|
|
youreIt: 'Jij bent het!',
|
|
youStake: 'Jij {stake}!',
|
|
teamsReady: 'De teams staan!',
|
|
orderDone: 'Dat is de volgorde!',
|
|
lastStanding: 'Laatste overlevende!',
|
|
tapRestart: 'Tik om opnieuw te spelen',
|
|
desktopHint: 'Op een computer? Zet ?debug=1 achter het adres om met de muis te testen.',
|
|
tapForSound: '🔈 Tik één keer op het scherm voor geluid',
|
|
team: 'Team {name}',
|
|
|
|
modeLabel: 'Modus',
|
|
mode: {
|
|
one: 'Kies één',
|
|
pickN: 'Kies meerdere',
|
|
teams: 'Teams',
|
|
order: 'Volgorde',
|
|
elimination: 'Afvalrace',
|
|
},
|
|
modeDesc: {
|
|
one: 'Eén vinger wordt gekozen.',
|
|
pickN: 'Meerdere vingers worden gekozen.',
|
|
teams: 'Iedereen wordt in teams verdeeld.',
|
|
order: 'Iedereen krijgt een nummer, één voor één.',
|
|
elimination: 'Elke ronde valt er één af, tot er één overblijft.',
|
|
},
|
|
pickNLabel: 'Hoeveel kiezen',
|
|
teamsLabel: 'Aantal teams',
|
|
stakesLabel: 'De gekozene…',
|
|
stakesPlaceholder: 'bijv. betaalt de rekening',
|
|
stakesClear: 'Wissen',
|
|
stakePresets: {
|
|
bill: 'betaalt de rekening',
|
|
dishes: 'doet de afwas',
|
|
first: 'mag beginnen',
|
|
round: 'haalt het volgende rondje',
|
|
movie: 'kiest de film',
|
|
},
|
|
themeLabel: 'Thema',
|
|
theme: { neon: 'Neon', pastel: 'Pastel', contrast: 'Hoog contrast' },
|
|
languageLabel: 'Taal',
|
|
soundLabel: 'Geluid',
|
|
hapticsLabel: 'Trillen',
|
|
on: 'Aan',
|
|
off: 'Uit',
|
|
done: 'Klaar',
|
|
settings: 'Instellingen',
|
|
mute: 'Geluid uit',
|
|
unmute: 'Geluid aan',
|
|
fullscreen: 'Volledig scherm',
|
|
exitFullscreen: 'Volledig scherm sluiten',
|
|
decrease: 'Minder',
|
|
increase: 'Meer',
|
|
},
|
|
};
|
|
|
|
export const LANGS = ['en', 'nl'];
|
|
let current = 'en';
|
|
|
|
export function detectLang() {
|
|
const prefs = navigator.languages?.length ? navigator.languages : [navigator.language || 'en'];
|
|
for (const p of prefs) {
|
|
const base = String(p).toLowerCase().split('-')[0];
|
|
if (LANGS.includes(base)) return base;
|
|
}
|
|
return 'en';
|
|
}
|
|
|
|
export function setLang(lang) {
|
|
current = LANGS.includes(lang) ? lang : 'en';
|
|
document.documentElement.lang = current;
|
|
}
|
|
|
|
export function getLang() {
|
|
return current;
|
|
}
|
|
|
|
/** Look up a dotted key ("mode.one"); interpolate {vars}. Falls back to English. */
|
|
export function t(key, vars) {
|
|
const lookup = (lang) => key.split('.').reduce((o, k) => (o == null ? o : o[k]), translations[lang]);
|
|
let s = lookup(current);
|
|
if (s == null) s = lookup('en');
|
|
if (s == null) return key;
|
|
if (typeof s === 'string' && vars) {
|
|
s = s.replace(/\{(\w+)\}/g, (m, k) => (k in vars ? vars[k] : m));
|
|
}
|
|
return s;
|
|
}
|