@nualang/nualang-ui-components 0.1.1414 → 0.1.1415
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/Cards/Course/Course.js +145 -13
- package/dist/Chat/Messages/Message/Message.js +4 -1
- package/dist/Chat/Messages/Message/Message.test.js +55 -0
- package/dist/Containers/App/App.js +10 -6
- package/dist/Dialogs/GenerateRoleplay/GenerateRoleplay.js +5 -2
- package/dist/Dialogs/QuickCreateChatbotDialog/QuickCreateChatbotDialog.js +2 -1
- package/dist/Editors/Bot/Bot.js +6 -4
- package/dist/Editors/Roleplay/Roleplay.js +5 -2
- package/dist/Exercises/ListenAndSpeak/ListenAndSpeak.js +1 -1
- package/dist/Exercises/Listener/Listener.js +1 -1
- package/dist/Exercises/Meaning/Meaning.js +1 -1
- package/dist/Exercises/MeaningReadWrite/MeaningReadWriteGame.js +4 -1
- package/dist/Exercises/Pronouncer/Pronouncer.js +1 -1
- package/dist/Exercises/Roleplay/Roleplay.js +5 -2
- package/dist/Exercises/Translator/Translator.js +1 -1
- package/dist/Forms/CreateBot/Steps/BotInformation/BotInformation.js +13 -2
- package/dist/Forms/CreateRoleplay/Steps/RoleplayInformation/RoleplayInformation.js +4 -2
- package/dist/Forms/UpdatePhraseList/UpdatePhraseList.js +5 -3
- package/dist/Forms/VoiceSelector/VoiceSelector.js +29 -14
- package/dist/Forms/VoiceSelector/VoiceSelector.test.js +125 -3
- package/dist/Lists/Courses/Courses.js +5 -2
- package/dist/Lists/Courses/Courses.test.js +10 -0
- package/dist/Lists/Roleplays/Roleplays.js +5 -2
- package/dist/Live/LiveListener/LiveListener.js +1 -1
- package/dist/Live/LiveMeaning/LiveMeaning.js +1 -1
- package/dist/Live/LiveMeaningReadWrite/LiveMeaningReadWrite.js +1 -1
- package/dist/Live/LiveTranslator/LiveTranslator.js +1 -1
- package/dist/Misc/ChatBubble/ChatBubble.js +2 -0
- package/dist/Misc/HoverText/HoverText.js +7 -2
- package/dist/hooks/useExerciseState.js +2 -0
- package/dist/index.js +1 -1
- package/dist/utils/voiceImages.js +19 -4
- package/dist/utils/voices.js +12 -2
- package/package.json +1 -1
- package/dist/Cards/SubmissionsCard/SubmissionsCard.js +0 -138
- package/dist/Cards/index.js +0 -2
- package/dist/Dialogs/Code/Code.js +0 -147
- package/dist/Dialogs/Code/Code.test.js +0 -20
- package/dist/Dialogs/Code/package.json +0 -6
- package/dist/Dialogs/CreateTopic/CreateTopic.js +0 -135
- package/dist/Dialogs/CreateTopic/CreateTopic.test.js +0 -15
- package/dist/Dialogs/CreateTopic/package.json +0 -6
- package/dist/Dialogs/FeedbackDialog/FeedbackDialog.js +0 -123
- package/dist/Dialogs/Icons/Icons.js +0 -18
- package/dist/Dialogs/Icons/package.json +0 -6
- package/dist/Dialogs/InactivePopover/InactivePopover.js +0 -71
- package/dist/Dialogs/InviteDialog/upload-emails-csv.png +0 -0
- package/dist/Dialogs/PDFViewer/pdf24.pdf +0 -0
- package/dist/Dialogs/SearchTopic/SearchTopic.js +0 -87
- package/dist/Dialogs/UploadPhrases/upload-phrases-csv.png +0 -0
- package/dist/Exercises/Roleplay/OriginalRoleplay.js +0 -944
- package/dist/Forms/CreateBot/CreateBot.js +0 -77
- package/dist/Forms/CreateBot/CreateBot.test.js +0 -20
- package/dist/Forms/CreateBot/package.json +0 -6
- package/dist/Forms/CreateClassroom/CreateClassroom.js +0 -56
- package/dist/Forms/CreateClassroom/CreateClassroom.test.js +0 -20
- package/dist/Forms/CreateClassroom/package.json +0 -6
- package/dist/Forms/CreateCourse/CreateCourse.js +0 -66
- package/dist/Forms/CreateCourse/CreateCourse.test.js +0 -20
- package/dist/Forms/CreateCourse/package.json +0 -6
- package/dist/Forms/CreateMeetingMultiStepForm/images/input1.js +0 -2
- package/dist/Forms/CreateMeetingMultiStepForm/images/input5.js +0 -2
- package/dist/Forms/CreateMeetingMultiStepForm/images/mode1.js +0 -2
- package/dist/Forms/CreateMeetingMultiStepForm/images/mode2.js +0 -2
- package/dist/Forms/CreateMeetingMultiStepForm/sampleTemplates.js +0 -44
- package/dist/Forms/CreateRoleplay/CreateRoleplay.js +0 -87
- package/dist/Forms/CreateRoleplay/CreateRoleplay.test.js +0 -20
- package/dist/Forms/CreateRoleplay/package.json +0 -6
- package/dist/Forms/CreateUser/CreateUser.js +0 -77
- package/dist/Forms/FeedbackForm/FeedbackForm.js +0 -1036
- package/dist/Forms/MultiStepFormDialog/MultiStepFormDialog.js +0 -354
- package/dist/Forms/MultiStepFormDialog/MultiStepFormDialog.test.js +0 -20
- package/dist/Forms/MultiStepFormDialog/package.json +0 -6
- package/dist/Forms/MultiStepFormHook/MultiStepFormHook.js +0 -279
- package/dist/Forms/RecordingInfo/RecordingInfo.js +0 -140
- package/dist/Lists/Categories/sample.png +0 -0
- package/dist/Lists/Sections/Sections.js +0 -238
- package/dist/Lists/Sections/Sections.test.js +0 -20
- package/dist/Lists/Sections/package.json +0 -6
- package/dist/Lists/Voices/horse.ogm +0 -0
- package/dist/Misc/AxiosRestExample/AxiosRestExample.js +0 -46
- package/dist/Misc/AxiosRestExample/AxiosRestPostExample.js +0 -65
- package/dist/Misc/ColorSelector/ColorSelector.js +0 -143
- package/dist/Misc/ColorSelector/package.json +0 -6
- package/dist/Misc/EmojiInput/css/emoji-mart.css +0 -497
- package/dist/Misc/MedalSelector/PlaceholderMedal.svg +0 -27
- package/dist/Misc/NotFound/Bot.js +0 -62
- package/dist/Misc/NotFound/Bots.js +0 -75
- package/dist/Misc/NotFound/Discussions.js +0 -52
- package/dist/Misc/NotFound/Roleplay.js +0 -62
- package/dist/Misc/NotFound/Roleplays.js +0 -75
- package/dist/Misc/NotFound/Script.js +0 -47
- package/dist/Misc/Notes/Notes.js +0 -77
- package/dist/Misc/Notes/Notes.test.js +0 -20
- package/dist/Misc/Notes/package.json +0 -6
- package/dist/Misc/NualaCreating/Nuala1.js +0 -352
- package/dist/Misc/OnboardingEnrolment/CheckIfCourse.js +0 -33
- package/dist/Misc/OnboardingEnrolment/ClassCodeInvalid.js +0 -14
- package/dist/Misc/OnboardingEnrolment/ClassroomCodeInvalid.js +0 -14
- package/dist/Misc/OnboardingEnrolment/EnrolKey.js +0 -14
- package/dist/Misc/RoleplayChatWaveForm/RoleplayChatWaveForm.js +0 -199
- package/dist/Misc/RoleplayChatWaveForm/package.json +0 -6
- package/dist/Misc/RoleplayWaveform/RoleplayWaveform.js +0 -95
- package/dist/Misc/RoleplayWaveform/package.json +0 -6
- package/dist/Misc/SpeedDial/SpeedDial.js +0 -49
- package/dist/Misc/SpeedDial/package.json +0 -6
- package/dist/Misc/SubmitTextField/SubmitTextField.js +0 -48
- package/dist/Misc/newGenerateCardBackground/Generate Card Background (standalone) (1).html +0 -186
- package/dist/Navigation/ResponsiveStepper/ResponsiveStepper.js +0 -253
- package/dist/Navigation/ResponsiveStepper/ResponsiveStepper.test.js +0 -20
- package/dist/Navigation/ResponsiveStepper/package.json +0 -6
- package/dist/Navigation/ResponsiveTabs/TabContainer.js +0 -28
- package/dist/Tables/CreatedDiscussionsTable/CreatedDiscussionsTable.js +0 -188
- package/dist/Tables/GameRows/GameRows.js +0 -87
- package/dist/Tables/GameRows/package.json +0 -6
- package/dist/Tables/Games/Games.js +0 -258
- package/dist/Tables/Games/package.json +0 -6
- package/dist/Tables/Phrases/Phrases.js +0 -200
- package/dist/Tables/Phrases/Phrases.test.js +0 -20
- package/dist/Tables/Phrases/package.json +0 -6
- package/dist/Tables/Plans/Plans.js +0 -74
- package/dist/Tables/Plans/plans.json +0 -162
- package/dist/Tables/Plans/plans2.json +0 -151
- package/dist/Tables/Progress/Header.js +0 -559
- package/dist/Tables/Progress/README.md +0 -53
- package/dist/Tables/SubmissionsTableCards/SubmissionsTableCards.js +0 -296
- package/dist/Tables/Users/UsersTable.js +0 -159
- package/dist/img/Bronze Medal.svg +0 -545
- package/dist/img/Bronze.svg +0 -349
- package/dist/img/BronzeBadge.svg +0 -493
- package/dist/img/BronzeBadgeWithoutRibbon.svg +0 -317
- package/dist/img/Frame 51.svg +0 -98
- package/dist/img/Frame 52.svg +0 -131
- package/dist/img/Frame 53.svg +0 -139
- package/dist/img/Gold Badge.svg +0 -362
- package/dist/img/Gold Medal.svg +0 -481
- package/dist/img/GoldBadge.svg +0 -470
- package/dist/img/GoldBadgeWithoutRibbon.svg +0 -324
- package/dist/img/NualaCreateImage.svg +0 -129
- package/dist/img/NualangLiveAnwerQuicklyListening.svg +0 -3608
- package/dist/img/NualangLiveListen.png +0 -0
- package/dist/img/NualangLiveListenQuickly.png +0 -0
- package/dist/img/NualangLiveListenToPhrase.svg +0 -4286
- package/dist/img/NualangLivePickAnswer.svg +0 -134
- package/dist/img/NualangLiveResult.png +0 -0
- package/dist/img/NualangLiveRoleplayAnswer.png +0 -0
- package/dist/img/NualangLiveRoleplayConvo.png +0 -0
- package/dist/img/NualangLiveSeePlace.svg +0 -134
- package/dist/img/NualangLiveTranslate.png +0 -0
- package/dist/img/NualangLiveTranslateQuickly.png +0 -0
- package/dist/img/NualangLiveViewConversations.svg +0 -135
- package/dist/img/Polly.svg +0 -18
- package/dist/img/Silver Badge.svg +0 -523
- package/dist/img/Silver Medal.svg +0 -549
- package/dist/img/SilverBadge.svg +0 -655
- package/dist/img/SilverBadgeWithoutRibbon.svg +0 -491
- package/dist/img/avatars/0-nuala-001.svg +0 -34
- package/dist/img/avatars/0-nuala-002.svg +0 -25
- package/dist/img/avatars/0-nuala-003.svg +0 -27
- package/dist/img/avatars/0-nuala-004.svg +0 -41
- package/dist/img/avatars/0-nuala-005.svg +0 -33
- package/dist/img/avatars/0-nuala-006.svg +0 -32
- package/dist/img/avatars/0-nuala-007.svg +0 -37
- package/dist/img/avatars/0-nuala-008.svg +0 -21
- package/dist/img/avatars/0-nuala-009.svg +0 -21
- package/dist/img/avatars/0-nuala-010.svg +0 -39
- package/dist/img/avatars/0-nuala-011.svg +0 -33
- package/dist/img/avatars/0-nuala-012.svg +0 -43
- package/dist/img/avatars/0-nuala-013.svg +0 -36
- package/dist/img/avatars/0-nuala-014.svg +0 -30
- package/dist/img/avatars/0-nuala-015.svg +0 -28
- package/dist/img/avatars/0-nuala-016.svg +0 -24
- package/dist/img/avatars/0-nuala-017.svg +0 -31
- package/dist/img/avatars/0-nuala-018.svg +0 -29
- package/dist/img/avatars/0-nuala-019.svg +0 -57
- package/dist/img/avatars/0-nuala-020.svg +0 -30
- package/dist/img/avatars/0-nuala-021.svg +0 -28
- package/dist/img/avatars/001-man.svg +0 -104
- package/dist/img/avatars/002-girl.svg +0 -92
- package/dist/img/avatars/006-woman-1.svg +0 -99
- package/dist/img/avatars/028-woman-7.svg +0 -95
- package/dist/img/avatars/029-man-8.svg +0 -95
- package/dist/img/avatars/035-woman-9.svg +0 -86
- package/dist/img/avatars/066-boy-6.svg +0 -91
- package/dist/img/avatars/1-teacher-001.svg +0 -38
- package/dist/img/avatars/1-teacher-002.svg +0 -52
- package/dist/img/avatars/1-teacher-003.svg +0 -86
- package/dist/img/avatars/avatar1.png +0 -0
- package/dist/img/avatars/avatar2.png +0 -0
- package/dist/img/avatars/nuala_10_speaking.svg +0 -45
- package/dist/img/avatars/nuala_11_speaking.svg +0 -41
- package/dist/img/avatars/nuala_12_speaking.svg +0 -49
- package/dist/img/avatars/nuala_13_speaking.svg +0 -44
- package/dist/img/avatars/nuala_14_speaking.svg +0 -36
- package/dist/img/avatars/nuala_15_speaking.svg +0 -36
- package/dist/img/avatars/nuala_16_speaking.svg +0 -32
- package/dist/img/avatars/nuala_17_speaking.svg +0 -39
- package/dist/img/avatars/nuala_18_speaking.svg +0 -37
- package/dist/img/avatars/nuala_19_speaking.svg +0 -65
- package/dist/img/avatars/nuala_1_celebrating.svg +0 -30
- package/dist/img/avatars/nuala_1_speaking.svg +0 -37
- package/dist/img/avatars/nuala_20_speaking.svg +0 -38
- package/dist/img/avatars/nuala_21_speaking.svg +0 -36
- package/dist/img/avatars/nuala_2_speaking.svg +0 -29
- package/dist/img/avatars/nuala_3_speaking.svg +0 -28
- package/dist/img/avatars/nuala_4_speaking.svg +0 -41
- package/dist/img/avatars/nuala_5_speaking.svg +0 -36
- package/dist/img/avatars/nuala_6_speaking.svg +0 -36
- package/dist/img/avatars/nuala_7_speaking.svg +0 -43
- package/dist/img/avatars/nuala_8_speaking.svg +0 -29
- package/dist/img/avatars/nuala_9_speaking.svg +0 -27
- package/dist/img/dashboard.svg +0 -104
- package/dist/img/defaultImg.png +0 -0
- package/dist/img/nua-glyph.svg +0 -6
- package/dist/img/nuala-silhouette.svg +0 -43
- package/dist/img/nuala_1_celebrating.svg +0 -33
- package/dist/img/nuala_2_celebrating.svg +0 -20
- package/dist/img/nuala_3_celebrating.svg +0 -21
- package/dist/img/nuala_4_celebrating.svg +0 -30
- package/dist/img/nuala_5_celebrating.svg +0 -30
- package/dist/img/nuala_celebrating.svg +0 -39
- package/dist/img/nuala_speaking_4.svg +0 -41
- package/dist/img/nualas.svg +0 -185
- package/dist/img/soundWave.png +0 -0
- package/dist/img/stars1.svg +0 -44
- package/dist/img/stars2.svg +0 -30
- package/dist/img/teacher.svg +0 -89
- package/dist/img/work-chat.svg +0 -1
- package/dist/img/world.svg +0 -41
|
@@ -2,8 +2,10 @@ import { useState, memo } from "react";
|
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
3
|
import { useInView } from "react-intersection-observer";
|
|
4
4
|
// Mui
|
|
5
|
-
import { Button, Box, Typography, IconButton, Menu, MenuItem, Checkbox, Tooltip, CardActions, CardActionArea, Divider } from "@mui/material";
|
|
5
|
+
import { Button, Box, Typography, IconButton, Menu, MenuItem, Checkbox, Tooltip, CardActions, CardActionArea, Divider, Chip } from "@mui/material";
|
|
6
6
|
import Skeleton from "@mui/material/Skeleton";
|
|
7
|
+
import { styled } from "@mui/material/styles";
|
|
8
|
+
import { tooltipClasses } from "@mui/material/Tooltip";
|
|
7
9
|
import Group from "@mui/icons-material/Group";
|
|
8
10
|
import ExitToApp from "@mui/icons-material/ExitToApp";
|
|
9
11
|
import Close from "@mui/icons-material/Close";
|
|
@@ -159,6 +161,141 @@ function OverflowMenu({
|
|
|
159
161
|
})]
|
|
160
162
|
});
|
|
161
163
|
}
|
|
164
|
+
const DIFFICULTY_ORDER = ["A1", "A2", "B1", "B2", "C1", "C2"];
|
|
165
|
+
const MAX_VISIBLE_DIFFICULTIES = 2;
|
|
166
|
+
const DifficultyOverflowTooltip = styled(({
|
|
167
|
+
className,
|
|
168
|
+
...props
|
|
169
|
+
}) => /*#__PURE__*/_jsx(Tooltip, {
|
|
170
|
+
...props,
|
|
171
|
+
classes: {
|
|
172
|
+
popper: className
|
|
173
|
+
}
|
|
174
|
+
}))(({
|
|
175
|
+
theme
|
|
176
|
+
}) => ({
|
|
177
|
+
[`& .${tooltipClasses.tooltip}`]: {
|
|
178
|
+
backgroundColor: theme.palette.background.paper,
|
|
179
|
+
color: theme.palette.text.primary,
|
|
180
|
+
border: `1px solid ${theme.palette.divider}`,
|
|
181
|
+
borderRadius: theme.shape.borderRadius,
|
|
182
|
+
boxShadow: theme.shadows[4],
|
|
183
|
+
padding: theme.spacing(1.5, 2),
|
|
184
|
+
minWidth: 160,
|
|
185
|
+
maxWidth: 260
|
|
186
|
+
}
|
|
187
|
+
}));
|
|
188
|
+
function normalizeDifficulties(difficulty) {
|
|
189
|
+
const values = Array.isArray(difficulty) ? difficulty : difficulty ? [difficulty] : [];
|
|
190
|
+
return DIFFICULTY_ORDER.filter(level => values.includes(level));
|
|
191
|
+
}
|
|
192
|
+
function difficultyChipSx(theme, compact) {
|
|
193
|
+
return {
|
|
194
|
+
height: compact ? 20 : 24,
|
|
195
|
+
backgroundColor: theme.palette.action.selected,
|
|
196
|
+
color: theme.palette.text.secondary,
|
|
197
|
+
"& .MuiChip-label": {
|
|
198
|
+
fontSize: compact ? "0.7rem" : "0.75rem",
|
|
199
|
+
px: 0.75
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function CourseDifficulty({
|
|
204
|
+
t,
|
|
205
|
+
difficulty,
|
|
206
|
+
compact
|
|
207
|
+
}) {
|
|
208
|
+
const levels = normalizeDifficulties(difficulty);
|
|
209
|
+
if (levels.length === 0) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
const levelLabels = levels.map(level => t(`card_${level}`));
|
|
213
|
+
const visibleLabels = levelLabels.slice(0, MAX_VISIBLE_DIFFICULTIES);
|
|
214
|
+
const overflowLabels = levelLabels.slice(MAX_VISIBLE_DIFFICULTIES);
|
|
215
|
+
return /*#__PURE__*/_jsxs(Box, {
|
|
216
|
+
component: "span",
|
|
217
|
+
role: "group",
|
|
218
|
+
"aria-label": `${t("difficulty")}: ${levelLabels.join(", ")}`,
|
|
219
|
+
sx: {
|
|
220
|
+
display: "inline-flex",
|
|
221
|
+
alignItems: "center",
|
|
222
|
+
gap: 0.5
|
|
223
|
+
},
|
|
224
|
+
"data-cy": "course-difficulty",
|
|
225
|
+
children: [/*#__PURE__*/_jsx(DifficultyIcon, {
|
|
226
|
+
sx: {
|
|
227
|
+
...classes.infoIcon,
|
|
228
|
+
fontSize: compact ? 18 : undefined
|
|
229
|
+
},
|
|
230
|
+
fontSize: "small"
|
|
231
|
+
}), visibleLabels.map((label, index) => /*#__PURE__*/_jsx(Chip, {
|
|
232
|
+
label: label,
|
|
233
|
+
size: "small",
|
|
234
|
+
"data-cy": `course-difficulty-chip-${index}`,
|
|
235
|
+
sx: theme => difficultyChipSx(theme, compact)
|
|
236
|
+
}, label)), overflowLabels.length > 0 && /*#__PURE__*/_jsx(DifficultyOverflowTooltip, {
|
|
237
|
+
placement: "bottom-start",
|
|
238
|
+
title: /*#__PURE__*/_jsxs(Box, {
|
|
239
|
+
sx: {
|
|
240
|
+
minWidth: 140
|
|
241
|
+
},
|
|
242
|
+
children: [/*#__PURE__*/_jsx(Typography, {
|
|
243
|
+
variant: "caption",
|
|
244
|
+
sx: {
|
|
245
|
+
display: "block",
|
|
246
|
+
color: "text.secondary",
|
|
247
|
+
fontWeight: 700,
|
|
248
|
+
letterSpacing: 0.5,
|
|
249
|
+
textTransform: "uppercase",
|
|
250
|
+
pb: 1,
|
|
251
|
+
borderBottom: "1px solid",
|
|
252
|
+
borderColor: "divider"
|
|
253
|
+
},
|
|
254
|
+
children: t("difficulties")
|
|
255
|
+
}), levelLabels.map((label, index) => /*#__PURE__*/_jsxs(Box, {
|
|
256
|
+
sx: {
|
|
257
|
+
display: "flex",
|
|
258
|
+
alignItems: "center",
|
|
259
|
+
gap: 1,
|
|
260
|
+
py: 0.75,
|
|
261
|
+
borderBottom: index < levelLabels.length - 1 ? "1px solid" : "none",
|
|
262
|
+
borderColor: "divider"
|
|
263
|
+
},
|
|
264
|
+
children: [/*#__PURE__*/_jsx(Typography, {
|
|
265
|
+
component: "span",
|
|
266
|
+
sx: {
|
|
267
|
+
color: "text.disabled",
|
|
268
|
+
fontSize: "1.3rem",
|
|
269
|
+
lineHeight: 1
|
|
270
|
+
},
|
|
271
|
+
children: "\u2022"
|
|
272
|
+
}), /*#__PURE__*/_jsx(Typography, {
|
|
273
|
+
variant: "body2",
|
|
274
|
+
sx: {
|
|
275
|
+
color: "text.primary"
|
|
276
|
+
},
|
|
277
|
+
children: label
|
|
278
|
+
})]
|
|
279
|
+
}, label))]
|
|
280
|
+
}),
|
|
281
|
+
children: /*#__PURE__*/_jsx(Chip, {
|
|
282
|
+
label: `+${overflowLabels.length}`,
|
|
283
|
+
size: "small",
|
|
284
|
+
"aria-label": `${t("difficulty")}: ${levelLabels.join(", ")}`,
|
|
285
|
+
"data-cy": "course-difficulty-overflow",
|
|
286
|
+
sx: theme => ({
|
|
287
|
+
...difficultyChipSx(theme, compact),
|
|
288
|
+
fontWeight: 600
|
|
289
|
+
})
|
|
290
|
+
})
|
|
291
|
+
})]
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
CourseDifficulty.propTypes = {
|
|
295
|
+
t: PropTypes.func.isRequired,
|
|
296
|
+
difficulty: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
|
|
297
|
+
compact: PropTypes.bool
|
|
298
|
+
};
|
|
162
299
|
function CourseLoading({
|
|
163
300
|
compact = false
|
|
164
301
|
}) {
|
|
@@ -278,7 +415,7 @@ function CourseCard({
|
|
|
278
415
|
limit: 1000
|
|
279
416
|
}
|
|
280
417
|
}, {
|
|
281
|
-
enabled: !!course?.courseId && isOutlineOpen
|
|
418
|
+
enabled: !!course?.courseId && (isOutlineOpen || visible)
|
|
282
419
|
});
|
|
283
420
|
const {
|
|
284
421
|
membersQuery,
|
|
@@ -356,6 +493,7 @@ function CourseCard({
|
|
|
356
493
|
handleLeaveCourse(courseId);
|
|
357
494
|
};
|
|
358
495
|
const courseSections = sectionsQuery.isSuccess ? sectionsQuery.data.Items : [];
|
|
496
|
+
const topicDifficulties = sectionsQuery.isSuccess ? [...new Set(courseSections.flatMap(section => section.topics || []).map(topic => topic.difficulty).filter(Boolean))] : [];
|
|
359
497
|
const deleteCourse = async () => {
|
|
360
498
|
const confirmed = await confirm(t("delete_course"), t("delete_course_confirmation"), "", true, t("course_deletion_note", {
|
|
361
499
|
sectionCount: courseSections ? courseSections.length : 0
|
|
@@ -497,16 +635,10 @@ function CourseCard({
|
|
|
497
635
|
columnGap: 1.5,
|
|
498
636
|
rowGap: 0.5
|
|
499
637
|
},
|
|
500
|
-
children: [
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
sx: {
|
|
505
|
-
...classes.infoIcon,
|
|
506
|
-
fontSize: compact ? 18 : undefined
|
|
507
|
-
},
|
|
508
|
-
fontSize: "small"
|
|
509
|
-
}), t(`card_${course.difficulty}`)]
|
|
638
|
+
children: [/*#__PURE__*/_jsx(CourseDifficulty, {
|
|
639
|
+
t: t,
|
|
640
|
+
difficulty: topicDifficulties.length > 0 ? topicDifficulties : course?.difficulty,
|
|
641
|
+
compact: compact
|
|
510
642
|
}), (course?.pdf || course.topicsWithPdf && Object.keys(course?.topicsWithPdf)?.length > 0) && /*#__PURE__*/_jsxs(CardInfoSectionItem, {
|
|
511
643
|
variant: "caption",
|
|
512
644
|
component: "span",
|
|
@@ -673,7 +805,7 @@ MemoizedCourse.propTypes = {
|
|
|
673
805
|
courseId: PropTypes.string.isRequired,
|
|
674
806
|
courseName: PropTypes.string.isRequired,
|
|
675
807
|
description: PropTypes.string.isRequired,
|
|
676
|
-
difficulty: PropTypes.string,
|
|
808
|
+
difficulty: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
|
|
677
809
|
picture: PropTypes.string.isRequired,
|
|
678
810
|
learnLang: PropTypes.string.isRequired,
|
|
679
811
|
forLang: PropTypes.string.isRequired,
|
|
@@ -272,6 +272,7 @@ export default function Message({
|
|
|
272
272
|
speak,
|
|
273
273
|
stopSpeaking,
|
|
274
274
|
voice,
|
|
275
|
+
voiceLanguageCode,
|
|
275
276
|
voicePitch,
|
|
276
277
|
voiceSpeed,
|
|
277
278
|
handleEditMessage,
|
|
@@ -471,6 +472,7 @@ export default function Message({
|
|
|
471
472
|
forLang: forLang,
|
|
472
473
|
handleSpeak: handleSpeak,
|
|
473
474
|
voice: voice,
|
|
475
|
+
voiceLanguageCode: voiceLanguageCode,
|
|
474
476
|
voicePitch: voicePitch,
|
|
475
477
|
voiceSpeed: voiceSpeed,
|
|
476
478
|
disableTranslation: disableTranslation,
|
|
@@ -538,6 +540,7 @@ export default function Message({
|
|
|
538
540
|
forLang: forLang,
|
|
539
541
|
handleSpeak: handleSpeak,
|
|
540
542
|
voice: voice,
|
|
543
|
+
voiceLanguageCode: voiceLanguageCode,
|
|
541
544
|
voicePitch: voicePitch,
|
|
542
545
|
voiceSpeed: voiceSpeed,
|
|
543
546
|
disableTranslation: disableTranslation,
|
|
@@ -623,7 +626,7 @@ export default function Message({
|
|
|
623
626
|
children: /*#__PURE__*/_jsx(IconButton, {
|
|
624
627
|
color: "inherit",
|
|
625
628
|
disabled: isSpeaking || recognizing || muteSound || isMessagePlaying || showTranslation,
|
|
626
|
-
onClick: () => speak(text, voice, false, messageContainerIdSelector,
|
|
629
|
+
onClick: () => speak(text, voice, false, messageContainerIdSelector, voiceLanguageCode, false, voicePitch),
|
|
627
630
|
size: "small",
|
|
628
631
|
"aria-label": messageIndex !== -1 ? accessibilityText ? accessibilityText : `Speak message ${messageIndex + 1}` : accessibilityText ? accessibilityText : `Speak message`,
|
|
629
632
|
sx: {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { render, screen, fireEvent, cleanup } from "@testing-library/react";
|
|
2
|
+
import { describe, it, expect, vi, afterEach } from "vitest";
|
|
3
|
+
import { createTheme, ThemeProvider } from "@mui/material/styles";
|
|
4
|
+
import Message from "./Message";
|
|
5
|
+
|
|
6
|
+
// Messages spreads each message over these props, so a roleplay message carries
|
|
7
|
+
// its own actor's voice and accent; a bot chat supplies one voice for the
|
|
8
|
+
// whole chat. Replaying must use whichever applies, not the language default.
|
|
9
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
|
+
const renderMessage = (overrides = {}) => {
|
|
11
|
+
const theme = createTheme();
|
|
12
|
+
const speak = vi.fn();
|
|
13
|
+
render(/*#__PURE__*/_jsx(ThemeProvider, {
|
|
14
|
+
theme: theme,
|
|
15
|
+
children: /*#__PURE__*/_jsx(Message, {
|
|
16
|
+
t: k => k,
|
|
17
|
+
text: "Kia ora",
|
|
18
|
+
speak: speak,
|
|
19
|
+
messageIndex: 0,
|
|
20
|
+
index: 0,
|
|
21
|
+
messageCount: 1,
|
|
22
|
+
messages: [{
|
|
23
|
+
text: "Kia ora"
|
|
24
|
+
}],
|
|
25
|
+
...overrides
|
|
26
|
+
})
|
|
27
|
+
}));
|
|
28
|
+
return speak;
|
|
29
|
+
};
|
|
30
|
+
describe("Message replay", () => {
|
|
31
|
+
afterEach(cleanup);
|
|
32
|
+
it("speaks with the accent the message carries", () => {
|
|
33
|
+
const speak = renderMessage({
|
|
34
|
+
voice: "Aria",
|
|
35
|
+
voiceLanguageCode: "en-NZ"
|
|
36
|
+
});
|
|
37
|
+
fireEvent.click(screen.getByRole("button", {
|
|
38
|
+
name: /Speak message/i
|
|
39
|
+
}));
|
|
40
|
+
|
|
41
|
+
// 5th positional argument of speak() is the accent.
|
|
42
|
+
expect(speak).toHaveBeenCalled();
|
|
43
|
+
expect(speak.mock.calls[0][1]).toBe("Aria");
|
|
44
|
+
expect(speak.mock.calls[0][4]).toBe("en-NZ");
|
|
45
|
+
});
|
|
46
|
+
it("sends no accent when nothing supplies one", () => {
|
|
47
|
+
const speak = renderMessage({
|
|
48
|
+
voice: "Joanna"
|
|
49
|
+
});
|
|
50
|
+
fireEvent.click(screen.getByRole("button", {
|
|
51
|
+
name: /Speak message/i
|
|
52
|
+
}));
|
|
53
|
+
expect(speak.mock.calls[0][4]).toBeUndefined();
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -386,16 +386,20 @@ function App({
|
|
|
386
386
|
startIcon: /*#__PURE__*/_jsx(Add, {}),
|
|
387
387
|
color: "secondary",
|
|
388
388
|
id: "appbar-create-button",
|
|
389
|
+
disabled: !subscription?.isSubscriptionLoaded,
|
|
389
390
|
children: t("create")
|
|
390
391
|
}) : /*#__PURE__*/_jsx(Tooltip, {
|
|
391
392
|
title: t("create"),
|
|
392
393
|
enterDelay: 300,
|
|
393
|
-
children: /*#__PURE__*/_jsx(
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
394
|
+
children: /*#__PURE__*/_jsx("span", {
|
|
395
|
+
children: /*#__PURE__*/_jsx(IconButton, {
|
|
396
|
+
color: "inherit",
|
|
397
|
+
"aria-label": t("create"),
|
|
398
|
+
"aria-haspopup": "true",
|
|
399
|
+
onClick: handleClickCreate,
|
|
400
|
+
disabled: !subscription?.isSubscriptionLoaded,
|
|
401
|
+
children: /*#__PURE__*/_jsx(Add, {})
|
|
402
|
+
})
|
|
399
403
|
})
|
|
400
404
|
})), isLgScreen && /*#__PURE__*/_jsx(WhatsNew, {
|
|
401
405
|
t: t,
|
|
@@ -110,13 +110,16 @@ function GenerateRoleplayDialog({
|
|
|
110
110
|
if (generatedRoleplay && generatedRoleplay.script) {
|
|
111
111
|
const tempMessages = generatedRoleplay.script.filter(l => !l?.question).map(line => {
|
|
112
112
|
const isActor1 = line.actor === 1;
|
|
113
|
+
const actor = (isActor1 ? generatedRoleplay.actor1 : generatedRoleplay.actor2) || {};
|
|
113
114
|
return {
|
|
114
115
|
...line,
|
|
115
116
|
text: line.text,
|
|
116
117
|
isMyMessage: !isActor1,
|
|
117
118
|
name: getActorName(isActor1),
|
|
118
|
-
userImage:
|
|
119
|
-
voice:
|
|
119
|
+
userImage: actor.picture || null,
|
|
120
|
+
voice: actor.voice || null,
|
|
121
|
+
voiceLanguageCode: actor.voiceLanguageCode || null,
|
|
122
|
+
voicePitch: actor.voicePitch || null
|
|
120
123
|
};
|
|
121
124
|
});
|
|
122
125
|
setPreviewMessages(tempMessages);
|
|
@@ -459,7 +459,7 @@ export default function QuickCreateChatbotDialog({
|
|
|
459
459
|
setSelectedVoicePitch(null);
|
|
460
460
|
setBotPicture(picked.voice.userImage || "");
|
|
461
461
|
}, [open, selectedVoice, voices]);
|
|
462
|
-
const selectedVoiceOption = findVoice(voices, selectedVoice)?.voice;
|
|
462
|
+
const selectedVoiceOption = findVoice(voices, selectedVoice, selectedVoiceLanguageCode)?.voice;
|
|
463
463
|
const hasAvailableVoice = Boolean(selectedVoice && selectedVoiceLanguageCode);
|
|
464
464
|
const isValid = Boolean(botTitle.trim()) && Boolean(difficulty) && Boolean(templateId) && Boolean(template && template.botId === templateId) && Number(numberOfQuestions) > 0 && hasAvailableVoice;
|
|
465
465
|
const handleSubmit = async () => {
|
|
@@ -600,6 +600,7 @@ export default function QuickCreateChatbotDialog({
|
|
|
600
600
|
name: "voiceSelector",
|
|
601
601
|
label: t("bot_voice"),
|
|
602
602
|
value: selectedVoice || "",
|
|
603
|
+
valueLanguageCode: selectedVoiceLanguageCode,
|
|
603
604
|
margin: "normal",
|
|
604
605
|
variant: "outlined",
|
|
605
606
|
fullWidth: true,
|
package/dist/Editors/Bot/Bot.js
CHANGED
|
@@ -486,18 +486,20 @@ function Bot({
|
|
|
486
486
|
return;
|
|
487
487
|
}
|
|
488
488
|
const voice = initialValues.voice;
|
|
489
|
+
const voiceLanguageCode = initialValues.voiceLanguageCode;
|
|
489
490
|
const message = {
|
|
490
491
|
isMyMessage: isMyMessage,
|
|
491
492
|
userImage: isErrorMsg ? BotNualaImage : isMyMessage ? userAttributes && userAttributes.picture ? userAttributes.picture : null : bot && bot.botAvatar ? bot.botAvatar : null,
|
|
492
493
|
name: isErrorMsg ? "Bot" : isMyMessage ? userAttributes && userAttributes.preferred_username ? userAttributes.preferred_username : "Me" : bot && bot.name ? bot.name : "Bot",
|
|
493
494
|
text: text,
|
|
494
|
-
datetime: new Date()
|
|
495
|
+
datetime: new Date(),
|
|
496
|
+
// Recorded so the replay button reproduces what was spoken.
|
|
497
|
+
voice: voice,
|
|
498
|
+
voiceLanguageCode: voiceLanguageCode
|
|
495
499
|
};
|
|
496
500
|
setMessages(prevState => [...prevState, message]);
|
|
497
501
|
if (playAudio !== false && learnLang !== "irish") {
|
|
498
|
-
speak(message.text, voice, false, `#message${messages.length + 1}
|
|
499
|
-
//voiceLanguageCode
|
|
500
|
-
);
|
|
502
|
+
speak(message.text, voice, false, `#message${messages.length + 1}`, voiceLanguageCode);
|
|
501
503
|
}
|
|
502
504
|
};
|
|
503
505
|
const handleSubmitText = async () => {
|
|
@@ -627,6 +627,7 @@ function Roleplay({
|
|
|
627
627
|
};
|
|
628
628
|
const currentMessages = (roleplay && roleplay.script ? roleplay.script : []).map(line => {
|
|
629
629
|
const isActor1 = line.actor === 1;
|
|
630
|
+
const actor = (isActor1 ? roleplay.actor1 : roleplay.actor2) || {};
|
|
630
631
|
return {
|
|
631
632
|
...line,
|
|
632
633
|
text: line.text && formatMarkdownNewlines(line.text),
|
|
@@ -636,8 +637,10 @@ function Roleplay({
|
|
|
636
637
|
}) : roleplay.actor2 && roleplay.actor2.name ? roleplay.actor2.name : t("actor", {
|
|
637
638
|
number: "2"
|
|
638
639
|
}),
|
|
639
|
-
userImage:
|
|
640
|
-
voice:
|
|
640
|
+
userImage: actor.picture || null,
|
|
641
|
+
voice: actor.voice || null,
|
|
642
|
+
voiceLanguageCode: actor.voiceLanguageCode || null,
|
|
643
|
+
voicePitch: actor.voicePitch || null
|
|
641
644
|
};
|
|
642
645
|
});
|
|
643
646
|
const afterElements = /*#__PURE__*/_jsx("div", {
|
|
@@ -444,7 +444,7 @@ function ListenAndSpeak({
|
|
|
444
444
|
voiceLanguageCode,
|
|
445
445
|
voicePitch
|
|
446
446
|
} = topicInfo;
|
|
447
|
-
const voiceMap = getVoiceImages(voices || []);
|
|
447
|
+
const voiceMap = getVoiceImages(voices || [], voiceLanguageCode);
|
|
448
448
|
const getNualaCelebratingImage = () => {
|
|
449
449
|
try {
|
|
450
450
|
const exerciseVoice = voiceMap.get(voice) || {};
|
|
@@ -354,7 +354,7 @@ function Listener({
|
|
|
354
354
|
voiceLanguageCode,
|
|
355
355
|
voicePitch
|
|
356
356
|
} = topicInfo;
|
|
357
|
-
const voiceMap = getVoiceImages(voices || []);
|
|
357
|
+
const voiceMap = getVoiceImages(voices || [], voiceLanguageCode);
|
|
358
358
|
const getNualaCelebratingImage = () => {
|
|
359
359
|
try {
|
|
360
360
|
const exerciseVoice = voiceMap.get(voice) || {};
|
|
@@ -358,7 +358,7 @@ function Meaning({
|
|
|
358
358
|
voiceLanguageCode,
|
|
359
359
|
voicePitch
|
|
360
360
|
} = topicInfo;
|
|
361
|
-
const voiceMap = getVoiceImages(voices || []);
|
|
361
|
+
const voiceMap = getVoiceImages(voices || [], voiceLanguageCode);
|
|
362
362
|
const getNualaCelebratingImage = () => {
|
|
363
363
|
try {
|
|
364
364
|
const exerciseVoice = voiceMap.get(voice) || {};
|
|
@@ -338,9 +338,10 @@ export default function MeaningReadWrite({
|
|
|
338
338
|
})();
|
|
339
339
|
const {
|
|
340
340
|
voice,
|
|
341
|
+
voiceLanguageCode,
|
|
341
342
|
voicePitch
|
|
342
343
|
} = topicInfo;
|
|
343
|
-
const voiceMap = getVoiceImages(voices || []);
|
|
344
|
+
const voiceMap = getVoiceImages(voices || [], voiceLanguageCode);
|
|
344
345
|
const getNualaCelebratingImage = () => {
|
|
345
346
|
try {
|
|
346
347
|
const exerciseVoice = voiceMap.get(voice) || {};
|
|
@@ -374,6 +375,7 @@ export default function MeaningReadWrite({
|
|
|
374
375
|
text: currentPhrase.phrase,
|
|
375
376
|
learnLanguage: learnLang,
|
|
376
377
|
voiceName: voice || null,
|
|
378
|
+
languageCode: voiceLanguageCode || null,
|
|
377
379
|
voiceSpeed,
|
|
378
380
|
pitch: voicePitch || null
|
|
379
381
|
});
|
|
@@ -559,6 +561,7 @@ export default function MeaningReadWrite({
|
|
|
559
561
|
stopAudio: stopAudio,
|
|
560
562
|
learnLang: learnLang,
|
|
561
563
|
voice: voice || null,
|
|
564
|
+
voiceLanguageCode: voiceLanguageCode || null,
|
|
562
565
|
voicePitch: voicePitch || null,
|
|
563
566
|
voiceSpeed: voiceSpeed,
|
|
564
567
|
forLang: forLang,
|
|
@@ -456,7 +456,7 @@ function Pronouncer({
|
|
|
456
456
|
voiceLanguageCode,
|
|
457
457
|
voicePitch
|
|
458
458
|
} = topicInfo;
|
|
459
|
-
const voiceMap = getVoiceImages(voices || []);
|
|
459
|
+
const voiceMap = getVoiceImages(voices || [], voiceLanguageCode);
|
|
460
460
|
const getNualaCelebratingImage = () => {
|
|
461
461
|
try {
|
|
462
462
|
const exerciseVoice = voiceMap.get(voice) || {};
|
|
@@ -177,13 +177,16 @@ function Roleplay({
|
|
|
177
177
|
if (roleplay && roleplay.script) {
|
|
178
178
|
const tempMessages = roleplay.script.filter(l => !l?.question).map(line => {
|
|
179
179
|
const isActor1 = line.actor === 1;
|
|
180
|
+
const actor = (isActor1 ? roleplay.actor1 : roleplay.actor2) || {};
|
|
180
181
|
return {
|
|
181
182
|
...line,
|
|
182
183
|
text: formatMarkdownNewlines(line.text),
|
|
183
184
|
isMyMessage: !isActor1,
|
|
184
185
|
name: getActorName(isActor1),
|
|
185
|
-
userImage:
|
|
186
|
-
voice:
|
|
186
|
+
userImage: actor.picture || null,
|
|
187
|
+
voice: actor.voice || null,
|
|
188
|
+
voiceLanguageCode: actor.voiceLanguageCode || null,
|
|
189
|
+
voicePitch: actor.voicePitch || null
|
|
187
190
|
};
|
|
188
191
|
});
|
|
189
192
|
setPreviewMessges(tempMessages);
|
|
@@ -523,7 +523,7 @@ function Translator({
|
|
|
523
523
|
voiceLanguageCode,
|
|
524
524
|
voicePitch
|
|
525
525
|
} = topicInfo;
|
|
526
|
-
const voiceMap = getVoiceImages(voices || []);
|
|
526
|
+
const voiceMap = getVoiceImages(voices || [], voiceLanguageCode);
|
|
527
527
|
const getNualaCelebratingImage = () => {
|
|
528
528
|
try {
|
|
529
529
|
const exerciseVoice = voiceMap.get(voice) || {};
|
|
@@ -451,6 +451,8 @@ function BotInformation({
|
|
|
451
451
|
}), /*#__PURE__*/_jsxs(Grid, {
|
|
452
452
|
size: 12,
|
|
453
453
|
children: [learnLang !== "irish" && /*#__PURE__*/_jsx(VoiceSelector, {
|
|
454
|
+
handleSpeak: handleSpeak,
|
|
455
|
+
learnLang: learnLang,
|
|
454
456
|
id: "voice",
|
|
455
457
|
name: "voice",
|
|
456
458
|
"data-cy": "voice",
|
|
@@ -462,12 +464,12 @@ function BotInformation({
|
|
|
462
464
|
voices: voiceOptions,
|
|
463
465
|
label: t("bot_voice"),
|
|
464
466
|
value: voice,
|
|
467
|
+
valueLanguageCode: voiceLanguageCode,
|
|
465
468
|
onChange: e => {
|
|
466
469
|
if (e && e.target && e.target.value) {
|
|
467
470
|
handleChange(e);
|
|
468
471
|
const voiceSelected = e.target.value;
|
|
469
|
-
const
|
|
470
|
-
const languageCode = voiceOptionElem.getAttribute("data-language-code");
|
|
472
|
+
const languageCode = e.target.languageCode;
|
|
471
473
|
handleChange({
|
|
472
474
|
target: {
|
|
473
475
|
name: "voice",
|
|
@@ -486,6 +488,15 @@ function BotInformation({
|
|
|
486
488
|
value: languageCode
|
|
487
489
|
}
|
|
488
490
|
});
|
|
491
|
+
// The avatar belongs to the voice, and two accents can share a
|
|
492
|
+
// voice name with different avatars, so it follows the accent
|
|
493
|
+
// the selector resolved rather than the name alone.
|
|
494
|
+
handleChange({
|
|
495
|
+
target: {
|
|
496
|
+
name: "botAvatar",
|
|
497
|
+
value: e.target.picture
|
|
498
|
+
}
|
|
499
|
+
});
|
|
489
500
|
handleChange({
|
|
490
501
|
target: {
|
|
491
502
|
name: "voicePitch",
|
|
@@ -165,6 +165,8 @@ export function ActorForm({
|
|
|
165
165
|
children: t("choose_avatar")
|
|
166
166
|
})]
|
|
167
167
|
}), learnLang !== "irish" && /*#__PURE__*/_jsx(VoiceSelector, {
|
|
168
|
+
handleSpeak: handleSpeak,
|
|
169
|
+
learnLang: learnLang,
|
|
168
170
|
id: `actor${number}.voice`,
|
|
169
171
|
"data-cy": `actor${number}.voice`,
|
|
170
172
|
name: `actor${number}.voice`,
|
|
@@ -176,11 +178,11 @@ export function ActorForm({
|
|
|
176
178
|
t: t,
|
|
177
179
|
voices: voiceOptions,
|
|
178
180
|
value: voice,
|
|
181
|
+
valueLanguageCode: voiceLanguageCode,
|
|
179
182
|
onChange: e => {
|
|
180
183
|
if (e && e.target && e.target.value) {
|
|
181
184
|
const voiceSelected = e.target.value;
|
|
182
|
-
const
|
|
183
|
-
const languageCode = voiceOptionElem.getAttribute("data-language-code");
|
|
185
|
+
const languageCode = e.target.languageCode;
|
|
184
186
|
handleChange({
|
|
185
187
|
target: {
|
|
186
188
|
name: `actor${number}.voice`,
|
|
@@ -83,7 +83,7 @@ export default function UpdatePhraseList({
|
|
|
83
83
|
isKeyboardHiddenPhraseGroupGames: rawInitialValues.isKeyboardHiddenPhraseGroupGames ?? {},
|
|
84
84
|
hiddenWordBankPhraseGroupGames: rawInitialValues.hiddenWordBankPhraseGroupGames ?? {},
|
|
85
85
|
hiddenImagePhraseGroupGames: rawInitialValues.hiddenImagePhraseGroupGames ?? {
|
|
86
|
-
|
|
86
|
+
meaning: true,
|
|
87
87
|
"meaning-listen-and-speak": true,
|
|
88
88
|
"meaning-read-and-write": true
|
|
89
89
|
}
|
|
@@ -288,6 +288,8 @@ export default function UpdatePhraseList({
|
|
|
288
288
|
gutterBottom: true,
|
|
289
289
|
children: t("excercise_voice_desc")
|
|
290
290
|
}), /*#__PURE__*/_jsx(VoiceSelector, {
|
|
291
|
+
handleSpeak: handleSpeak,
|
|
292
|
+
learnLang: learnLang,
|
|
291
293
|
id: "voice",
|
|
292
294
|
name: "voice",
|
|
293
295
|
"data-cy": "voice",
|
|
@@ -299,11 +301,11 @@ export default function UpdatePhraseList({
|
|
|
299
301
|
voices: voiceOptions,
|
|
300
302
|
label: t("excercise_voice"),
|
|
301
303
|
value: values.voice,
|
|
304
|
+
valueLanguageCode: values.voiceLanguageCode,
|
|
302
305
|
onChange: e => {
|
|
303
306
|
if (e && e.target && e.target.value) {
|
|
304
307
|
const voiceSelected = e.target.value;
|
|
305
|
-
const
|
|
306
|
-
const languageCode = voiceOptionElem.getAttribute("data-language-code");
|
|
308
|
+
const languageCode = e.target.languageCode;
|
|
307
309
|
handleChange({
|
|
308
310
|
target: {
|
|
309
311
|
name: "voice",
|