aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/client/atoms/study.ts
blob: 2e3e1ea53b08120415684d9653596a2949d42218 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import { apiClient } from "../api/client";
import { shuffle } from "../utils/shuffle";
import { createReloadableAtomFamily } from "./utils";

export interface StudyCard {
	id: string;
	deckId: string;
	noteId: string;
	isReversed: boolean;
	front: string;
	back: string;
	state: number;
	due: string;
	stability: number;
	difficulty: number;
	reps: number;
	lapses: number;
	noteType: {
		frontTemplate: string;
		backTemplate: string;
	};
	fieldValuesMap: Record<string, string>;
}

export interface StudyDeck {
	id: string;
	name: string;
}

export interface StudyData {
	deck: StudyDeck;
	cards: StudyCard[];
}

// =====================
// Study Session - Suspense-compatible
// =====================

export const studyDataAtomFamily = createReloadableAtomFamily(
	async (deckId: string): Promise<StudyData> => {
		// Fetch deck and due cards in parallel
		const [deckRes, cardsRes] = await Promise.all([
			apiClient.rpc.api.decks[":id"].$get({ param: { id: deckId } }),
			apiClient.rpc.api.decks[":deckId"].study.$get({ param: { deckId } }),
		]);

		const deckData = await apiClient.handleResponse<{ deck: StudyDeck }>(
			deckRes,
		);
		const cardsData = await apiClient.handleResponse<{ cards: StudyCard[] }>(
			cardsRes,
		);

		return {
			deck: deckData.deck,
			cards: shuffle(cardsData.cards),
		};
	},
);