Refactor PK page and add Trellis setup
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user