Files
englishPk/app/pk/utils.ts
T

62 lines
2.2 KiB
TypeScript

import { defaultSettings } from "./constants";
import type { AppSettings } from "./types";
export function shuffleArray<T>(array: T[]) {
const next = [...array];
for (let i = next.length - 1; i > 0; i -= 1) {
const j = Math.floor(Math.random() * (i + 1));
[next[i], next[j]] = [next[j], next[i]];
}
return next;
}
export function mergeSettings(settings: Partial<AppSettings>): AppSettings {
return {
ttsVoice: settings.ttsVoice || defaultSettings.ttsVoice,
ttsRate: settings.ttsRate || defaultSettings.ttsRate,
scorePerCorrect: Number(settings.scorePerCorrect ?? defaultSettings.scorePerCorrect),
scorePerWrong: Number(settings.scorePerWrong ?? defaultSettings.scorePerWrong),
autoSpeak: settings.autoSpeak ?? defaultSettings.autoSpeak,
wordDisplayMode:
settings.wordDisplayMode === "capitalize" ||
settings.wordDisplayMode === "input" ||
settings.wordDisplayMode === "uppercase"
? settings.wordDisplayMode
: defaultSettings.wordDisplayMode,
pkWordCount: Math.max(0, Math.floor(Number(settings.pkWordCount ?? defaultSettings.pkWordCount))),
pkOptionCount: normalizeOptionCount(Number(settings.pkOptionCount ?? defaultSettings.pkOptionCount)),
};
}
export function getFairRoundCount(availableCount: number, limit: number) {
const requestedCount = limit > 0 ? Math.min(limit, availableCount) : availableCount;
if (requestedCount < 2) return requestedCount;
return requestedCount % 2 === 0 ? requestedCount : requestedCount - 1;
}
export function formatWordDisplay(text: string, mode: AppSettings["wordDisplayMode"]) {
if (mode === "input") return text;
if (mode === "capitalize") {
return text
.split(/(\s+)/)
.map((part) => {
if (/^\s+$/.test(part) || !part) return part;
return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
})
.join("");
}
return text.toUpperCase();
}
export function normalizeOptionCount(value: number) {
const count = Math.floor(value);
if (!Number.isFinite(count)) return defaultSettings.pkOptionCount;
if (count < 2) return 2;
if (count > 8) return 8;
return count % 2 === 0 ? count : count + 1;
}
export function isImageSource(value: string) {
return /^(https?:\/\/|\/|data:image\/)/i.test(value);
}