Skip to content

Commit 0587f5b

Browse files
committed
various improvements, add grammar_details
1 parent 8323514 commit 0587f5b

21 files changed

+31515
-1662
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ yarn-error.*
4343
*.tsbuildinfo
4444

4545

46-
scripts/data
46+
scripts/data/*
47+
!scripts/data/grammar_details.json
4748

4849
# ignore ios
4950
ios/

.yarn/install-state.gz

-27.4 KB
Binary file not shown.

.yarn/releases/yarn-4.1.1.cjs .yarn/releases/yarn-4.3.0.cjs

+343-342
Large diffs are not rendered by default.

.yarnrc.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
nodeLinker: node-modules
22

3-
yarnPath: .yarn/releases/yarn-4.1.1.cjs
3+
yarnPath: .yarn/releases/yarn-4.3.0.cjs

app.json

+16-15
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,42 @@
88
"scheme": "myapp",
99
"userInterfaceStyle": "automatic",
1010
"splash": {
11-
"image": "./assets/images/splash.png",
12-
"resizeMode": "contain",
11+
"image": "./assets/images/splash-jellip.png",
12+
"resizeMode": "cover",
1313
"backgroundColor": "#ffffff"
1414
},
15-
"assetBundlePatterns": [
16-
"**/*"
17-
],
15+
"assetBundlePatterns": ["**/*"],
1816
"ios": {
1917
"supportsTablet": true,
2018
"bundleIdentifier": "dev.mmtf.jlpt-practice",
2119
"infoPlist": {
22-
"LSApplicationQueriesSchemes": [
23-
"shirabelookup"
24-
]
20+
"LSApplicationQueriesSchemes": ["shirabelookup"]
2521
}
2622
},
2723
"android": {
2824
"adaptiveIcon": {
2925
"foregroundImage": "./assets/images/adaptive-icon.png",
3026
"backgroundColor": "#ffffff"
3127
},
32-
"package": "com.anonymous.jlptpractice"
28+
"package": "dev.mmtf.jlpt-practice"
3329
},
3430
"web": {
3531
"bundler": "metro",
3632
"output": "static",
3733
"favicon": "./assets/images/favicon.png"
3834
},
39-
"plugins": [
40-
"expo-router",
41-
"expo-build-properties",
42-
"expo-font"
43-
],
35+
"plugins": ["expo-router", "expo-build-properties", "expo-font"],
4436
"experiments": {
4537
"typedRoutes": true
46-
}
38+
},
39+
"extra": {
40+
"router": {
41+
"origin": false
42+
},
43+
"eas": {
44+
"projectId": "dff87a81-66f6-4afb-aed0-ac90289b3417"
45+
}
46+
},
47+
"owner": "mmdf"
4748
}
4849
}

app/(tabs)/grammar.tsx

+1-66
Original file line numberDiff line numberDiff line change
@@ -1,66 +1 @@
1-
import { Input, ScrollView, useMedia, XStack } from "tamagui";
2-
import { useRouter } from "expo-router";
3-
4-
import { ListItem, Text } from "tamagui";
5-
import { useRoute } from "@react-navigation/native";
6-
import Details from "../../scripts/data/grammar_details.json";
7-
import { BookKey, ChevronRight, Search } from "@tamagui/lucide-icons";
8-
import { FlatList } from "react-native";
9-
import { useMemo, useState } from "react";
10-
11-
const LevelComp = ({ level }: { level: string }) => {
12-
return (
13-
<XStack gap="$2" ai="center">
14-
<XStack px="$2" py="$1" br="$4" bg={"$gray4"}>
15-
<Text color="$gray9">{level}</Text>
16-
</XStack>
17-
<ChevronRight />
18-
</XStack>
19-
);
20-
};
21-
export default function () {
22-
const r = useRouter();
23-
const [search, setSearch] = useState("");
24-
25-
const results = useMemo(
26-
() =>
27-
search === ""
28-
? Details
29-
: Details.filter(
30-
(d) =>
31-
d.main_grammar.includes(search) ||
32-
d.meaning?.actual?.toLowerCase()?.includes(search) ||
33-
d.jlpt_level?.toLowerCase()?.includes(search)
34-
),
35-
[search]
36-
);
37-
return (
38-
<>
39-
<XStack ai="center" px="$3" gap="$2" py="$2">
40-
<Search />
41-
<Input flex={1} onChangeText={(r) => setSearch(r.toLowerCase())} />
42-
</XStack>
43-
<FlatList
44-
data={results}
45-
getItemLayout={(data, index) => ({
46-
length: 65,
47-
offset: 65 * index,
48-
index,
49-
})}
50-
renderItem={({ item }) => (
51-
<ListItem
52-
hoverTheme
53-
pressTheme
54-
title={item.main_grammar}
55-
subTitle={item.meaning.actual}
56-
icon={BookKey}
57-
iconAfter={<LevelComp level={item.jlpt_level} />}
58-
onPress={() => {
59-
r.push(`/grammar/${item.id}`);
60-
}}
61-
/>
62-
)}
63-
/>
64-
</>
65-
);
66-
}
1+
export { default } from "../grammar/list";

app/(tabs)/question.tsx

+10-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import { AnimatePresence, Heading, Paragraph, View, YStack } from "tamagui";
2-
import { useCallback, useEffect, useState } from "react";
1+
import { QuestionView } from "@/components/QuestionView";
32
import {
43
getRandomQuestion,
54
QuestionWithAnswers,
65
submitAnswer,
76
} from "@/services/questions";
7+
import { settingsStore } from "@/services/store";
88
import { useToastController } from "@tamagui/toast";
9+
import { useCallback, useEffect, useState } from "react";
10+
import { AnimatePresence, Heading, Paragraph, View, YStack } from "tamagui";
911
import * as zod from "zod";
10-
import { QuestionView } from "@/components/QuestionView";
11-
import { settingsStore } from "@/services/store";
1212
import { usePermuteAnswers } from "../../components/usePermuteAnswers";
1313

1414
const questionSchema = zod.object({
@@ -24,21 +24,22 @@ function QuestionManager() {
2424
const [solvedId, setSolvedId] = useState(0);
2525
const [answer, setAnswer] = useState<null | number>(null);
2626
const [questionBase, setQuestion] = useState<QuestionWithAnswers | null>(
27-
null,
27+
null
2828
);
2929
const [loading, setLoading] = useState(false);
3030
const toast = useToastController();
3131

3232
const [categoryFilter, levelFilter] = settingsStore((state) => [
3333
state.data.categoryFilter,
34-
state.data.levelFilter,
34+
state.data.questionLevelFilter,
3535
]);
3636

3737
const fetchQuestion = useCallback(
3838
async function () {
3939
setLoading(true);
4040
try {
41-
const { categoryFilter, levelFilter } = settingsStore.getState().data;
41+
const { categoryFilter, questionLevelFilter: levelFilter } =
42+
settingsStore.getState().data;
4243
const question = await getRandomQuestion({
4344
categoryFilter: categoryFilter.length ? categoryFilter : undefined,
4445
levelFilter: levelFilter.length ? levelFilter : undefined,
@@ -67,7 +68,7 @@ function QuestionManager() {
6768
setLoading(false);
6869
}
6970
},
70-
[setQuestion],
71+
[setQuestion]
7172
);
7273

7374
useEffect(() => {
@@ -104,7 +105,7 @@ function QuestionManager() {
104105
bottom={0}
105106
animation="fast"
106107
paddingHorizontal="$8"
107-
key={solvedId} // animate out even if it's the same question
108+
key={solvedId}
108109
exitStyle={{ transform: [{ translateX: 200 }], opacity: 0 }}
109110
enterStyle={{ transform: [{ translateX: -200 }], opacity: 0 }}
110111
transform={[{ translateX: 0 }]}

app/(tabs)/settings.tsx

+23-26
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,15 @@
1+
import { Statistics } from "@/components/Statistics";
12
import {
23
getAnswersToday,
34
getQuestionSeenStats,
45
Question,
56
QuestionAnswer,
67
QuestionWithAnswers,
78
} from "@/services/questions";
8-
import React, { useEffect, useMemo } from "react";
9-
import {
10-
YStack,
11-
Heading,
12-
Text,
13-
XStack,
14-
Label,
15-
useTheme,
16-
View,
17-
useMedia,
18-
Paragraph,
19-
Button,
20-
ScrollView,
21-
} from "tamagui";
229
import { answersTodayStore, settingsStore } from "@/services/store";
23-
import { MultipleSelectBox, SelectBox } from "../../components/SelectBox";
24-
import { useRouter } from "expo-router";
25-
import { Alert } from "react-native";
26-
import { resetAndReseed } from "../../components/SeedProvider";
27-
import { Delete } from "@tamagui/lucide-icons";
28-
import { Statistics } from "@/components/Statistics";
10+
import React, { useEffect } from "react";
11+
import { H5, Heading, Label, ScrollView, XStack, YStack } from "tamagui";
12+
import { MultipleSelectBox } from "../../components/SelectBox";
2913

3014
const levelItems: { name: Question["level"] }[] = [
3115
{ name: "N1" },
@@ -34,13 +18,19 @@ const levelItems: { name: Question["level"] }[] = [
3418
{ name: "N4" },
3519
{ name: "N5" },
3620
];
37-
const LevelFilter = () => {
38-
const filters = settingsStore((state) => state.data.levelFilter);
39-
const [val, setVal] = React.useState<QuestionWithAnswers["level"][]>(filters);
21+
const LevelFilter = ({
22+
settingKey: settingsKey,
23+
}: {
24+
settingKey: "questionLevelFilter" | "grammarLevelFilter";
25+
}) => {
26+
const filters = settingsStore((state) => state.data[settingsKey]);
27+
const [val, setVal] = React.useState<QuestionWithAnswers["level"][]>(
28+
filters || []
29+
);
4030
const name = "Level Filter";
4131
useEffect(() => {
4232
settingsStore.getState().update((state) => {
43-
state.levelFilter = val;
33+
state[settingsKey] = val;
4434
});
4535
}, [val]);
4636

@@ -107,7 +97,9 @@ const SettingsTab: React.FC = () => {
10797
null
10898
);
10999

110-
const { categoryFilter, levelFilter } = settingsStore((state) => state.data);
100+
const { categoryFilter, questionLevelFilter: levelFilter } = settingsStore(
101+
(state) => state.data
102+
);
111103

112104
useEffect(() => {
113105
getQuestionSeenStats({
@@ -123,8 +115,13 @@ const SettingsTab: React.FC = () => {
123115
<YStack padding="$8" gap="$4">
124116
<Heading>Settings</Heading>
125117
<YStack gap="$2">
118+
<H5>Question Filters</H5>
126119
<CategoryFilter />
127-
<LevelFilter />
120+
<LevelFilter settingKey="questionLevelFilter" />
121+
</YStack>
122+
<YStack gap="$2">
123+
<H5>Grammar Filters</H5>
124+
<LevelFilter settingKey="grammarLevelFilter" />
128125
</YStack>
129126
<Heading>Statistics</Heading>
130127
<Statistics

app/_layout.tsx

+10-9
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,23 @@ import {
33
DarkTheme,
44
DefaultTheme,
55
ThemeProvider,
6-
useRoute,
76
} from "@react-navigation/native";
87
import { useFonts } from "expo-font";
9-
import { Stack, useRouter } from "expo-router";
8+
import { Stack } from "expo-router";
109
import * as SplashScreen from "expo-splash-screen";
1110
import { useEffect } from "react";
1211

13-
import { useColorScheme } from "react-native";
14-
import MigrationProvider from "../components/MigrationProvider";
15-
import { TamaguiProvider, Theme, YStack } from "tamagui";
12+
import { tamaguiConfig } from "@/constants/tamagui";
1613
import {
1714
Toast,
1815
ToastProvider,
1916
ToastViewport,
2017
useToastState,
2118
} from "@tamagui/toast";
22-
import { tamaguiConfig } from "@/constants/tamagui";
23-
import { useRehydrate } from "@colorfy-software/zfy";
24-
import { stores } from "@/services/store";
19+
import { useColorScheme } from "react-native";
2520
import { useSafeAreaInsets } from "react-native-safe-area-context";
21+
import { TamaguiProvider, YStack } from "tamagui";
22+
import MigrationProvider from "../components/MigrationProvider";
2623

2724
export {
2825
// Catch any errors thrown by the Layout component.
@@ -115,7 +112,11 @@ function RootLayoutNav() {
115112
name="grammar/[id]"
116113
options={{ title: "Grammar" }}
117114
/>
118-
<Stack.Screen name="review" options={{ presentation: "modal" }} />
115+
<Stack.Screen
116+
name="grammar/list"
117+
options={{ title: "Grammar List" }}
118+
/>
119+
<Stack.Screen name="review" options={{ title: "Review" }} />
119120
</Stack>
120121
</MigrationProvider>
121122
</ToastProvider>

0 commit comments

Comments
 (0)