init commit,

This commit is contained in:
louiscklaw
2025-04-26 10:08:01 +08:00
parent 7d70b5826b
commit d0ea7e5452
473 changed files with 29989 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
import React, { createContext, useContext, useEffect, useState } from 'react';
import { useIdle } from 'react-use';
import { useAppUseTime } from './MyIonMetric/AppUseTime';
const AppOnRecorderContext = createContext<MyContextProps | undefined>(undefined);
export const AppOnRecorderProvider: React.FC = () => {
const [my_context, setMyContext] = useState<string>('initial value');
const { myIonMetricIncAppUseTime } = useAppUseTime();
const isIdle = useIdle(3e3);
let getCurrentTimeInSec = () => Math.floor(Date.now() / 1000);
let [last_on_s, setLastOn_s] = useState(getCurrentTimeInSec());
useEffect(() => {
(async () => {
if (isIdle) {
// active -> inactive
let current_s = getCurrentTimeInSec();
myIonMetricIncAppUseTime(current_s - last_on_s);
} else {
// inactive->active
setLastOn_s(getCurrentTimeInSec());
}
})();
}, [isIdle]);
return <AppOnRecorderContext.Provider value={{ my_context, setMyContext }}>{/* */}</AppOnRecorderContext.Provider>;
};
export const useMyContext = (): MyContextProps => {
const context = useContext(AppOnRecorderContext);
if (!context) {
throw new Error('useMyContext must be used within a MyProvider');
}
return context;
};
interface MyContextProps {
my_context: string;
setMyContext: React.Dispatch<React.SetStateAction<string>>;
}

View File

@@ -0,0 +1,145 @@
import React, { createContext, ReactNode, useContext, useEffect, useState } from 'react';
import RemoveFavoritePrompt from '../components/RemoveFavoritePrompt';
import { LESSON_LINK } from '../constants';
const AppStateContext = createContext<AppStateContextProps | undefined>(undefined);
export const AppStateProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [my_context, setMyContext] = useState<string>('initial value');
const [tab_active, setTabActive] = useState<string>(LESSON_LINK);
const [show_confirm_user_exit, useShowConfirmUserExit] = useState<boolean>(false);
const [url_push_after_user_confirm, setURLPushAfterUserConfirm] = useState<string>(LESSON_LINK);
const [matching_frenzy_in_progress, setMatchingFrenzyInProgress] = useState<boolean>(false);
const [connective_revision_in_progress, setConnectiveRevisionInProgress] = useState<boolean>(false);
const [listening_practice_in_progress, setListeningPracticeInProgress] = useState<boolean>(false);
const [disable_user_tap, setDisableUserTap] = useState<boolean>(false);
const [show_remove_fav_prompt, setShowRemoceFavPrompt] = useState(false);
// 010_user_configurable_anwered_timeout
const [LISTENING_PRACTICE_ANWERED_WAIT_S, setListeningPracticeAnswerWait_s] = useState<number>(1);
const [MATCHING_FRENZY_ANWERED_WAIT_S, setMatchingFrenzyAnswerWait_s] = useState<number>(1);
//
const [WRONG_ANS_TOAST_APPEAR_TIMEOUT_S, setWRONG_ANS_TOAST_APPEAR_TIMEOUT_S] = useState<number>(3);
const [CORRECT_ANS_TOAST_APPEAR_TIMEOUT_S, setCORRECT_ANS_TOAST_APPEAR_TIMEOUT_S] = useState<number>(3);
const [CONNECTIVES_REVISION_ANWERED_WAIT_S, setCONNECTIVES_REVISION_ANWERED_WAIT_S] = useState<number>(3);
// user_config.json
// 012_put_matching_frenzy_count_down_time_to_config_file
const [user_config_json, setUserConfigJson] = useState<any>({});
const [MATCHING_FRENZY_COUNT_DOWN_S, setMATCHING_FRENZY_COUNT_DOWN_S] = useState<number>(120);
useEffect(() => {
fetch('/data/user_config.json')
.then((res) => res.json())
.then((res_json) => {
setUserConfigJson(res_json);
setMATCHING_FRENZY_COUNT_DOWN_S(res_json['matching_frenzy_count_down_s']);
setListeningPracticeAnswerWait_s(res_json['listening_practice_anwered_wait_s']);
setMatchingFrenzyAnswerWait_s(res_json['matching_frenzy_anwered_wait_s']);
setCONNECTIVES_REVISION_ANWERED_WAIT_S(res_json['connectives_revision_anwered_wait_s']);
// console.log({ res_json });
setWRONG_ANS_TOAST_APPEAR_TIMEOUT_S(res_json['WRONG_ANS_TOAST_APPEAR_TIMEOUT_S']);
setCORRECT_ANS_TOAST_APPEAR_TIMEOUT_S(res_json['CORRECT_ANS_TOAST_APPEAR_TIMEOUT_S']);
});
}, []);
return (
<AppStateContext.Provider
value={{
my_context,
setMyContext,
//
tab_active,
setTabActive,
//
listening_practice_in_progress,
setListeningPracticeInProgress,
//
matching_frenzy_in_progress,
setMatchingFrenzyInProgress,
//
connective_revision_in_progress,
setConnectiveRevisionInProgress,
//
show_confirm_user_exit,
setShowConfirmUserExit: useShowConfirmUserExit,
//
url_push_after_user_confirm,
setURLPushAfterUserConfirm,
//
disable_user_tap,
setDisableUserTap,
//
show_remove_fav_prompt,
setShowRemoceFavPrompt,
//
// 012_put_matching_frenzy_count_down_time_to_config_file
MATCHING_FRENZY_COUNT_DOWN_S,
//
LISTENING_PRACTICE_ANWERED_WAIT_S,
MATCHING_FRENZY_ANWERED_WAIT_S,
CONNECTIVES_REVISION_ANWERED_WAIT_S,
//
WRONG_ANS_TOAST_APPEAR_TIMEOUT_S,
CORRECT_ANS_TOAST_APPEAR_TIMEOUT_S,
}}
>
{children}
<RemoveFavoritePrompt open={show_remove_fav_prompt} setIsOpen={setShowRemoceFavPrompt} />
</AppStateContext.Provider>
);
};
export const useAppStateContext = (): AppStateContextProps => {
const context = useContext(AppStateContext);
if (!context) {
throw new Error('useMyContext must be used within a MyProvider');
}
return context;
};
interface AppStateContextProps {
my_context: string;
setMyContext: React.Dispatch<React.SetStateAction<string>>;
//
listening_practice_in_progress: boolean;
setListeningPracticeInProgress: React.Dispatch<React.SetStateAction<boolean>>;
//
//
matching_frenzy_in_progress: boolean;
setMatchingFrenzyInProgress: React.Dispatch<React.SetStateAction<boolean>>;
//
connective_revision_in_progress: boolean;
setConnectiveRevisionInProgress: React.Dispatch<React.SetStateAction<boolean>>;
//
tab_active: string;
setTabActive: React.Dispatch<React.SetStateAction<string>>;
//
show_confirm_user_exit: boolean;
setShowConfirmUserExit: React.Dispatch<React.SetStateAction<boolean>>;
//
url_push_after_user_confirm: string;
setURLPushAfterUserConfirm: React.Dispatch<React.SetStateAction<string>>;
//
disable_user_tap: boolean;
setDisableUserTap: React.Dispatch<React.SetStateAction<boolean>>;
//
show_remove_fav_prompt: boolean;
setShowRemoceFavPrompt: React.Dispatch<React.SetStateAction<boolean>>;
//
MATCHING_FRENZY_COUNT_DOWN_S: number;
//
LISTENING_PRACTICE_ANWERED_WAIT_S: number;
MATCHING_FRENZY_ANWERED_WAIT_S: number;
CONNECTIVES_REVISION_ANWERED_WAIT_S: number;
//
WRONG_ANS_TOAST_APPEAR_TIMEOUT_S: number;
CORRECT_ANS_TOAST_APPEAR_TIMEOUT_S: number;
}

View File

@@ -0,0 +1,8 @@
export interface ConnectiveRevisionAllResult {
[quiz_name: string]: number;
}
export interface ConnectiveRevisionResult {
date: string;
progress: number;
}

View File

@@ -0,0 +1,91 @@
import { Haptics, ImpactStyle } from '@capacitor/haptics';
import React, { createContext, ReactNode, useContext, useState } from 'react';
const MyContext = createContext<MyContextProps | undefined>(undefined);
const hapticsImpactMedium = async () => {
await Haptics.impact({ style: ImpactStyle.Medium });
};
const hapticsImpactLight = async () => {
await Haptics.impact({ style: ImpactStyle.Light });
};
const hapticsVibrate = async () => {
await Haptics.vibrate();
};
const hapticsSelectionStart = async () => {
await Haptics.selectionStart();
};
const hapticsSelectionChanged = async () => {
await Haptics.selectionChanged();
};
const hapticsSelectionEnd = async () => {
await Haptics.selectionEnd();
};
export const MyProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [my_context, setMyContext] = useState<string>('initial value');
const [test_first, setTestFirst] = useState<IFirst | undefined>(undefined);
const [test_second, setTestSecond] = useState<ISecond | undefined>(undefined);
const [test_third, setTestThird] = useState<IThird | undefined>(undefined);
return (
<MyContext.Provider
value={{
my_context,
setMyContext,
//
test_first,
setTestFirst,
test_second,
setTestSecond,
test_third,
setTestThird,
}}
>
{children}
</MyContext.Provider>
);
};
export const useMyContext = (): MyContextProps => {
const context = useContext(MyContext);
if (!context) {
throw new Error('useMyContext must be used within a MyProvider');
}
return context;
};
interface MyContextProps {
my_context: string;
setMyContext: React.Dispatch<React.SetStateAction<string>>;
//
test_first: IFirst | undefined;
setTestFirst: React.Dispatch<React.SetStateAction<IFirst | undefined>>;
test_second: ISecond | undefined;
setTestSecond: React.Dispatch<React.SetStateAction<ISecond | undefined>>;
test_third: IThird | undefined;
setTestThird: React.Dispatch<React.SetStateAction<IThird | undefined>>;
}
interface IFirst {
test_s: string;
test_i: number;
}
interface ISecond {
test_s: string;
test_i: number;
content: IFirst[] | [];
}
interface IThird {
test_s: string;
test_i: number;
content: ISecond[] | [];
}

View File

@@ -0,0 +1,66 @@
import React, { createContext, ReactNode, useContext, useState } from 'react';
const MyContext = createContext<MyContextProps | undefined>(undefined);
export const MyProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [my_context, setMyContext] = useState<string>('initial value');
const [test_first, setTestFirst] = useState<IFirst | undefined>(undefined);
const [test_second, setTestSecond] = useState<ISecond | undefined>(undefined);
const [test_third, setTestThird] = useState<IThird | undefined>(undefined);
return (
<MyContext.Provider
value={{
my_context,
setMyContext,
//
test_first,
setTestFirst,
test_second,
setTestSecond,
test_third,
setTestThird,
}}
>
{children}
</MyContext.Provider>
);
};
export const useMyContext = (): MyContextProps => {
const context = useContext(MyContext);
if (!context) {
throw new Error('useMyContext must be used within a MyProvider');
}
return context;
};
interface MyContextProps {
my_context: string;
setMyContext: React.Dispatch<React.SetStateAction<string>>;
//
test_first: IFirst | undefined;
setTestFirst: React.Dispatch<React.SetStateAction<IFirst | undefined>>;
test_second: ISecond | undefined;
setTestSecond: React.Dispatch<React.SetStateAction<ISecond | undefined>>;
test_third: IThird | undefined;
setTestThird: React.Dispatch<React.SetStateAction<IThird | undefined>>;
}
interface IFirst {
test_s: string;
test_i: number;
}
interface ISecond {
test_s: string;
test_i: number;
content: IFirst[] | [];
}
interface IThird {
test_s: string;
test_i: number;
content: ISecond[] | [];
}

View File

@@ -0,0 +1,7 @@
export interface MatchingFrezyRanking {
ranking: MatchingFrenzyResult[] | [];
}
export interface MatchingFrenzyResult {
date: string;
result: number;
}

View File

@@ -0,0 +1,138 @@
import React, { createContext, ReactNode, useContext } from 'react';
import { useMyIonStore } from './MyIonStore';
const MyIonFavoriteContext = createContext<MyContextProps | undefined>(undefined);
export const MyIonFavoriteProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const { myIonStoreRead, myIonStoreWrite, user_store } = useMyIonStore();
async function myIonStoreAddFavorite(address_to_add: string) {
console.log('myIonStoreAddFavorite', address_to_add);
let current_fav = await JSON.parse(await myIonStoreRead('lesson_favorite_word'));
if (JSON.stringify(current_fav) == '{}') current_fav = [];
current_fav = [...current_fav, address_to_add];
await myIonStoreWrite('lesson_favorite_word', JSON.stringify(current_fav));
}
async function myIonStoreRemoveFavorite(address_to_remove: string) {
let current_fav = await JSON.parse(await myIonStoreRead('lesson_favorite_word'));
current_fav = current_fav.filter((address: string) => address !== address_to_remove);
await myIonStoreWrite('lesson_favorite_word', JSON.stringify(current_fav));
}
async function myIonStoreLoadFavorite() {
let current_fav = await JSON.parse(await myIonStoreRead('lesson_favorite_word'));
return current_fav ? current_fav : [];
}
async function myIonStoreFindInFavorite(string_to_search: string) {
const current_fav = await myIonStoreLoadFavorite();
return current_fav.includes(string_to_search);
}
//
const KEY_FAV_VOCBULARY = 'lesson_favorite_vocabulary';
async function myIonStoreAddFavoriteVocabulary(address_to_add: string) {
console.log('myIonStoreAddFavorite', address_to_add);
let current_fav = await JSON.parse(await myIonStoreRead(KEY_FAV_VOCBULARY));
if (JSON.stringify(current_fav) == '{}') current_fav = [];
current_fav = [...current_fav, address_to_add];
await myIonStoreWrite(KEY_FAV_VOCBULARY, JSON.stringify(current_fav));
}
async function myIonStoreRemoveFavoriteVocabulary(address_to_remove: string) {
let current_fav = await JSON.parse(await myIonStoreRead(KEY_FAV_VOCBULARY));
current_fav = current_fav.filter((address: string) => address !== address_to_remove);
await myIonStoreWrite(KEY_FAV_VOCBULARY, JSON.stringify(current_fav));
}
async function myIonStoreLoadFavoriteVocabulary(): Promise<string[]> {
let result = await myIonStoreRead(KEY_FAV_VOCBULARY);
if (result == '{}') return [];
let current_fav = JSON.parse(result);
return current_fav;
}
async function myIonStoreFindInFavoriteVocabulary(string_to_search: string): Promise<boolean> {
const current_fav = await myIonStoreLoadFavoriteVocabulary();
console.log({ current_fav });
return current_fav.includes(string_to_search);
}
//
const KEY_FAV_CONNECTIVES = 'lesson_favorite_connectives';
async function myIonStoreAddFavoriteConnectives(address_to_add: string) {
console.log('myIonStoreAddFavorite', address_to_add);
let current_fav = await JSON.parse(await myIonStoreRead(KEY_FAV_CONNECTIVES));
if (JSON.stringify(current_fav) == '{}') current_fav = [];
current_fav = [...current_fav, address_to_add];
await myIonStoreWrite(KEY_FAV_CONNECTIVES, JSON.stringify(current_fav));
}
async function myIonStoreRemoveFavoriteConnectives(address_to_remove: string) {
let current_fav = await JSON.parse(await myIonStoreRead(KEY_FAV_CONNECTIVES));
current_fav = current_fav.filter((address: string) => address !== address_to_remove);
await myIonStoreWrite(KEY_FAV_CONNECTIVES, JSON.stringify(current_fav));
}
async function myIonStoreLoadFavoriteConnectives(): Promise<string[]> {
let temp = await myIonStoreRead(KEY_FAV_CONNECTIVES);
let current_fav = await JSON.parse(temp);
return current_fav ? current_fav : [];
}
async function myIonStoreFindInFavoriteConnectives(string_to_search: string) {
const current_fav = await myIonStoreLoadFavoriteConnectives();
return current_fav.includes(string_to_search);
}
return (
<MyIonFavoriteContext.Provider
value={{
myIonStoreAddFavorite,
myIonStoreRemoveFavorite,
myIonStoreLoadFavorite,
myIonStoreFindInFavorite,
//
myIonStoreAddFavoriteVocabulary,
myIonStoreRemoveFavoriteVocabulary,
myIonStoreLoadFavoriteVocabulary,
myIonStoreFindInFavoriteVocabulary,
//
myIonStoreAddFavoriteConnectives,
myIonStoreRemoveFavoriteConnectives,
myIonStoreLoadFavoriteConnectives,
myIonStoreFindInFavoriteConnectives,
}}
>
{children}
</MyIonFavoriteContext.Provider>
);
};
export const useMyIonFavorite = (): MyContextProps => {
const context = useContext(MyIonFavoriteContext);
if (!context) {
throw new Error('useMyContext must be used within a MyProvider');
}
return context;
};
interface MyContextProps {
myIonStoreAddFavorite: (address_to_add: string) => Promise<void>;
myIonStoreRemoveFavorite: (address_to_add: string) => Promise<void>;
myIonStoreLoadFavorite: () => Promise<[]>;
myIonStoreFindInFavorite: (string_to_search: string) => Promise<boolean>;
//
myIonStoreAddFavoriteVocabulary: (address_to_add: string) => Promise<void>;
myIonStoreRemoveFavoriteVocabulary: (address_to_add: string) => Promise<void>;
myIonStoreLoadFavoriteVocabulary: () => Promise<string[]>;
myIonStoreFindInFavoriteVocabulary: (string_to_search: string) => Promise<boolean>;
//
myIonStoreAddFavoriteConnectives: (address_to_add: string) => Promise<void>;
myIonStoreRemoveFavoriteConnectives: (address_to_add: string) => Promise<void>;
myIonStoreLoadFavoriteConnectives: () => Promise<string[]>;
myIonStoreFindInFavoriteConnectives: (string_to_search: string) => Promise<boolean>;
}

View File

@@ -0,0 +1,78 @@
import React, { createContext, ReactNode, useContext } from 'react';
import { useMyIonMetric } from '.';
import { APP_USE_TIME } from '../../constants';
const AppUseTimeContext = createContext<AppUseTimeContextProps | undefined>(undefined);
export const AppUseTimeProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const { myIonStoreRead, myIonStoreWrite } = useMyIonMetric();
function Helloworld() {
console.log('helloworld');
}
async function myIonMetricGetAppUseTime() {
let result = JSON.parse(await myIonStoreRead(APP_USE_TIME, { time_spent_s: 0 }));
return result;
}
async function myIonMetricResetAppUseTime() {
await myIonStoreWrite(APP_USE_TIME, JSON.stringify({ time_spent_s: 0 }));
}
async function myIonMetricIncAppUseTime(time_spent_s: number) {
let result = await myIonMetricGetAppUseTime();
await myIonStoreWrite(APP_USE_TIME, JSON.stringify({ time_spent_s: result.time_spent_s + time_spent_s }));
}
async function myIonMetricSetAppUseTime(time_spent_s: number) {
await myIonStoreWrite(APP_USE_TIME, JSON.stringify({ time_spent_s: time_spent_s }));
}
async function myIonMetricGetAppUseTimeIgnore() {
let result = JSON.parse(await myIonStoreRead(APP_USE_TIME + '_ignore', { time_spent_s: 0 }));
return result;
}
async function myIonMetricSetAppUseTimeIgnore(time_spent_s: number) {
await myIonStoreWrite(APP_USE_TIME + '_ignore', JSON.stringify({ time_spent_s: time_spent_s }));
}
return (
<AppUseTimeContext.Provider
value={{
//
Helloworld,
myIonMetricGetAppUseTime,
myIonMetricResetAppUseTime,
myIonMetricIncAppUseTime,
//
myIonMetricSetAppUseTime,
myIonMetricGetAppUseTimeIgnore,
myIonMetricSetAppUseTimeIgnore,
}}
>
{/* */}
{children}
</AppUseTimeContext.Provider>
);
};
export const useAppUseTime = (): AppUseTimeContextProps => {
const context = useContext(AppUseTimeContext);
if (!context) {
throw new Error('useAppUseTime must be used within a AppUseTimeProvider');
}
return context;
};
interface AppUseTimeContextProps {
Helloworld: () => void;
myIonMetricGetAppUseTime: () => Promise<{ time_spent_s: number }>;
myIonMetricIncAppUseTime: (time_spent_s: number) => Promise<void>;
myIonMetricResetAppUseTime: () => Promise<void>;
//
myIonMetricSetAppUseTime: (time_spent_s: number) => Promise<void>;
myIonMetricGetAppUseTimeIgnore: () => Promise<{ time_spent_s: number }>;
myIonMetricSetAppUseTimeIgnore: (time_spent_s: number) => Promise<void>;
}

View File

@@ -0,0 +1,81 @@
import React, { createContext, ReactNode, useContext } from 'react';
import { useMyIonMetric } from '.';
import { CONNECTIVES_REVISION_CORRECT_COUNT } from '../../constants';
const ConnectivesRevisionCorrectCount = createContext<ConnectivesRevisionCorrectCountProps | undefined>(undefined);
export const ConnectivesRevisionCorrectCountProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const NS_KEY_IGNORE = `${CONNECTIVES_REVISION_CORRECT_COUNT}_ignore`;
const { myIonStoreRead, myIonStoreWrite } = useMyIonMetric();
function Helloworld() {
console.log('helloworld ConnectivesRevisionCorrectCountProvider');
}
async function myIonMetricGetConnectivesRevisionCorrectCount() {
let result = JSON.parse(await myIonStoreRead(CONNECTIVES_REVISION_CORRECT_COUNT, { count: 0 }));
return result;
}
async function myIonMetricResetConnectivesRevisionCorrectCount() {
await myIonStoreWrite(CONNECTIVES_REVISION_CORRECT_COUNT, JSON.stringify({ count: 0 }));
}
async function myIonMetricIncConnectivesRevisionCorrectCount() {
let result = await myIonMetricGetConnectivesRevisionCorrectCount();
await myIonStoreWrite(CONNECTIVES_REVISION_CORRECT_COUNT, JSON.stringify({ count: result.count + 1 }));
}
async function myIonMetricSetConnectivesRevisionCorrectCount(count: number) {
await myIonStoreWrite(CONNECTIVES_REVISION_CORRECT_COUNT, JSON.stringify({ count: count }));
}
async function myIonMetricGetConnectivesRevisionCorrectCountIgnore() {
let result = JSON.parse(await myIonStoreRead(NS_KEY_IGNORE, { count: 0 }));
return result;
}
async function myIonMetricSetConnectivesRevisionCorrectCountIgnore(count: number) {
await myIonStoreWrite(NS_KEY_IGNORE, JSON.stringify({ count: count }));
}
return (
<ConnectivesRevisionCorrectCount.Provider
value={{
Helloworld,
// ConnectivesRevisionCorrect
myIonMetricGetConnectivesRevisionCorrectCount,
myIonMetricResetConnectivesRevisionCorrectCount,
myIonMetricIncConnectivesRevisionCorrectCount,
//
myIonMetricSetConnectivesRevisionCorrectCount,
myIonMetricGetConnectivesRevisionCorrectCountIgnore,
myIonMetricSetConnectivesRevisionCorrectCountIgnore,
}}
>
{children}
</ConnectivesRevisionCorrectCount.Provider>
);
};
export const useConnectivesRevisionCorrectCount = (): ConnectivesRevisionCorrectCountProps => {
const context = useContext(ConnectivesRevisionCorrectCount);
if (!context) {
throw new Error('useConnectivesRevisionCorrectCount must be used within a MyProvider');
}
return context;
};
interface ConnectivesRevisionCorrectCountProps {
Helloworld: () => void;
// ConnectivesRevision
myIonMetricGetConnectivesRevisionCorrectCount: () => Promise<{ count: number }>;
myIonMetricResetConnectivesRevisionCorrectCount: () => Promise<void>;
myIonMetricIncConnectivesRevisionCorrectCount: () => Promise<void>;
//
myIonMetricSetConnectivesRevisionCorrectCount: (count: number) => Promise<void>;
myIonMetricGetConnectivesRevisionCorrectCountIgnore: () => Promise<{ count: number }>;
myIonMetricSetConnectivesRevisionCorrectCountIgnore: (count: number) => Promise<void>;
}

View File

@@ -0,0 +1,77 @@
import React, { createContext, ReactNode, useContext } from 'react';
import { useMyIonMetric } from '.';
import { FULLMARK_COUNT_KEY, FULLMARK_IGNORE_COUNT } from '../../constants';
const FullmarkCountContext = createContext<FullmarkCountContextProps | undefined>(undefined);
export const FullmarkCountProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const { myIonStoreRead, myIonStoreWrite } = useMyIonMetric();
function Helloworld() {
console.log('helloworld');
}
async function myIonMetricGetFullMarkCount() {
let result = JSON.parse(await myIonStoreRead(FULLMARK_COUNT_KEY, { count: 0 }));
return result;
}
async function myIonMetricResetFullMarkCount() {
await myIonStoreWrite(FULLMARK_COUNT_KEY, JSON.stringify({ count: 0 }));
}
async function myIonMetricIncFullMarkCount() {
let result = await myIonMetricGetFullMarkCount();
await myIonStoreWrite(FULLMARK_COUNT_KEY, JSON.stringify({ count: result.count + 1 }));
}
async function myIonMetricSetFullMarkCount(num: number) {
await myIonStoreWrite(FULLMARK_COUNT_KEY, JSON.stringify({ count: num }));
}
async function myIonMetricSetFullMarkIgnore(num: number) {
await myIonStoreWrite(FULLMARK_IGNORE_COUNT, JSON.stringify({ count: num }));
}
async function myIonMetricGetFullMarkIgnore() {
let result = JSON.parse(await myIonStoreRead(FULLMARK_IGNORE_COUNT, { count: 0 }));
return result;
}
return (
<FullmarkCountContext.Provider
value={{
Helloworld,
myIonMetricGetFullMarkCount,
myIonMetricResetFullMarkCount,
myIonMetricIncFullMarkCount,
//
myIonMetricSetFullMarkCount,
myIonMetricSetFullMarkIgnore,
myIonMetricGetFullMarkIgnore,
}}
>
{/* */}
{children}
</FullmarkCountContext.Provider>
);
};
export const useFullmarkCount = (): FullmarkCountContextProps => {
const context = useContext(FullmarkCountContext);
if (!context) {
throw new Error('useMyContext must be used within a MyProvider');
}
return context;
};
interface FullmarkCountContextProps {
Helloworld: () => void;
//
// FullMark
myIonMetricGetFullMarkCount: () => Promise<{ count: number }>;
myIonMetricResetFullMarkCount: () => Promise<void>;
myIonMetricIncFullMarkCount: () => Promise<void>;
//
myIonMetricSetFullMarkCount: (num: number) => Promise<void>;
myIonMetricSetFullMarkIgnore: (num: number) => Promise<void>;
myIonMetricGetFullMarkIgnore: () => Promise<{ count: number }>;
}

View File

@@ -0,0 +1,5 @@
function Helloworld() {
console.log('helloworld');
}
export { Helloworld };

View File

@@ -0,0 +1,88 @@
import React, { createContext, ReactNode, useContext } from 'react';
import { useMyIonMetric } from '.';
import { LISTENING_PRACTICE_TIME_SPENT } from '../../constants';
const ListenPracticeTimeSpent = createContext<ListenPracticeTimeSpentProps | undefined>(undefined);
export const ListeningPracticeTimeSpentProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
// TODO create namespace for LISTENING_PRACTICE_TIME_SPENT ignore
const { myIonStoreRead, myIonStoreWrite } = useMyIonMetric();
function Helloworld() {
console.log('helloworld ListeningPracticeTimeSpentProvider');
}
async function myIonMetricGetListeningPracticeTimeSpent() {
let result = JSON.parse(await myIonStoreRead(LISTENING_PRACTICE_TIME_SPENT, { time_spent_s: 0 }));
return result;
}
async function myIonMetricResetListeningPracticeTimeSpent() {
await myIonStoreWrite(LISTENING_PRACTICE_TIME_SPENT, JSON.stringify({ time_spent_s: 0 }));
}
async function myIonMetricIncListeningPracticeTimeSpent(time_spent_s: number) {
let result = await myIonMetricGetListeningPracticeTimeSpent();
await myIonStoreWrite(
LISTENING_PRACTICE_TIME_SPENT,
JSON.stringify({ time_spent_s: result.time_spent_s + time_spent_s }),
);
}
async function myIonMetricSetListeningPracticeProgress(num: number) {
await myIonStoreWrite(
//
LISTENING_PRACTICE_TIME_SPENT,
JSON.stringify({ time_spent_s: num }),
);
}
async function myIonMetricGetListeningPracticeProgressIgnore() {
let result = JSON.parse(await myIonStoreRead(LISTENING_PRACTICE_TIME_SPENT + '_ignore', { time_spent_s: 0 }));
return result;
}
async function myIonMetricSetListeningPracticeProgressIgnore(time_spent_s: number) {
await myIonStoreWrite(LISTENING_PRACTICE_TIME_SPENT + '_ignore', JSON.stringify({ time_spent_s: time_spent_s }));
}
return (
<ListenPracticeTimeSpent.Provider
value={{
Helloworld,
myIonMetricGetListeningPracticeTimeSpent,
myIonMetricIncListeningPracticeTimeSpent,
myIonMetricResetListeningPracticeTimeSpent,
//
myIonMetricSetListeningPracticeProgress,
myIonMetricGetListeningPracticeProgressIgnore,
myIonMetricSetListeningPracticeProgressIgnore,
}}
>
{/* */}
{children}
</ListenPracticeTimeSpent.Provider>
);
};
export const useListeningPracticeTimeSpent = (): ListenPracticeTimeSpentProps => {
const context = useContext(ListenPracticeTimeSpent);
if (!context) {
throw new Error('useListenPracticeTimeSpent must be used within a MyProvider');
}
return context;
};
interface ListenPracticeTimeSpentProps {
Helloworld: () => void;
//
// ListeningPractice
myIonMetricGetListeningPracticeTimeSpent: () => Promise<{ time_spent_s: number }>;
myIonMetricIncListeningPracticeTimeSpent: (time_spent_s: number) => Promise<void>;
myIonMetricResetListeningPracticeTimeSpent: () => Promise<void>;
//
myIonMetricSetListeningPracticeProgress: (time_spent_s: number) => Promise<void>;
myIonMetricGetListeningPracticeProgressIgnore: () => Promise<{ time_spent_s: number }>;
myIonMetricSetListeningPracticeProgressIgnore: (time_spent_s: number) => Promise<void>;
}

View File

@@ -0,0 +1,79 @@
import React, { createContext, ReactNode, useContext } from 'react';
import { useMyIonMetric } from '.';
import { MATCHING_FRENZY_CORRECT_COUNT } from '../../constants';
const MatchingFrenzyCorrectCountContext = createContext<MatchingFrenzyCorrectCountContextProps | undefined>(undefined);
export const MatchingFrenzyCorrectCountProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const { myIonStoreRead, myIonStoreWrite } = useMyIonMetric();
function Helloworld() {
console.log('helloworld MatchingFrenzyCorrectCountProvider');
}
async function myIonMetricGetMatchingFrenzyCorrectCount() {
let result = JSON.parse(await myIonStoreRead(MATCHING_FRENZY_CORRECT_COUNT, { count: 0 }));
return result;
}
async function myIonMetricResetMatchingFrenzyCorrectCount() {
await myIonStoreWrite(MATCHING_FRENZY_CORRECT_COUNT, JSON.stringify({ count: 0 }));
}
async function myIonMetricIncMatchingFrenzyCorrectCount() {
let result = await myIonMetricGetMatchingFrenzyCorrectCount();
await myIonStoreWrite(MATCHING_FRENZY_CORRECT_COUNT, JSON.stringify({ count: result.count + 1 }));
}
async function myIonMetricSetMatchingFrenzyCorrectCount(count: number) {
await myIonStoreWrite(MATCHING_FRENZY_CORRECT_COUNT, JSON.stringify({ count: count }));
}
async function myIonMetricGetMatchingFrenzyCorrectCountIgnore() {
let result = JSON.parse(await myIonStoreRead(`${MATCHING_FRENZY_CORRECT_COUNT}_ignore`, { count: 0 }));
return result;
}
async function myIonMetricSetMatchingFrenzyCorrectCountIgnore(count: number) {
await myIonStoreWrite(`${MATCHING_FRENZY_CORRECT_COUNT}_ignore`, JSON.stringify({ count: count }));
}
return (
<MatchingFrenzyCorrectCountContext.Provider
value={{
Helloworld,
// MatchingFrenzyCorrect
myIonMetricGetMatchingFrenzyCorrectCount,
myIonMetricResetMatchingFrenzyCorrectCount,
myIonMetricIncMatchingFrenzyCorrectCount,
//
myIonMetricSetMatchingFrenzyCorrectCount,
myIonMetricGetMatchingFrenzyCorrectCountIgnore,
myIonMetricSetMatchingFrenzyCorrectCountIgnore,
}}
>
{children}
</MatchingFrenzyCorrectCountContext.Provider>
);
};
export const useMatchingFrenzyCorrectCount = (): MatchingFrenzyCorrectCountContextProps => {
const context = useContext(MatchingFrenzyCorrectCountContext);
if (!context) {
throw new Error('useMatchingFrenzyCorrectCountContext must be used within a MyProvider');
}
return context;
};
interface MatchingFrenzyCorrectCountContextProps {
Helloworld: () => void;
// MatchingFrenzyCorrect
myIonMetricGetMatchingFrenzyCorrectCount: () => Promise<{ count: number }>;
myIonMetricResetMatchingFrenzyCorrectCount: () => Promise<void>;
myIonMetricIncMatchingFrenzyCorrectCount: () => Promise<void>;
//
myIonMetricSetMatchingFrenzyCorrectCount: (count: number) => Promise<void>;
myIonMetricGetMatchingFrenzyCorrectCountIgnore: () => Promise<{ count: number }>;
myIonMetricSetMatchingFrenzyCorrectCountIgnore: (count: number) => Promise<void>;
}

View File

@@ -0,0 +1,75 @@
import { Drivers, Storage } from '@ionic/storage';
import React, { createContext, ReactNode, useContext, useEffect } from 'react';
import { AppOnRecorderProvider } from '../AppOnRecorder';
import { AppUseTimeProvider } from './AppUseTime';
import { ConnectivesRevisionCorrectCountProvider } from './ConnectivesRevisionCorrectCount';
import { FullmarkCountProvider } from './FullmarkCount';
import { Helloworld } from './Helloworld';
import { ListeningPracticeTimeSpentProvider } from './ListeningPracticeTimeSpent';
import { MatchingFrenzyCorrectCountProvider } from './MatchingFrenzyCorrectCount';
const metric_store = new Storage({
name: 'app_metrics',
driverOrder: [Drivers.IndexedDB, Drivers.LocalStorage],
});
const MyContext = createContext<MyContextProps | undefined>(undefined);
export const MyIonMetricProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
async function myIonStoreRead(key: string, not_found_output: any = {}) {
const output = (await metric_store.get(key)) || JSON.stringify(not_found_output);
return output;
}
async function myIonStoreWrite(key: string, value: string) {
await metric_store.set(key, value);
}
useEffect(() => {
(async () => {
await metric_store.create();
})();
}, []);
return (
<MyContext.Provider
value={{
myIonStoreRead,
myIonStoreWrite,
//
Helloworld,
}}
>
<AppUseTimeProvider>
<AppOnRecorderProvider />
<FullmarkCountProvider>
<ListeningPracticeTimeSpentProvider>
<MatchingFrenzyCorrectCountProvider>
<ConnectivesRevisionCorrectCountProvider>
{/* */}
{children}
</ConnectivesRevisionCorrectCountProvider>
</MatchingFrenzyCorrectCountProvider>
</ListeningPracticeTimeSpentProvider>
</FullmarkCountProvider>
</AppUseTimeProvider>
</MyContext.Provider>
);
};
export const useMyIonMetric = (): MyContextProps => {
const context = useContext(MyContext);
if (!context) {
throw new Error('useMyContext must be used within a MyProvider');
}
return context;
};
interface MyContextProps {
myIonStoreRead: (key: string, not_found_output: any) => Promise<any>;
myIonStoreWrite: (key: string, value: string) => Promise<void>;
//
//
Helloworld: () => void;
}

View File

@@ -0,0 +1,156 @@
import React, { createContext, ReactNode, useContext, useState } from 'react';
import { MATCH_FRENZY_SCOREBOARD_KEY } from '../constants';
import IListeningPracticeQuestion from '../interfaces/IListeningPracticeQuestion';
import { ConnectiveRevisionAllResult } from './ConnectiveRevisionRanking';
import { MatchingFrenzyResult, MatchingFrezyRanking } from './MatchingFrezyRanking';
import { useMyIonStore } from './MyIonStore';
const MyIonQuizContext = createContext<MyContextProps | undefined>(undefined);
export const MyIonQuizProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [my_context, setMyContext] = useState<string>('initial value');
const { myIonStoreRead, myIonStoreWrite } = useMyIonStore();
function Helloworld() {
listening_practice_correction_list;
}
const [listening_practice_result, setListeningPracticeResult] = useState<number>(0);
const [listening_practice_current_test, setListeningPracticeCurrentTest] = useState<number>(0);
const [listening_practice_correction_list, setListeningPracticeCorrectionList] = useState<any[] | []>([]);
//
function appendToListeningPracticeCorrectionList(question: IListeningPracticeQuestion) {
setListeningPracticeCorrectionList([...listening_practice_correction_list, question]);
}
//
function resetListeningPracticeCorrectionList() {
setListeningPracticeCorrectionList([]);
}
//
const [matching_frenzy_result, setMatchingFrenzyResult] = useState<number>(0);
const [matching_frenzy_current_test, setMatchingFrenzyCurrentTest] = useState<number>(0);
//
const getCategoryKey = (category: string) => `${MATCH_FRENZY_SCOREBOARD_KEY}/${category}`;
//
async function loadMatchingFrenzyScoreBoard(cat_name: string): Promise<MatchingFrezyRanking> {
let category_key = getCategoryKey(cat_name);
let current_result = JSON.parse(await myIonStoreRead(category_key));
if (!current_result || JSON.stringify(current_result) == '{}') {
current_result = { ranking: [] };
}
return current_result;
}
async function saveMatchingFrenzyResultToScoreBoard(cat_name: string, result: MatchingFrenzyResult) {
let category_key = getCategoryKey(cat_name);
let current_result: MatchingFrezyRanking = await loadMatchingFrenzyScoreBoard(cat_name);
current_result['ranking'] = [...current_result['ranking'], result];
current_result['ranking'].sort((a: MatchingFrenzyResult, b: MatchingFrenzyResult) => b.result - a.result).splice(3);
myIonStoreWrite(category_key, JSON.stringify(current_result));
}
//
const [connective_revision_progress, setConnectiveRevisionProgress] = useState<number>(0);
const [connective_revision_current_test, setConnectiveRevisionCurrentTest] = useState<number>(0);
//
const CONNECT_REVISION_SCOREBOARD_KEY = 'connective_revision_scoreboard';
async function loadConnectiveRevisionScoreBoard(): Promise<ConnectiveRevisionAllResult> {
let current_result = JSON.parse(await myIonStoreRead(CONNECT_REVISION_SCOREBOARD_KEY));
if (!current_result || JSON.stringify(current_result) == '{}') {
current_result = {};
}
return current_result;
}
const [connective_revision_score, setConnectiveRevisionScore] = useState<number>(0);
async function saveConnectiveRevisionResultToScoreBoard(quiz_index: string, progress: number) {
let current_result: ConnectiveRevisionAllResult = await loadConnectiveRevisionScoreBoard();
current_result = { ...current_result, [quiz_index]: progress };
myIonStoreWrite(CONNECT_REVISION_SCOREBOARD_KEY, JSON.stringify(current_result));
}
return (
<MyIonQuizContext.Provider
value={{
my_context,
setMyContext,
//
listening_practice_current_test,
setListeningPracticeCurrentTest,
//
listening_practice_result,
setListeningPracticeResult,
//
listening_practice_correction_list,
setListeningPracticeCorrectionList,
appendToListeningPracticeCorrectionList,
resetListeningPracticeCorrectionList,
//
matching_frenzy_current_test,
setMatchingFrenzyCurrentTest,
loadMatchingFrenzyScoreBoard,
saveMatchingFrenzyResultToScoreBoard,
matching_frenzy_result,
setMatchingFrenzyResult,
//
connective_revision_progress,
setConnectiveRevisionProgress,
//
connective_revision_score,
setConnectiveRevisionScore,
connective_revision_current_test,
setConnectiveRevisionCurrentTest,
loadConnectiveRevisionScoreBoard,
saveConnectiveRevisionResultToScoreBoard,
//
Helloworld,
}}
>
{children}
</MyIonQuizContext.Provider>
);
};
export const useMyIonQuizContext = (): MyContextProps => {
const context = useContext(MyIonQuizContext);
if (!context) {
throw new Error('useMyContext must be used within a MyProvider');
}
return context;
};
interface MyContextProps {
my_context: string;
setMyContext: React.Dispatch<React.SetStateAction<string>>;
//
//
listening_practice_result: number;
setListeningPracticeResult: React.Dispatch<React.SetStateAction<number>>;
//
listening_practice_current_test: number;
setListeningPracticeCurrentTest: React.Dispatch<React.SetStateAction<number>>;
//
listening_practice_correction_list: IListeningPracticeQuestion[];
setListeningPracticeCorrectionList: React.Dispatch<React.SetStateAction<IListeningPracticeQuestion[]>>;
appendToListeningPracticeCorrectionList: (question: IListeningPracticeQuestion) => void;
resetListeningPracticeCorrectionList: () => void;
//
matching_frenzy_result: number;
setMatchingFrenzyResult: React.Dispatch<React.SetStateAction<number>>;
matching_frenzy_current_test: number;
setMatchingFrenzyCurrentTest: React.Dispatch<React.SetStateAction<number>>;
loadMatchingFrenzyScoreBoard: (cat_name: string) => Promise<MatchingFrezyRanking>;
saveMatchingFrenzyResultToScoreBoard: (cat_name: string, result: MatchingFrenzyResult) => Promise<void>;
//
connective_revision_progress: number;
setConnectiveRevisionProgress: React.Dispatch<React.SetStateAction<number>>;
//
connective_revision_score: number;
setConnectiveRevisionScore: React.Dispatch<React.SetStateAction<number>>;
connective_revision_current_test: number;
setConnectiveRevisionCurrentTest: React.Dispatch<React.SetStateAction<number>>;
loadConnectiveRevisionScoreBoard: () => Promise<ConnectiveRevisionAllResult>;
saveConnectiveRevisionResultToScoreBoard: (quiz_index: string, progress: number) => Promise<void>;
//
Helloworld: () => void;
}

View File

@@ -0,0 +1,113 @@
import { Drivers, Storage } from '@ionic/storage';
import React, { createContext, ReactNode, useContext, useEffect, useState } from 'react';
import ILesson from '../interfaces/ILesson';
import { listLessonCategories } from '../public_data/listLessonCategories';
const user_store = new Storage({
name: '__mydb',
driverOrder: [Drivers.IndexedDB, Drivers.LocalStorage],
});
const MyContext = createContext<MyContextProps | undefined>(undefined);
export const MyIonStoreProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [db, setDB] = useState<[]>([]);
const [lesson_content, setLessonContent] = useState<ILesson[] | []>([]);
const [my_context, setMyContext] = useState<string>('initial value');
const [test_first, setTestFirst] = useState<IFirst | undefined>(undefined);
const [test_second, setTestSecond] = useState<ISecond | undefined>(undefined);
const [test_third, setTestThird] = useState<IThird | undefined>(undefined);
async function myIonStoreRead(key: string, not_found_output: string = '{}'): Promise<string> {
const output = (await user_store.get(key)) || not_found_output;
return output;
}
async function myIonStoreWrite(key: string, value: string): Promise<void> {
await user_store.set(key, value);
}
useEffect(() => {
(async () => {
let cats = await listLessonCategories();
setLessonContent(cats);
})();
(async () => {
await user_store.create();
})();
}, []);
return (
<MyContext.Provider
value={{
db,
setDB,
lesson_contents: lesson_content,
setLessonContent,
user_store,
//
myIonStoreRead,
myIonStoreWrite,
//
my_context,
setMyContext,
test_first,
setTestFirst,
test_second,
setTestSecond,
test_third,
setTestThird,
}}
>
{children}
</MyContext.Provider>
);
};
export const useMyIonStore = (): MyContextProps => {
const context = useContext(MyContext);
if (!context) {
throw new Error('useMyContext must be used within a MyProvider');
}
return context;
};
interface MyContextProps {
//
db: [];
setDB: React.Dispatch<React.SetStateAction<[]>>;
lesson_contents: ILesson[] | [];
setLessonContent: React.Dispatch<React.SetStateAction<ILesson[] | []>>;
user_store: Storage;
//
myIonStoreRead: (key: string, not_found_output?: any) => Promise<string>;
myIonStoreWrite: (key: string, value: string) => Promise<void>;
//
my_context: string;
setMyContext: React.Dispatch<React.SetStateAction<string>>;
test_first: IFirst | undefined;
setTestFirst: React.Dispatch<React.SetStateAction<IFirst | undefined>>;
test_second: ISecond | undefined;
setTestSecond: React.Dispatch<React.SetStateAction<ISecond | undefined>>;
test_third: IThird | undefined;
setTestThird: React.Dispatch<React.SetStateAction<IThird | undefined>>;
}
interface IFirst {
test_s: string;
test_i: number;
}
interface ISecond {
test_s: string;
test_i: number;
content: IFirst[] | [];
}
interface IThird {
test_s: string;
test_i: number;
content: ISecond[] | [];
}

View File

@@ -0,0 +1,26 @@
import { AppStateProvider } from './AppState';
import { MyIonFavoriteProvider } from './MyIonFavorite';
import { MyIonMetricProvider } from './MyIonMetric';
import { MyIonQuizProvider } from './MyIonQuiz';
import { MyIonStoreProvider } from './MyIonStore';
const ContextMeta = ({ children }: { children: React.ReactNode }) => {
return (
<>
<AppStateProvider>
<MyIonStoreProvider>
<MyIonFavoriteProvider>
<MyIonQuizProvider>
<MyIonMetricProvider>
{/* */}
{children}
</MyIonMetricProvider>
</MyIonQuizProvider>
</MyIonFavoriteProvider>
</MyIonStoreProvider>
</AppStateProvider>
</>
);
};
export default ContextMeta;