@magmamath/students-features 1.8.4 → 1.8.6-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commonjs/features/chatbot/components/ChatInput/FreeText/ChatTextInput.js.map +1 -1
- package/dist/commonjs/features/profile/Profile.js +90 -0
- package/dist/commonjs/features/profile/Profile.js.map +1 -0
- package/dist/commonjs/features/profile/components/actions/ProfileActions.js +70 -0
- package/dist/commonjs/features/profile/components/actions/ProfileActions.js.map +1 -0
- package/dist/commonjs/features/profile/components/cards/ProfileCard.js +57 -0
- package/dist/commonjs/features/profile/components/cards/ProfileCard.js.map +1 -0
- package/dist/commonjs/features/profile/components/info/AccountInfoCard.js +91 -0
- package/dist/commonjs/features/profile/components/info/AccountInfoCard.js.map +1 -0
- package/dist/commonjs/features/profile/components/modals/JoinClassModal.js +190 -0
- package/dist/commonjs/features/profile/components/modals/JoinClassModal.js.map +1 -0
- package/dist/commonjs/features/profile/components/modals/LogoutConfirmModal.js +61 -0
- package/dist/commonjs/features/profile/components/modals/LogoutConfirmModal.js.map +1 -0
- package/dist/commonjs/features/profile/components/modals/TranslationLanguageModal.js +128 -0
- package/dist/commonjs/features/profile/components/modals/TranslationLanguageModal.js.map +1 -0
- package/dist/commonjs/features/profile/components/settings/LanguageSettingsCard.js +22 -0
- package/dist/commonjs/features/profile/components/settings/LanguageSettingsCard.js.map +1 -0
- package/dist/commonjs/features/profile/components/settings/PreferencesCard.js +69 -0
- package/dist/commonjs/features/profile/components/settings/PreferencesCard.js.map +1 -0
- package/dist/commonjs/features/profile/components/settings/SettingRow.js +48 -0
- package/dist/commonjs/features/profile/components/settings/SettingRow.js.map +1 -0
- package/dist/commonjs/features/profile/components/settings/TextSettingsCard.js +77 -0
- package/dist/commonjs/features/profile/components/settings/TextSettingsCard.js.map +1 -0
- package/dist/commonjs/features/profile/components/settings/TextSizeSlider.js +119 -0
- package/dist/commonjs/features/profile/components/settings/TextSizeSlider.js.map +1 -0
- package/dist/commonjs/features/profile/components/settings/TextToSpeechRow.js +37 -0
- package/dist/commonjs/features/profile/components/settings/TextToSpeechRow.js.map +1 -0
- package/dist/commonjs/features/profile/components/settings/TranslationLanguageRow.js +62 -0
- package/dist/commonjs/features/profile/components/settings/TranslationLanguageRow.js.map +1 -0
- package/dist/commonjs/features/profile/context/ProfileContext.js +18 -0
- package/dist/commonjs/features/profile/context/ProfileContext.js.map +1 -0
- package/dist/commonjs/features/profile/index.js +80 -0
- package/dist/commonjs/features/profile/index.js.map +1 -0
- package/dist/commonjs/features/profile/model/ProfileApi.js +15 -0
- package/dist/commonjs/features/profile/model/ProfileApi.js.map +1 -0
- package/dist/commonjs/features/profile/model/ProfileJoinClassModel.js +60 -0
- package/dist/commonjs/features/profile/model/ProfileJoinClassModel.js.map +1 -0
- package/dist/commonjs/features/profile/model/ProfileLanguageModel.js +30 -0
- package/dist/commonjs/features/profile/model/ProfileLanguageModel.js.map +1 -0
- package/dist/commonjs/features/profile/model/ProfileModel.js +53 -0
- package/dist/commonjs/features/profile/model/ProfileModel.js.map +1 -0
- package/dist/commonjs/features/profile/model/profileModal.types.js +6 -0
- package/dist/commonjs/features/profile/model/profileModal.types.js.map +1 -0
- package/dist/commonjs/features/profile/shared/JoinClassError.js +16 -0
- package/dist/commonjs/features/profile/shared/JoinClassError.js.map +1 -0
- package/dist/commonjs/features/profile/shared/profile.constants.js +29 -0
- package/dist/commonjs/features/profile/shared/profile.constants.js.map +1 -0
- package/dist/commonjs/features/profile/shared/profile.helpers.js +40 -0
- package/dist/commonjs/features/profile/shared/profile.helpers.js.map +1 -0
- package/dist/commonjs/features/profile/shared/profile.types.js +6 -0
- package/dist/commonjs/features/profile/shared/profile.types.js.map +1 -0
- package/dist/commonjs/index.js +12 -0
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/shared/hooks/useKeyboardOffset.js +54 -0
- package/dist/commonjs/shared/hooks/useKeyboardOffset.js.map +1 -0
- package/dist/module/features/chatbot/components/ChatInput/FreeText/ChatTextInput.js.map +1 -1
- package/dist/module/features/profile/Profile.js +84 -0
- package/dist/module/features/profile/Profile.js.map +1 -0
- package/dist/module/features/profile/components/actions/ProfileActions.js +64 -0
- package/dist/module/features/profile/components/actions/ProfileActions.js.map +1 -0
- package/dist/module/features/profile/components/cards/ProfileCard.js +51 -0
- package/dist/module/features/profile/components/cards/ProfileCard.js.map +1 -0
- package/dist/module/features/profile/components/info/AccountInfoCard.js +85 -0
- package/dist/module/features/profile/components/info/AccountInfoCard.js.map +1 -0
- package/dist/module/features/profile/components/modals/JoinClassModal.js +183 -0
- package/dist/module/features/profile/components/modals/JoinClassModal.js.map +1 -0
- package/dist/module/features/profile/components/modals/LogoutConfirmModal.js +55 -0
- package/dist/module/features/profile/components/modals/LogoutConfirmModal.js.map +1 -0
- package/dist/module/features/profile/components/modals/TranslationLanguageModal.js +122 -0
- package/dist/module/features/profile/components/modals/TranslationLanguageModal.js.map +1 -0
- package/dist/module/features/profile/components/settings/LanguageSettingsCard.js +16 -0
- package/dist/module/features/profile/components/settings/LanguageSettingsCard.js.map +1 -0
- package/dist/module/features/profile/components/settings/PreferencesCard.js +63 -0
- package/dist/module/features/profile/components/settings/PreferencesCard.js.map +1 -0
- package/dist/module/features/profile/components/settings/SettingRow.js +42 -0
- package/dist/module/features/profile/components/settings/SettingRow.js.map +1 -0
- package/dist/module/features/profile/components/settings/TextSettingsCard.js +71 -0
- package/dist/module/features/profile/components/settings/TextSettingsCard.js.map +1 -0
- package/dist/module/features/profile/components/settings/TextSizeSlider.js +112 -0
- package/dist/module/features/profile/components/settings/TextSizeSlider.js.map +1 -0
- package/dist/module/features/profile/components/settings/TextToSpeechRow.js +31 -0
- package/dist/module/features/profile/components/settings/TextToSpeechRow.js.map +1 -0
- package/dist/module/features/profile/components/settings/TranslationLanguageRow.js +56 -0
- package/dist/module/features/profile/components/settings/TranslationLanguageRow.js.map +1 -0
- package/dist/module/features/profile/context/ProfileContext.js +13 -0
- package/dist/module/features/profile/context/ProfileContext.js.map +1 -0
- package/dist/module/features/profile/index.js +11 -0
- package/dist/module/features/profile/index.js.map +1 -0
- package/dist/module/features/profile/model/ProfileApi.js +10 -0
- package/dist/module/features/profile/model/ProfileApi.js.map +1 -0
- package/dist/module/features/profile/model/ProfileJoinClassModel.js +55 -0
- package/dist/module/features/profile/model/ProfileJoinClassModel.js.map +1 -0
- package/dist/module/features/profile/model/ProfileLanguageModel.js +25 -0
- package/dist/module/features/profile/model/ProfileLanguageModel.js.map +1 -0
- package/dist/module/features/profile/model/ProfileModel.js +48 -0
- package/dist/module/features/profile/model/ProfileModel.js.map +1 -0
- package/dist/module/features/profile/model/profileModal.types.js +4 -0
- package/dist/module/features/profile/model/profileModal.types.js.map +1 -0
- package/dist/module/features/profile/shared/JoinClassError.js +11 -0
- package/dist/module/features/profile/shared/JoinClassError.js.map +1 -0
- package/dist/module/features/profile/shared/profile.constants.js +25 -0
- package/dist/module/features/profile/shared/profile.constants.js.map +1 -0
- package/dist/module/features/profile/shared/profile.helpers.js +32 -0
- package/dist/module/features/profile/shared/profile.helpers.js.map +1 -0
- package/dist/module/features/profile/shared/profile.types.js +4 -0
- package/dist/module/features/profile/shared/profile.types.js.map +1 -0
- package/dist/module/index.js +1 -0
- package/dist/module/index.js.map +1 -1
- package/dist/module/shared/hooks/useKeyboardOffset.js +49 -0
- package/dist/module/shared/hooks/useKeyboardOffset.js.map +1 -0
- package/dist/typescript/commonjs/features/chatbot/components/ChatInput/FreeText/ChatTextInput.d.ts.map +1 -1
- package/dist/typescript/commonjs/features/profile/Profile.d.ts +6 -0
- package/dist/typescript/commonjs/features/profile/Profile.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/__tests__/ProfileModel.test.d.ts +2 -0
- package/dist/typescript/commonjs/features/profile/__tests__/ProfileModel.test.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/__tests__/profile.helpers.test.d.ts +2 -0
- package/dist/typescript/commonjs/features/profile/__tests__/profile.helpers.test.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/components/actions/ProfileActions.d.ts +3 -0
- package/dist/typescript/commonjs/features/profile/components/actions/ProfileActions.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/components/cards/ProfileCard.d.ts +10 -0
- package/dist/typescript/commonjs/features/profile/components/cards/ProfileCard.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/components/info/AccountInfoCard.d.ts +3 -0
- package/dist/typescript/commonjs/features/profile/components/info/AccountInfoCard.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/components/modals/JoinClassModal.d.ts +4 -0
- package/dist/typescript/commonjs/features/profile/components/modals/JoinClassModal.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/components/modals/LogoutConfirmModal.d.ts +4 -0
- package/dist/typescript/commonjs/features/profile/components/modals/LogoutConfirmModal.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/components/modals/TranslationLanguageModal.d.ts +4 -0
- package/dist/typescript/commonjs/features/profile/components/modals/TranslationLanguageModal.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/components/settings/LanguageSettingsCard.d.ts +3 -0
- package/dist/typescript/commonjs/features/profile/components/settings/LanguageSettingsCard.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/components/settings/PreferencesCard.d.ts +3 -0
- package/dist/typescript/commonjs/features/profile/components/settings/PreferencesCard.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/components/settings/SettingRow.d.ts +11 -0
- package/dist/typescript/commonjs/features/profile/components/settings/SettingRow.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/components/settings/TextSettingsCard.d.ts +3 -0
- package/dist/typescript/commonjs/features/profile/components/settings/TextSettingsCard.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/components/settings/TextSizeSlider.d.ts +8 -0
- package/dist/typescript/commonjs/features/profile/components/settings/TextSizeSlider.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/components/settings/TextToSpeechRow.d.ts +3 -0
- package/dist/typescript/commonjs/features/profile/components/settings/TextToSpeechRow.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/components/settings/TranslationLanguageRow.d.ts +3 -0
- package/dist/typescript/commonjs/features/profile/components/settings/TranslationLanguageRow.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/context/ProfileContext.d.ts +13 -0
- package/dist/typescript/commonjs/features/profile/context/ProfileContext.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/index.d.ts +12 -0
- package/dist/typescript/commonjs/features/profile/index.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/model/ProfileApi.d.ts +11 -0
- package/dist/typescript/commonjs/features/profile/model/ProfileApi.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/model/ProfileJoinClassModel.d.ts +14 -0
- package/dist/typescript/commonjs/features/profile/model/ProfileJoinClassModel.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/model/ProfileLanguageModel.d.ts +13 -0
- package/dist/typescript/commonjs/features/profile/model/ProfileLanguageModel.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/model/ProfileModel.d.ts +26 -0
- package/dist/typescript/commonjs/features/profile/model/ProfileModel.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/model/profileModal.types.d.ts +14 -0
- package/dist/typescript/commonjs/features/profile/model/profileModal.types.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/shared/JoinClassError.d.ts +5 -0
- package/dist/typescript/commonjs/features/profile/shared/JoinClassError.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/shared/profile.constants.d.ts +20 -0
- package/dist/typescript/commonjs/features/profile/shared/profile.constants.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/shared/profile.helpers.d.ts +6 -0
- package/dist/typescript/commonjs/features/profile/shared/profile.helpers.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/profile/shared/profile.types.d.ts +27 -0
- package/dist/typescript/commonjs/features/profile/shared/profile.types.d.ts.map +1 -0
- package/dist/typescript/commonjs/index.d.ts +1 -0
- package/dist/typescript/commonjs/index.d.ts.map +1 -1
- package/dist/typescript/commonjs/shared/hooks/useKeyboardOffset.d.ts +11 -0
- package/dist/typescript/commonjs/shared/hooks/useKeyboardOffset.d.ts.map +1 -0
- package/dist/typescript/module/features/chatbot/components/ChatInput/FreeText/ChatTextInput.d.ts.map +1 -1
- package/dist/typescript/module/features/profile/Profile.d.ts +6 -0
- package/dist/typescript/module/features/profile/Profile.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/__tests__/ProfileModel.test.d.ts +2 -0
- package/dist/typescript/module/features/profile/__tests__/ProfileModel.test.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/__tests__/profile.helpers.test.d.ts +2 -0
- package/dist/typescript/module/features/profile/__tests__/profile.helpers.test.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/components/actions/ProfileActions.d.ts +3 -0
- package/dist/typescript/module/features/profile/components/actions/ProfileActions.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/components/cards/ProfileCard.d.ts +10 -0
- package/dist/typescript/module/features/profile/components/cards/ProfileCard.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/components/info/AccountInfoCard.d.ts +3 -0
- package/dist/typescript/module/features/profile/components/info/AccountInfoCard.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/components/modals/JoinClassModal.d.ts +4 -0
- package/dist/typescript/module/features/profile/components/modals/JoinClassModal.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/components/modals/LogoutConfirmModal.d.ts +4 -0
- package/dist/typescript/module/features/profile/components/modals/LogoutConfirmModal.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/components/modals/TranslationLanguageModal.d.ts +4 -0
- package/dist/typescript/module/features/profile/components/modals/TranslationLanguageModal.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/components/settings/LanguageSettingsCard.d.ts +3 -0
- package/dist/typescript/module/features/profile/components/settings/LanguageSettingsCard.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/components/settings/PreferencesCard.d.ts +3 -0
- package/dist/typescript/module/features/profile/components/settings/PreferencesCard.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/components/settings/SettingRow.d.ts +11 -0
- package/dist/typescript/module/features/profile/components/settings/SettingRow.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/components/settings/TextSettingsCard.d.ts +3 -0
- package/dist/typescript/module/features/profile/components/settings/TextSettingsCard.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/components/settings/TextSizeSlider.d.ts +8 -0
- package/dist/typescript/module/features/profile/components/settings/TextSizeSlider.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/components/settings/TextToSpeechRow.d.ts +3 -0
- package/dist/typescript/module/features/profile/components/settings/TextToSpeechRow.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/components/settings/TranslationLanguageRow.d.ts +3 -0
- package/dist/typescript/module/features/profile/components/settings/TranslationLanguageRow.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/context/ProfileContext.d.ts +13 -0
- package/dist/typescript/module/features/profile/context/ProfileContext.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/index.d.ts +12 -0
- package/dist/typescript/module/features/profile/index.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/model/ProfileApi.d.ts +11 -0
- package/dist/typescript/module/features/profile/model/ProfileApi.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/model/ProfileJoinClassModel.d.ts +14 -0
- package/dist/typescript/module/features/profile/model/ProfileJoinClassModel.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/model/ProfileLanguageModel.d.ts +13 -0
- package/dist/typescript/module/features/profile/model/ProfileLanguageModel.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/model/ProfileModel.d.ts +26 -0
- package/dist/typescript/module/features/profile/model/ProfileModel.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/model/profileModal.types.d.ts +14 -0
- package/dist/typescript/module/features/profile/model/profileModal.types.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/shared/JoinClassError.d.ts +5 -0
- package/dist/typescript/module/features/profile/shared/JoinClassError.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/shared/profile.constants.d.ts +20 -0
- package/dist/typescript/module/features/profile/shared/profile.constants.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/shared/profile.helpers.d.ts +6 -0
- package/dist/typescript/module/features/profile/shared/profile.helpers.d.ts.map +1 -0
- package/dist/typescript/module/features/profile/shared/profile.types.d.ts +27 -0
- package/dist/typescript/module/features/profile/shared/profile.types.d.ts.map +1 -0
- package/dist/typescript/module/index.d.ts +1 -0
- package/dist/typescript/module/index.d.ts.map +1 -1
- package/dist/typescript/module/shared/hooks/useKeyboardOffset.d.ts +11 -0
- package/dist/typescript/module/shared/hooks/useKeyboardOffset.d.ts.map +1 -0
- package/package.json +4 -2
- package/src/features/chatbot/components/ChatInput/FreeText/ChatTextInput.tsx +0 -1
- package/src/features/profile/Profile.tsx +83 -0
- package/src/features/profile/__tests__/ProfileModel.test.ts +99 -0
- package/src/features/profile/__tests__/profile.helpers.test.ts +57 -0
- package/src/features/profile/components/actions/ProfileActions.tsx +68 -0
- package/src/features/profile/components/cards/ProfileCard.tsx +53 -0
- package/src/features/profile/components/info/AccountInfoCard.tsx +74 -0
- package/src/features/profile/components/modals/JoinClassModal.tsx +180 -0
- package/src/features/profile/components/modals/LogoutConfirmModal.tsx +64 -0
- package/src/features/profile/components/modals/TranslationLanguageModal.tsx +126 -0
- package/src/features/profile/components/settings/LanguageSettingsCard.tsx +16 -0
- package/src/features/profile/components/settings/PreferencesCard.tsx +67 -0
- package/src/features/profile/components/settings/SettingRow.tsx +42 -0
- package/src/features/profile/components/settings/TextSettingsCard.tsx +64 -0
- package/src/features/profile/components/settings/TextSizeSlider.tsx +117 -0
- package/src/features/profile/components/settings/TextToSpeechRow.tsx +29 -0
- package/src/features/profile/components/settings/TranslationLanguageRow.tsx +60 -0
- package/src/features/profile/context/ProfileContext.tsx +24 -0
- package/src/features/profile/index.ts +11 -0
- package/src/features/profile/model/ProfileApi.ts +23 -0
- package/src/features/profile/model/ProfileJoinClassModel.ts +58 -0
- package/src/features/profile/model/ProfileLanguageModel.ts +26 -0
- package/src/features/profile/model/ProfileModel.ts +57 -0
- package/src/features/profile/model/profileModal.types.ts +16 -0
- package/src/features/profile/shared/JoinClassError.ts +7 -0
- package/src/features/profile/shared/profile.constants.ts +23 -0
- package/src/features/profile/shared/profile.helpers.ts +36 -0
- package/src/features/profile/shared/profile.types.ts +34 -0
- package/src/i18n/.generated/schema.json +9 -1
- package/src/index.ts +1 -0
- package/src/shared/hooks/useKeyboardOffset.ts +57 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { StyleSheet } from 'react-native'
|
|
3
|
+
import {
|
|
4
|
+
BaseModal,
|
|
5
|
+
Button,
|
|
6
|
+
ButtonColor,
|
|
7
|
+
ButtonSize,
|
|
8
|
+
ButtonVariant,
|
|
9
|
+
} from '@magmamath/react-native-ui'
|
|
10
|
+
|
|
11
|
+
import { useText } from '../../../../i18n/i18n'
|
|
12
|
+
import type { LogoutModalParams, ProfileModalProps } from '../../model/profileModal.types'
|
|
13
|
+
|
|
14
|
+
export const LogoutConfirmModal = ({
|
|
15
|
+
modal: { closeModal, params },
|
|
16
|
+
}: ProfileModalProps<LogoutModalParams>) => {
|
|
17
|
+
const t = useText()
|
|
18
|
+
|
|
19
|
+
const confirm = () => {
|
|
20
|
+
closeModal()
|
|
21
|
+
params.onConfirm()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<BaseModal
|
|
26
|
+
onClose={closeModal}
|
|
27
|
+
style={modalStyle}
|
|
28
|
+
header={t('profile.logOut')}
|
|
29
|
+
content={t('profile.logOutConfirmMessage')}
|
|
30
|
+
footer={
|
|
31
|
+
<>
|
|
32
|
+
<Button
|
|
33
|
+
variant={ButtonVariant.TERTIARY}
|
|
34
|
+
size={ButtonSize.LARGE}
|
|
35
|
+
onPress={closeModal}
|
|
36
|
+
style={buttonTextStyle}
|
|
37
|
+
>
|
|
38
|
+
{t('profile.cancel')}
|
|
39
|
+
</Button>
|
|
40
|
+
<Button
|
|
41
|
+
colorScheme={ButtonColor.ORANGE}
|
|
42
|
+
size={ButtonSize.LARGE}
|
|
43
|
+
onPress={confirm}
|
|
44
|
+
style={buttonTextStyle}
|
|
45
|
+
>
|
|
46
|
+
{t('profile.yes')}
|
|
47
|
+
</Button>
|
|
48
|
+
</>
|
|
49
|
+
}
|
|
50
|
+
/>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const styles = StyleSheet.create({
|
|
55
|
+
modal: {
|
|
56
|
+
width: 530,
|
|
57
|
+
},
|
|
58
|
+
uppercase: {
|
|
59
|
+
textTransform: 'uppercase',
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const modalStyle = { container: styles.modal }
|
|
64
|
+
const buttonTextStyle = { text: styles.uppercase }
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { StyleSheet, View } from 'react-native'
|
|
3
|
+
import { useUnit } from 'effector-react'
|
|
4
|
+
import type { Language } from '@magmamath/frontend-config'
|
|
5
|
+
import {
|
|
6
|
+
BaseModal,
|
|
7
|
+
Checkbox,
|
|
8
|
+
CheckboxColor,
|
|
9
|
+
CheckboxGroup,
|
|
10
|
+
COLORS,
|
|
11
|
+
HeadingVariants,
|
|
12
|
+
Search,
|
|
13
|
+
SPACING,
|
|
14
|
+
Typography,
|
|
15
|
+
} from '@magmamath/react-native-ui'
|
|
16
|
+
import { TEST_IDS } from '@magmamath/students-qa'
|
|
17
|
+
|
|
18
|
+
import { useText } from '../../../../i18n/i18n'
|
|
19
|
+
import type { ProfileModalProps } from '../../model/profileModal.types'
|
|
20
|
+
|
|
21
|
+
const LIST_HEIGHT = 360
|
|
22
|
+
|
|
23
|
+
export const TranslationLanguageModal = ({ modal: { closeModal, params } }: ProfileModalProps) => {
|
|
24
|
+
const t = useText()
|
|
25
|
+
const { model } = params
|
|
26
|
+
const { search, languages, settings } = useUnit({
|
|
27
|
+
search: model.language.$search,
|
|
28
|
+
languages: model.language.$languages,
|
|
29
|
+
settings: model.$settings,
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const closeAndReset = () => {
|
|
33
|
+
model.language.reset()
|
|
34
|
+
closeModal()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const selectLanguage = (language: Language | null) => {
|
|
38
|
+
model.language.selectLanguage(language)
|
|
39
|
+
closeAndReset()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const items = languages.map((language) => ({
|
|
43
|
+
id: language,
|
|
44
|
+
label: language,
|
|
45
|
+
radio: true,
|
|
46
|
+
color: CheckboxColor.ORANGE,
|
|
47
|
+
}))
|
|
48
|
+
const selectedItems = items.filter((item) => item.id === settings.translationLanguage)
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<BaseModal
|
|
52
|
+
onClose={closeAndReset}
|
|
53
|
+
style={modalStyle}
|
|
54
|
+
header={
|
|
55
|
+
<View style={styles.header}>
|
|
56
|
+
<Typography variant={HeadingVariants.H2} align="center" style={styles.title}>
|
|
57
|
+
{t('profile.translationModalTitle')}
|
|
58
|
+
</Typography>
|
|
59
|
+
<Search
|
|
60
|
+
nativeID="translation-language-search"
|
|
61
|
+
value={search}
|
|
62
|
+
onChangeText={model.language.setSearch}
|
|
63
|
+
placeholder={t('profile.search')}
|
|
64
|
+
containerStyle={styles.search}
|
|
65
|
+
testID={TEST_IDS.LANGUAGE_SEARCH_INPUT}
|
|
66
|
+
/>
|
|
67
|
+
</View>
|
|
68
|
+
}
|
|
69
|
+
content={
|
|
70
|
+
<View style={styles.content}>
|
|
71
|
+
<Checkbox
|
|
72
|
+
radio
|
|
73
|
+
label={t('profile.noLanguage')}
|
|
74
|
+
checked={!settings.translationLanguage}
|
|
75
|
+
color={CheckboxColor.ORANGE}
|
|
76
|
+
style={noLanguageStyle}
|
|
77
|
+
onPress={() => selectLanguage(null)}
|
|
78
|
+
/>
|
|
79
|
+
<View style={styles.divider} />
|
|
80
|
+
<CheckboxGroup
|
|
81
|
+
items={items}
|
|
82
|
+
selectedItems={selectedItems}
|
|
83
|
+
initialNumToRender={items.length}
|
|
84
|
+
style={listStyle}
|
|
85
|
+
onPress={(item) =>
|
|
86
|
+
selectLanguage(languages.find((language) => language === item.id) ?? null)
|
|
87
|
+
}
|
|
88
|
+
/>
|
|
89
|
+
</View>
|
|
90
|
+
}
|
|
91
|
+
/>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const styles = StyleSheet.create({
|
|
96
|
+
modal: {
|
|
97
|
+
width: 530,
|
|
98
|
+
},
|
|
99
|
+
header: {
|
|
100
|
+
gap: SPACING['500'],
|
|
101
|
+
},
|
|
102
|
+
title: {
|
|
103
|
+
color: COLORS.NEUTRAL_9,
|
|
104
|
+
},
|
|
105
|
+
search: {
|
|
106
|
+
width: '100%',
|
|
107
|
+
},
|
|
108
|
+
content: {
|
|
109
|
+
gap: SPACING['300'],
|
|
110
|
+
},
|
|
111
|
+
noLanguage: {
|
|
112
|
+
paddingLeft: SPACING['200'],
|
|
113
|
+
},
|
|
114
|
+
divider: {
|
|
115
|
+
backgroundColor: COLORS.NEUTRAL_3,
|
|
116
|
+
height: 1,
|
|
117
|
+
},
|
|
118
|
+
list: {
|
|
119
|
+
height: LIST_HEIGHT,
|
|
120
|
+
width: '100%',
|
|
121
|
+
},
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
const modalStyle = { container: styles.modal }
|
|
125
|
+
const noLanguageStyle = { container: styles.noLanguage }
|
|
126
|
+
const listStyle = { container: styles.list }
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { useText } from '../../../../i18n/i18n'
|
|
3
|
+
import { ProfileCard } from '../cards/ProfileCard'
|
|
4
|
+
import { TextToSpeechRow } from './TextToSpeechRow'
|
|
5
|
+
import { TranslationLanguageRow } from './TranslationLanguageRow'
|
|
6
|
+
|
|
7
|
+
export const LanguageSettingsCard = () => {
|
|
8
|
+
const t = useText()
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<ProfileCard title={t('profile.languageSettings')}>
|
|
12
|
+
<TextToSpeechRow />
|
|
13
|
+
<TranslationLanguageRow />
|
|
14
|
+
</ProfileCard>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { StyleSheet, View } from 'react-native'
|
|
3
|
+
import { useUnit } from 'effector-react'
|
|
4
|
+
import {
|
|
5
|
+
COLORS,
|
|
6
|
+
KeyboardIcon,
|
|
7
|
+
PencilIcon,
|
|
8
|
+
SelectGroup,
|
|
9
|
+
SelectOptionColor,
|
|
10
|
+
SelectOptionProps,
|
|
11
|
+
} from '@magmamath/react-native-ui'
|
|
12
|
+
|
|
13
|
+
import { useText } from '../../../../i18n/i18n'
|
|
14
|
+
import { useProfile } from '../../context/ProfileContext'
|
|
15
|
+
import { ProfileCanvasType } from '../../shared/profile.constants'
|
|
16
|
+
import { ProfileCard } from '../cards/ProfileCard'
|
|
17
|
+
import { SettingRow } from './SettingRow'
|
|
18
|
+
|
|
19
|
+
const ICON_SIZE = 22
|
|
20
|
+
const CONTROL_MAX_WIDTH = 248
|
|
21
|
+
|
|
22
|
+
// Pass the glyph via `title` (children), not `icon`: an icon-only Button locks to a fixed
|
|
23
|
+
// square and collapses the SelectOption's flex stretch.
|
|
24
|
+
const CANVAS_OPTIONS: SelectOptionProps[] = [
|
|
25
|
+
{
|
|
26
|
+
key: String(ProfileCanvasType.DRAWING),
|
|
27
|
+
title: <PencilIcon size={ICON_SIZE} color={COLORS.NEUTRAL_9} />,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
key: String(ProfileCanvasType.SPREADSHEET),
|
|
31
|
+
title: <KeyboardIcon size={ICON_SIZE} color={COLORS.NEUTRAL_9} />,
|
|
32
|
+
},
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
export const PreferencesCard = () => {
|
|
36
|
+
const t = useText()
|
|
37
|
+
const { model } = useProfile()
|
|
38
|
+
const settings = useUnit(model.$settings)
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<ProfileCard title={t('profile.preferences')}>
|
|
42
|
+
<SettingRow label={t('profile.solveMode')}>
|
|
43
|
+
<View style={styles.control}>
|
|
44
|
+
<SelectGroup
|
|
45
|
+
color={SelectOptionColor.GREY}
|
|
46
|
+
options={CANVAS_OPTIONS}
|
|
47
|
+
selectedOptions={CANVAS_OPTIONS.filter(({ key }) => key === String(settings.canvasType))}
|
|
48
|
+
onOptionChange={({ key }) =>
|
|
49
|
+
model.setCanvasType(
|
|
50
|
+
key === String(ProfileCanvasType.SPREADSHEET)
|
|
51
|
+
? ProfileCanvasType.SPREADSHEET
|
|
52
|
+
: ProfileCanvasType.DRAWING,
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
/>
|
|
56
|
+
</View>
|
|
57
|
+
</SettingRow>
|
|
58
|
+
</ProfileCard>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const styles = StyleSheet.create({
|
|
63
|
+
control: {
|
|
64
|
+
flex: 1,
|
|
65
|
+
maxWidth: CONTROL_MAX_WIDTH,
|
|
66
|
+
},
|
|
67
|
+
})
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react'
|
|
2
|
+
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'
|
|
3
|
+
import { COLORS, HeadingVariants, SPACING, Typography } from '@magmamath/react-native-ui'
|
|
4
|
+
|
|
5
|
+
type SettingRowProps = {
|
|
6
|
+
label: string
|
|
7
|
+
children: ReactNode
|
|
8
|
+
style?: StyleProp<ViewStyle>
|
|
9
|
+
icon?: ReactNode
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const SettingRow = ({ icon, label, children, style }: SettingRowProps) => (
|
|
13
|
+
<View style={[styles.row, style]}>
|
|
14
|
+
<View style={styles.labelGroup}>
|
|
15
|
+
{icon}
|
|
16
|
+
<Typography variant={HeadingVariants.H8} style={styles.label}>
|
|
17
|
+
{label}
|
|
18
|
+
</Typography>
|
|
19
|
+
</View>
|
|
20
|
+
{children}
|
|
21
|
+
</View>
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
const styles = StyleSheet.create({
|
|
25
|
+
row: {
|
|
26
|
+
alignItems: 'center',
|
|
27
|
+
flexDirection: 'row',
|
|
28
|
+
gap: SPACING['400'],
|
|
29
|
+
justifyContent: 'space-between',
|
|
30
|
+
padding: SPACING['200'],
|
|
31
|
+
},
|
|
32
|
+
labelGroup: {
|
|
33
|
+
alignItems: 'center',
|
|
34
|
+
flexDirection: 'row',
|
|
35
|
+
flexShrink: 1,
|
|
36
|
+
gap: SPACING['200'],
|
|
37
|
+
},
|
|
38
|
+
label: {
|
|
39
|
+
color: COLORS.NEUTRAL_9,
|
|
40
|
+
flexShrink: 1,
|
|
41
|
+
},
|
|
42
|
+
})
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { useUnit } from 'effector-react'
|
|
3
|
+
import { StyleSheet, View } from 'react-native'
|
|
4
|
+
import {
|
|
5
|
+
COLORS,
|
|
6
|
+
HeadingVariants,
|
|
7
|
+
ParagraphVariants,
|
|
8
|
+
SPACING,
|
|
9
|
+
Typography,
|
|
10
|
+
} from '@magmamath/react-native-ui'
|
|
11
|
+
|
|
12
|
+
import { useText } from '../../../../i18n/i18n'
|
|
13
|
+
import { useProfile } from '../../context/ProfileContext'
|
|
14
|
+
import { TextSizeSlider } from './TextSizeSlider'
|
|
15
|
+
import { ProfileCard } from '../cards/ProfileCard'
|
|
16
|
+
|
|
17
|
+
export const TextSettingsCard = () => {
|
|
18
|
+
const t = useText()
|
|
19
|
+
const { model } = useProfile()
|
|
20
|
+
const settings = useUnit(model.$settings)
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<ProfileCard title={t('profile.textSettings')}>
|
|
24
|
+
<Typography variant={HeadingVariants.H8} style={styles.label}>
|
|
25
|
+
{t('profile.textSize')}
|
|
26
|
+
</Typography>
|
|
27
|
+
<View style={styles.sliderWrap}>
|
|
28
|
+
<TextSizeSlider value={settings.textSize} onSlidingComplete={model.setTextSize} />
|
|
29
|
+
<View style={styles.markers}>
|
|
30
|
+
<Typography variant={ParagraphVariants.XS} style={styles.marker} selectable={false}>
|
|
31
|
+
A
|
|
32
|
+
</Typography>
|
|
33
|
+
<Typography variant={ParagraphVariants.MEDIUM} style={styles.marker} selectable={false}>
|
|
34
|
+
A
|
|
35
|
+
</Typography>
|
|
36
|
+
<Typography variant={ParagraphVariants.XL} style={styles.marker} selectable={false}>
|
|
37
|
+
A
|
|
38
|
+
</Typography>
|
|
39
|
+
</View>
|
|
40
|
+
</View>
|
|
41
|
+
</ProfileCard>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const styles = StyleSheet.create({
|
|
46
|
+
label: {
|
|
47
|
+
color: COLORS.NEUTRAL_9,
|
|
48
|
+
padding: SPACING['200'],
|
|
49
|
+
},
|
|
50
|
+
sliderWrap: {
|
|
51
|
+
gap: SPACING['200'],
|
|
52
|
+
margin: SPACING['100'],
|
|
53
|
+
},
|
|
54
|
+
markers: {
|
|
55
|
+
alignItems: 'center',
|
|
56
|
+
flexDirection: 'row',
|
|
57
|
+
justifyContent: 'space-between',
|
|
58
|
+
},
|
|
59
|
+
marker: {
|
|
60
|
+
color: COLORS.NEUTRAL_7,
|
|
61
|
+
fontWeight: '700',
|
|
62
|
+
width: 16,
|
|
63
|
+
},
|
|
64
|
+
})
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import React, { useRef, useState } from 'react'
|
|
2
|
+
import { LayoutChangeEvent, PanResponder, StyleSheet, View } from 'react-native'
|
|
3
|
+
import { COLORS, SPACING } from '@magmamath/react-native-ui'
|
|
4
|
+
import { TEST_IDS } from '@magmamath/students-qa'
|
|
5
|
+
|
|
6
|
+
import { TEXT_SIZE } from '../../shared/profile.constants'
|
|
7
|
+
import { snapTextSize } from '../../shared/profile.helpers'
|
|
8
|
+
|
|
9
|
+
type TextSizeSliderProps = {
|
|
10
|
+
value: number
|
|
11
|
+
onSlidingComplete: (value: number) => void
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const THUMB_SIZE = 20
|
|
15
|
+
const DOT_SIZE = 6
|
|
16
|
+
const TRACK_HEIGHT = 10
|
|
17
|
+
const TRACK_RADIUS = 5
|
|
18
|
+
const STEPS = (TEXT_SIZE.MAX - TEXT_SIZE.MIN) / TEXT_SIZE.STEP + 1
|
|
19
|
+
const RANGE = TEXT_SIZE.MAX - TEXT_SIZE.MIN
|
|
20
|
+
const TRACK_PADDING = THUMB_SIZE / 2 - DOT_SIZE / 2
|
|
21
|
+
|
|
22
|
+
export const TextSizeSlider = ({ value, onSlidingComplete }: TextSizeSliderProps) => {
|
|
23
|
+
const [trackWidth, setTrackWidth] = useState(0)
|
|
24
|
+
const [dragValue, setDragValue] = useState<number | null>(null)
|
|
25
|
+
const widthRef = useRef(0)
|
|
26
|
+
const onCompleteRef = useRef(onSlidingComplete)
|
|
27
|
+
onCompleteRef.current = onSlidingComplete
|
|
28
|
+
|
|
29
|
+
const currentValue = dragValue ?? value
|
|
30
|
+
const fraction = RANGE === 0 ? 0 : (currentValue - TEXT_SIZE.MIN) / RANGE
|
|
31
|
+
const travel = Math.max(0, trackWidth - THUMB_SIZE)
|
|
32
|
+
|
|
33
|
+
const measureTrack = (event: LayoutChangeEvent) => {
|
|
34
|
+
const width = event.nativeEvent.layout.width
|
|
35
|
+
widthRef.current = width
|
|
36
|
+
setTrackWidth(width)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const valueFromX = (x: number) => {
|
|
40
|
+
const width = widthRef.current
|
|
41
|
+
if (width <= 0) return TEXT_SIZE.MIN
|
|
42
|
+
const ratio = Math.min(1, Math.max(0, x / width))
|
|
43
|
+
return snapTextSize(TEXT_SIZE.MIN + ratio * RANGE)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const panResponder = useRef(
|
|
47
|
+
PanResponder.create({
|
|
48
|
+
onStartShouldSetPanResponder: () => true,
|
|
49
|
+
onMoveShouldSetPanResponder: () => true,
|
|
50
|
+
onPanResponderGrant: (event) => setDragValue(valueFromX(event.nativeEvent.locationX)),
|
|
51
|
+
onPanResponderMove: (event) => setDragValue(valueFromX(event.nativeEvent.locationX)),
|
|
52
|
+
onPanResponderRelease: (event) => {
|
|
53
|
+
const next = valueFromX(event.nativeEvent.locationX)
|
|
54
|
+
setDragValue(null)
|
|
55
|
+
onCompleteRef.current(next)
|
|
56
|
+
},
|
|
57
|
+
onPanResponderTerminate: () => setDragValue(null),
|
|
58
|
+
}),
|
|
59
|
+
).current
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<View
|
|
63
|
+
style={styles.container}
|
|
64
|
+
onLayout={measureTrack}
|
|
65
|
+
testID={TEST_IDS.TEXT_SIZE_SLIDER}
|
|
66
|
+
{...panResponder.panHandlers}
|
|
67
|
+
>
|
|
68
|
+
<View style={styles.track}>
|
|
69
|
+
{Array.from({ length: STEPS }, (_, index) => {
|
|
70
|
+
const isEdge = index === 0 || index === STEPS - 1
|
|
71
|
+
return <View key={index} style={[styles.dot, isEdge && styles.dotHidden]} />
|
|
72
|
+
})}
|
|
73
|
+
</View>
|
|
74
|
+
<View style={[styles.thumb, { left: fraction * travel }]} />
|
|
75
|
+
</View>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const styles = StyleSheet.create({
|
|
80
|
+
container: {
|
|
81
|
+
cursor: 'pointer',
|
|
82
|
+
height: THUMB_SIZE,
|
|
83
|
+
justifyContent: 'center',
|
|
84
|
+
width: '100%',
|
|
85
|
+
},
|
|
86
|
+
track: {
|
|
87
|
+
alignItems: 'center',
|
|
88
|
+
backgroundColor: COLORS.NEUTRAL_3,
|
|
89
|
+
borderColor: COLORS.NEUTRAL_4,
|
|
90
|
+
borderRadius: TRACK_RADIUS,
|
|
91
|
+
borderWidth: 0.5,
|
|
92
|
+
boxShadow:
|
|
93
|
+
'inset -3px -3px 3px rgba(255, 255, 255, 0.6), inset 2px 2px 3px rgba(0, 0, 0, 0.12)',
|
|
94
|
+
flexDirection: 'row',
|
|
95
|
+
height: TRACK_HEIGHT,
|
|
96
|
+
justifyContent: 'space-between',
|
|
97
|
+
paddingHorizontal: TRACK_PADDING,
|
|
98
|
+
width: '100%',
|
|
99
|
+
},
|
|
100
|
+
dot: {
|
|
101
|
+
backgroundColor: COLORS.NEUTRAL_5,
|
|
102
|
+
borderRadius: DOT_SIZE / 2,
|
|
103
|
+
height: DOT_SIZE,
|
|
104
|
+
width: DOT_SIZE,
|
|
105
|
+
},
|
|
106
|
+
dotHidden: {
|
|
107
|
+
opacity: 0,
|
|
108
|
+
},
|
|
109
|
+
thumb: {
|
|
110
|
+
backgroundColor: COLORS.NEUTRAL_1,
|
|
111
|
+
borderRadius: THUMB_SIZE / 2,
|
|
112
|
+
boxShadow: '0px 2px 6px rgba(0, 0, 0, 0.2)',
|
|
113
|
+
height: THUMB_SIZE,
|
|
114
|
+
position: 'absolute',
|
|
115
|
+
width: THUMB_SIZE,
|
|
116
|
+
},
|
|
117
|
+
})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { useUnit } from 'effector-react'
|
|
3
|
+
import { COLORS, SpeakerIcon, Toggle } from '@magmamath/react-native-ui'
|
|
4
|
+
import { TEST_IDS } from '@magmamath/students-qa'
|
|
5
|
+
|
|
6
|
+
import { useText } from '../../../../i18n/i18n'
|
|
7
|
+
import { useProfile } from '../../context/ProfileContext'
|
|
8
|
+
import { SettingRow } from './SettingRow'
|
|
9
|
+
|
|
10
|
+
const ICON_SIZE = 20
|
|
11
|
+
|
|
12
|
+
export const TextToSpeechRow = () => {
|
|
13
|
+
const t = useText()
|
|
14
|
+
const { model } = useProfile()
|
|
15
|
+
const settings = useUnit(model.$settings)
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<SettingRow
|
|
19
|
+
icon={<SpeakerIcon size={ICON_SIZE} color={COLORS.NEUTRAL_7} />}
|
|
20
|
+
label={t('profile.textToSpeech')}
|
|
21
|
+
>
|
|
22
|
+
<Toggle
|
|
23
|
+
value={settings.textToSpeech}
|
|
24
|
+
onValueChange={model.setTextToSpeech}
|
|
25
|
+
testID={TEST_IDS.PROFILE_TTS_SWITCH}
|
|
26
|
+
/>
|
|
27
|
+
</SettingRow>
|
|
28
|
+
)
|
|
29
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { useUnit } from 'effector-react'
|
|
3
|
+
import { StyleSheet } from 'react-native'
|
|
4
|
+
import {
|
|
5
|
+
COLORS,
|
|
6
|
+
FilterDropdown,
|
|
7
|
+
FilterDropdownSize,
|
|
8
|
+
FilterDropdownVariant,
|
|
9
|
+
GlobeIcon,
|
|
10
|
+
} from '@magmamath/react-native-ui'
|
|
11
|
+
import { TEST_IDS } from '@magmamath/students-qa'
|
|
12
|
+
|
|
13
|
+
import { useText } from '../../../../i18n/i18n'
|
|
14
|
+
import { useProfile } from '../../context/ProfileContext'
|
|
15
|
+
import { SettingRow } from './SettingRow'
|
|
16
|
+
|
|
17
|
+
const ICON_SIZE = 20
|
|
18
|
+
|
|
19
|
+
export const TranslationLanguageRow = () => {
|
|
20
|
+
const t = useText()
|
|
21
|
+
const { model, onOpenTranslationModal } = useProfile()
|
|
22
|
+
const settings = useUnit(model.$settings)
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<SettingRow
|
|
26
|
+
icon={<GlobeIcon size={ICON_SIZE} color={COLORS.NEUTRAL_7} />}
|
|
27
|
+
label={t('profile.translationLanguage')}
|
|
28
|
+
style={styles.settingRow}
|
|
29
|
+
>
|
|
30
|
+
<FilterDropdown
|
|
31
|
+
variant={FilterDropdownVariant.SECONDARY}
|
|
32
|
+
size={FilterDropdownSize.MEDIUM}
|
|
33
|
+
value={settings.translationLanguage ?? undefined}
|
|
34
|
+
placeholder={t('profile.selectLanguage')}
|
|
35
|
+
disabled={settings.isTranslationLocked}
|
|
36
|
+
onPress={onOpenTranslationModal}
|
|
37
|
+
accessibilityLabel={t('profile.translationLanguage')}
|
|
38
|
+
testID={TEST_IDS.PROFILE_LANGUAGE_SELECTOR}
|
|
39
|
+
style={{
|
|
40
|
+
text: styles.filterLabel,
|
|
41
|
+
container: styles.filterContainer,
|
|
42
|
+
}}
|
|
43
|
+
/>
|
|
44
|
+
</SettingRow>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const styles = StyleSheet.create({
|
|
49
|
+
settingRow: {
|
|
50
|
+
paddingVertical: 0,
|
|
51
|
+
},
|
|
52
|
+
filterLabel: {
|
|
53
|
+
color: COLORS.NEUTRAL_7,
|
|
54
|
+
fontSize: 16,
|
|
55
|
+
fontWeight: '400',
|
|
56
|
+
},
|
|
57
|
+
filterContainer: {
|
|
58
|
+
maxWidth: 231,
|
|
59
|
+
},
|
|
60
|
+
})
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createContext, useContext, type ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
import type { ProfileModel } from '../model/ProfileModel'
|
|
4
|
+
|
|
5
|
+
export type ProfileContextValue = {
|
|
6
|
+
model: ProfileModel
|
|
7
|
+
onLogout: () => void
|
|
8
|
+
onOpenTranslationModal: () => void
|
|
9
|
+
onOpenJoinClass: () => void
|
|
10
|
+
showSolveMode?: boolean
|
|
11
|
+
versionInfo?: ReactNode
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const ProfileContext = createContext<ProfileContextValue | null>(null)
|
|
15
|
+
|
|
16
|
+
export function useProfile(): ProfileContextValue {
|
|
17
|
+
const value = useContext(ProfileContext)
|
|
18
|
+
if (!value) {
|
|
19
|
+
throw new Error('useProfile must be used within ProfileProvider')
|
|
20
|
+
}
|
|
21
|
+
return value
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const ProfileProvider = ProfileContext.Provider
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { Profile } from './Profile'
|
|
2
|
+
export { ProfileModel } from './model/ProfileModel'
|
|
3
|
+
export type { ProfileApiProps } from './model/ProfileApi'
|
|
4
|
+
export type { ProfileContextValue } from './context/ProfileContext'
|
|
5
|
+
export { TranslationLanguageModal } from './components/modals/TranslationLanguageModal'
|
|
6
|
+
export { JoinClassModal } from './components/modals/JoinClassModal'
|
|
7
|
+
export { LogoutConfirmModal } from './components/modals/LogoutConfirmModal'
|
|
8
|
+
export type { ProfileModalParams, LogoutModalParams } from './model/profileModal.types'
|
|
9
|
+
export { JoinClassError } from './shared/JoinClassError'
|
|
10
|
+
export * from './shared/profile.types'
|
|
11
|
+
export * from './shared/profile.constants'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { createEffect } from 'effector'
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
JoinClassPayload,
|
|
5
|
+
JoinClassResult,
|
|
6
|
+
ProfileSettingsUpdate,
|
|
7
|
+
} from '../shared/profile.types'
|
|
8
|
+
|
|
9
|
+
export type ProfileApiProps = {
|
|
10
|
+
// `=> void` (not a Promise union) lets consumers wire an effector event or effect directly.
|
|
11
|
+
updateSettings: (payload: ProfileSettingsUpdate) => void
|
|
12
|
+
joinClass: (payload: JoinClassPayload) => Promise<JoinClassResult>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class ProfileApi {
|
|
16
|
+
public readonly updateSettingsFx
|
|
17
|
+
public readonly joinClassFx
|
|
18
|
+
|
|
19
|
+
constructor(props: ProfileApiProps) {
|
|
20
|
+
this.updateSettingsFx = createEffect(props.updateSettings)
|
|
21
|
+
this.joinClassFx = createEffect(props.joinClass)
|
|
22
|
+
}
|
|
23
|
+
}
|