init commit,
This commit is contained in:
42
002_source/ionic_mobile/src/contexts/AppOnRecorder.tsx
Normal file
42
002_source/ionic_mobile/src/contexts/AppOnRecorder.tsx
Normal 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>>;
|
||||
}
|
145
002_source/ionic_mobile/src/contexts/AppState.tsx
Normal file
145
002_source/ionic_mobile/src/contexts/AppState.tsx
Normal 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;
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
export interface ConnectiveRevisionAllResult {
|
||||
[quiz_name: string]: number;
|
||||
}
|
||||
|
||||
export interface ConnectiveRevisionResult {
|
||||
date: string;
|
||||
progress: number;
|
||||
}
|
91
002_source/ionic_mobile/src/contexts/Haptics.tsx
Normal file
91
002_source/ionic_mobile/src/contexts/Haptics.tsx
Normal 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[] | [];
|
||||
}
|
66
002_source/ionic_mobile/src/contexts/Helloworld.tsx
Normal file
66
002_source/ionic_mobile/src/contexts/Helloworld.tsx
Normal 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[] | [];
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
export interface MatchingFrezyRanking {
|
||||
ranking: MatchingFrenzyResult[] | [];
|
||||
}
|
||||
export interface MatchingFrenzyResult {
|
||||
date: string;
|
||||
result: number;
|
||||
}
|
138
002_source/ionic_mobile/src/contexts/MyIonFavorite.tsx
Normal file
138
002_source/ionic_mobile/src/contexts/MyIonFavorite.tsx
Normal 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>;
|
||||
}
|
@@ -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>;
|
||||
}
|
@@ -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>;
|
||||
}
|
@@ -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 }>;
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
function Helloworld() {
|
||||
console.log('helloworld');
|
||||
}
|
||||
|
||||
export { Helloworld };
|
@@ -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>;
|
||||
}
|
@@ -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>;
|
||||
}
|
75
002_source/ionic_mobile/src/contexts/MyIonMetric/index.tsx
Normal file
75
002_source/ionic_mobile/src/contexts/MyIonMetric/index.tsx
Normal 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;
|
||||
}
|
156
002_source/ionic_mobile/src/contexts/MyIonQuiz.tsx
Normal file
156
002_source/ionic_mobile/src/contexts/MyIonQuiz.tsx
Normal 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;
|
||||
}
|
113
002_source/ionic_mobile/src/contexts/MyIonStore.tsx
Normal file
113
002_source/ionic_mobile/src/contexts/MyIonStore.tsx
Normal 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[] | [];
|
||||
}
|
26
002_source/ionic_mobile/src/contexts/index.tsx
Normal file
26
002_source/ionic_mobile/src/contexts/index.tsx
Normal 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;
|
Reference in New Issue
Block a user