@nualang/nualang-ui-components 0.1.1359 → 0.1.1360

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.
@@ -32,9 +32,17 @@ function Exercise({
32
32
  const noRoleplays = name.toLowerCase() === "roleplays" && roleplays.length === 0;
33
33
  const noPhrases = name.toLowerCase() === "phrases" && !phrases?.length && !getPhraseLists;
34
34
  const [roleplaysOpen, setRoleplaysOpen] = useState(noRoleplays ? false : true);
35
- const [phraseListsOpen, setPhraseListsOpen] = useState(false);
35
+ const [phraseListsOpen, setPhraseListsOpen] = useState(noPhrases ? false : true);
36
+ const [hasPhraseListsAvailable, setHasPhraseListsAvailable] = useState(true);
37
+ const handlePhraseListsLoaded = count => {
38
+ if (count === 0) {
39
+ setHasPhraseListsAvailable(false);
40
+ setPhraseListsOpen(false);
41
+ }
42
+ };
43
+ const noPhraseListsAvailable = name.toLowerCase() === "phrases" && !hasPhraseListsAvailable;
36
44
  return /*#__PURE__*/_jsxs(Tooltip, {
37
- title: (name === "roleplays" && noRoleplays ? t("topic_no_roleplays") : "") || (name === "phrases" && noPhrases ? t("topic_no_phrases") : ""),
45
+ title: (name === "roleplays" && noRoleplays ? t("topic_no_roleplays") : "") || (name === "phrases" && noPhrases ? t("topic_no_phrases") : "") || (noPhraseListsAvailable ? t("no_phrase_lists") : ""),
38
46
  children: [/*#__PURE__*/_jsxs(ListItemButton, {
39
47
  onClick: () => {
40
48
  if (name.toLowerCase() === "roleplays") {
@@ -46,7 +54,7 @@ function Exercise({
46
54
  display: "flex",
47
55
  alignItems: "center",
48
56
  justifyContent: "space-between",
49
- disabled: isExerciseSelected || noRoleplays || noPhrases,
57
+ disabled: isExerciseSelected || noRoleplays || noPhrases || noPhraseListsAvailable,
50
58
  sx: theme => ({
51
59
  [theme.breakpoints.up("sm")]: {
52
60
  ml: 3.5
@@ -83,7 +91,8 @@ function Exercise({
83
91
  t: t,
84
92
  isExerciseSelected: isExerciseSelected,
85
93
  setIsExerciseSelected: setIsExerciseSelected,
86
- isExpanded: phraseListsOpen
94
+ isExpanded: phraseListsOpen,
95
+ onPhraseListsLoaded: handlePhraseListsLoaded
87
96
  })
88
97
  })
89
98
  }), name.toLowerCase() === "roleplays" && /*#__PURE__*/_jsx(Collapse, {
@@ -1,4 +1,4 @@
1
- import { useState } from "react";
1
+ import { useState, useEffect } from "react";
2
2
  import { Box, Button, ListItemText, ListItemButton, Avatar, ListItemIcon, Collapse, CircularProgress, Typography } from "@mui/material";
3
3
  import PlayCircleOutlineIcon from "@mui/icons-material/PlayCircleOutline";
4
4
  import HearingIcon from "@mui/icons-material/Hearing";
@@ -23,6 +23,7 @@ function PhraseList({
23
23
  const isTranslationHidden = phraseList?.hiddenPhraseGroupGames?.translation;
24
24
  const isListeningHidden = phraseList?.hiddenPhraseGroupGames?.listening;
25
25
  const isMeaningHidden = phraseList?.hiddenPhraseGroupGames?.meaning;
26
+ const hasDefinitions = phraseList?.phrases?.some(p => p.definitions?.length > 0);
26
27
  const hasSelectableGame = !isTranslationHidden || !isListeningHidden || !isMeaningHidden;
27
28
  if (!hasSelectableGame) return null;
28
29
  const handleGameSelected = exercise => () => {
@@ -115,7 +116,7 @@ function PhraseList({
115
116
  })]
116
117
  }), !isMeaningHidden && /*#__PURE__*/_jsxs(ListItemButton, {
117
118
  onClick: handleGameSelected("meaning"),
118
- disabled: isPhraseListSelected || isExerciseSelected,
119
+ disabled: isPhraseListSelected || isExerciseSelected || !hasDefinitions,
119
120
  children: [/*#__PURE__*/_jsx(ListItemIcon, {
120
121
  children: /*#__PURE__*/_jsx(ExtensionIcon, {})
121
122
  }), /*#__PURE__*/_jsx(ListItemText, {
@@ -141,7 +142,8 @@ function PhraseListSelection({
141
142
  t,
142
143
  isExerciseSelected,
143
144
  isExpanded,
144
- setIsExerciseSelected
145
+ setIsExerciseSelected,
146
+ onPhraseListsLoaded
145
147
  }) {
146
148
  const [isPhraseListSelected, setIsPhraseListSelected] = useState(false);
147
149
  const phraseListsQuery = courseQuerys.useCourseSectionTopicPhraseLists(async (cId, sId, tId, filters) => getPhraseLists(cId, sId, tId, filters), {
@@ -156,6 +158,11 @@ function PhraseListSelection({
156
158
  enabled: !!courseId && !!sectionId && !!topicId && isExpanded
157
159
  });
158
160
  const phraseLists = phraseListsQuery.isSuccess && Array.isArray(phraseListsQuery.data?.Items) ? phraseListsQuery.data.Items : [];
161
+ useEffect(() => {
162
+ if (phraseListsQuery.isSuccess && onPhraseListsLoaded) {
163
+ onPhraseListsLoaded(phraseLists.length);
164
+ }
165
+ }, [phraseListsQuery.isSuccess, phraseLists.length]);
159
166
  if (phraseListsQuery.isError) {
160
167
  return /*#__PURE__*/_jsxs(Box, {
161
168
  px: 2,
@@ -113,10 +113,7 @@ function LiveMeaning({
113
113
  if (isCreator && currentQuestion && definitionText !== "") {
114
114
  speak(definitionText, voice, false, "#currentDefinition", voiceLanguageCode, false, voicePitch, () => setIsFinishedInitialSpeaking(true));
115
115
  }
116
- return () => {
117
- // Cleanup: cancel/stop any in-flight speak
118
- };
119
- }, [speak, definitionText, voice, voiceLanguageCode, voicePitch, currentQuestion?.phrase, isCreator]);
116
+ }, [currentQuestion?.phrase, isCreator]);
120
117
  const voiceMap = getVoiceImages(voices || []);
121
118
  const getVoiceImage = () => {
122
119
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nualang/nualang-ui-components",
3
- "version": "0.1.1359",
3
+ "version": "0.1.1360",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "files": [