50 lines
1.0 KiB
TypeScript
50 lines
1.0 KiB
TypeScript
import type { AttemptResult } from '@flashcard/shared';
|
|
|
|
export const MAX_BOX = 5;
|
|
// index 1..5; index 0 unused
|
|
export const BOX_INTERVALS_SEC: Record<number, number> = {
|
|
1: 0,
|
|
2: 1 * 24 * 60 * 60,
|
|
3: 3 * 24 * 60 * 60,
|
|
4: 7 * 24 * 60 * 60,
|
|
5: 14 * 24 * 60 * 60,
|
|
};
|
|
|
|
export interface ProgressLike {
|
|
box: number;
|
|
correctCount: number;
|
|
incorrectCount: number;
|
|
}
|
|
|
|
export interface ProgressDelta {
|
|
box: number;
|
|
correctCount: number;
|
|
incorrectCount: number;
|
|
nextDueAt: number;
|
|
lastShownAt: number;
|
|
}
|
|
|
|
export function applyResult(
|
|
current: ProgressLike,
|
|
result: AttemptResult,
|
|
nowSec: number
|
|
): ProgressDelta {
|
|
let box = current.box;
|
|
let correctCount = current.correctCount;
|
|
let incorrectCount = current.incorrectCount;
|
|
if (result === 'correct') {
|
|
box = Math.min(MAX_BOX, current.box + 1);
|
|
correctCount += 1;
|
|
} else {
|
|
box = 1;
|
|
incorrectCount += 1;
|
|
}
|
|
return {
|
|
box,
|
|
correctCount,
|
|
incorrectCount,
|
|
nextDueAt: nowSec + BOX_INTERVALS_SEC[box]!,
|
|
lastShownAt: nowSec,
|
|
};
|
|
}
|