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,199 @@
import { DEBUG, DEBUG_LINK, LESSON_LINK, QUIZ_MAIN_MENU_LINK, RECORD_LINK, SETTING_LINK } from './constants';
/* Core CSS required for Ionic components to work properly */
import '@ionic/react/css/core.css';
/* Basic CSS for apps built with Ionic */
import '@ionic/react/css/normalize.css';
import '@ionic/react/css/structure.css';
/* Optional CSS utils that can be commented out */
import '@ionic/react/css/padding.css';
import '@ionic/react/css/float-elements.css';
import '@ionic/react/css/text-alignment.css';
import '@ionic/react/css/text-transformation.css';
import '@ionic/react/css/flex-utils.css';
import '@ionic/react/css/typography.css';
import '@ionic/react/css/display.css';
/**
* Ionic Dark Mode
* -----------------------------------------------------
* For more info, please see:
* https://ionicframework.com/docs/theming/dark-mode
*/
/* import '@ionic/react/css/palettes/dark.always.css'; */
/* import '@ionic/react/css/palettes/dark.class.css'; */
// import '@ionic/react/css/palettes/dark.system.css';
/* Theme variables */
import './theme/variables.css';
import './debug.css';
import './style.css';
import './google_fonts.css';
import { App as CapacitorApp } from '@capacitor/app';
import {
IonApp,
IonIcon,
IonLabel,
IonRouterOutlet,
IonTabBar,
IonTabButton,
IonTabs,
setupIonicReact,
useIonRouter,
} from '@ionic/react';
import { IonReactRouter } from '@ionic/react-router';
import { bookOutline, bug, heartOutline, newspaperOutline, settingsOutline } from 'ionicons/icons';
import { useTranslation } from 'react-i18next';
import ConfirmUserExit from './components/ConfirmUserExit';
import { DisableUserTap } from './components/DisableUserTap';
import ContextMeta from './contexts';
import { useAppStateContext } from './contexts/AppState';
import { useMyIonQuizContext } from './contexts/MyIonQuiz';
import { RouteConfig } from './RouteConfig';
let active_color = 'tomato';
let inactive_color = 'gray';
CapacitorApp.addListener('appStateChange', ({ isActive }) => {
console.log('App state changed. Is active?', isActive);
});
CapacitorApp.addListener('backButton', ({ canGoBack }) => {
if (!canGoBack) {
// CapacitorApp.minimizeApp();
// alert('blablabla');
}
});
setupIonicReact();
const TabButtons: React.FC = () => {
let router = useIonRouter();
const { t } = useTranslation();
let {
url_push_after_user_confirm,
setURLPushAfterUserConfirm,
setShowConfirmUserExit,
listening_practice_in_progress,
setListeningPracticeInProgress,
matching_frenzy_in_progress,
connective_revision_in_progress,
tab_active,
setTabActive,
} = useAppStateContext();
const { resetListeningPracticeCorrectionList } = useMyIonQuizContext();
function goSwitchPage(url: string) {
if (listening_practice_in_progress || matching_frenzy_in_progress || connective_revision_in_progress) {
if (url != QUIZ_MAIN_MENU_LINK) {
setURLPushAfterUserConfirm(url);
setShowConfirmUserExit(true);
}
} else {
setTabActive(url);
router.push(url, 'none', 'replace');
}
}
return (
<>
<IonTabBar slot="bottom">
<IonTabButton
tab="lesson"
onClick={() => goSwitchPage(LESSON_LINK)}
style={{ color: tab_active == LESSON_LINK ? active_color : inactive_color }}
>
<IonIcon aria-hidden="true" icon={bookOutline} size="large" />
</IonTabButton>
{/* */}
<IonTabButton
tab="quiz"
onClick={() => goSwitchPage(QUIZ_MAIN_MENU_LINK)}
style={{ color: tab_active == QUIZ_MAIN_MENU_LINK ? active_color : inactive_color }}
>
<IonIcon aria-hidden="true" icon={newspaperOutline} size="large" />
</IonTabButton>
<IonTabButton
tab="quiz"
onClick={() => goSwitchPage(QUIZ_MAIN_MENU_LINK)}
style={{ color: tab_active == QUIZ_MAIN_MENU_LINK ? active_color : inactive_color }}
></IonTabButton>
{/* */}
<IonTabButton
tab="record"
onClick={() => goSwitchPage(RECORD_LINK)}
style={{ color: tab_active == RECORD_LINK ? active_color : inactive_color }}
>
<IonIcon aria-hidden="true" icon={heartOutline} size="large" />
</IonTabButton>
{/* */}
{/* 003_remove_setting_screen, hide setting on bottom tabs */}
<IonTabButton
tab="setting"
onClick={() => goSwitchPage(SETTING_LINK)}
style={{ color: tab_active == SETTING_LINK ? active_color : inactive_color }}
>
<IonIcon aria-hidden="true" icon={settingsOutline} size="large" />
</IonTabButton>
{DEBUG ? (
<IonTabButton
tab="debug"
onClick={() => goSwitchPage(DEBUG_LINK)}
// href={DEBUG_LINK}
>
<IonIcon aria-hidden="true" icon={bug} color="danger" />
<IonLabel color="danger">Debug</IonLabel>
</IonTabButton>
) : (
<></>
)}
</IonTabBar>
</>
);
};
const App: React.FC = () => {
return (
<IonApp>
<ContextMeta>
<DisableUserTap>
<IonReactRouter>
<IonTabs>
<IonRouterOutlet>
<RouteConfig />
</IonRouterOutlet>
<TabButtons />
</IonTabs>
<div
style={{
zIndex: 9999,
backgroundColor: 'tomato',
position: 'fixed',
bottom: '1rem',
height: '4rem',
width: '4rem',
left: 'calc( (100vw - 4rem ) / 2 )',
borderRadius: '50%',
//
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
}}
>
<div style={{ fontWeight: 'bold', fontSize: '2rem', color: 'white' }}>AI</div>
</div>
{/* */}
<ConfirmUserExit />
{/* */}
</IonReactRouter>
</DisableUserTap>
</ContextMeta>
</IonApp>
);
};
export default App;