catchup-library-web 1.20.35 → 1.21.0
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/index.js +1056 -823
- package/dist/index.mjs +971 -738
- package/package.json +2 -6
- package/src/components/activities/material-contents/FillInTheBlanksActivityMaterialContent.tsx +62 -2
- package/src/components/activities/material-contents/GroupingActivityMaterialContent.tsx +363 -203
- package/src/components/activities/material-contents/MatchingActivityMaterialContent.tsx +318 -172
- package/src/components/activities/material-contents/OrderingActivityMaterialContent.tsx +76 -2
- package/src/components/activities/material-contents/FillInTheBlanksActivityMaterialContent2.tsx +0 -306
- package/src/components/activities/material-contents/OrderingActivityMaterialContent2.tsx +0 -231
- package/src/components/dnds/DraggableDroppableItem.tsx +0 -60
- package/src/components/dnds/DraggableItem.tsx +0 -39
- package/src/components/dnds/DroppableItem.tsx +0 -33
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from "react";
|
|
2
|
-
import { useDrop } from "react-dnd";
|
|
3
2
|
import ShowMaterialMediaByContentType from "./ShowMaterialMediaByContentType";
|
|
4
3
|
import { InlineMath } from "react-katex";
|
|
5
4
|
import { constructInputWithSpecialExpressionList } from "../../../utilization/CatchtivityUtilization";
|
|
6
5
|
import { IMatchingActivityMaterialProps } from "../../../properties/ActivityProperties";
|
|
7
|
-
import DraggableItem from "../../dnds/DraggableItem";
|
|
8
|
-
import DroppableItem from "../../dnds/DroppableItem";
|
|
9
6
|
import DividerLine from "../../dividers/DividerLine";
|
|
10
7
|
|
|
11
8
|
const MatchingActivityMaterialContent = ({
|
|
@@ -18,17 +15,22 @@ const MatchingActivityMaterialContent = ({
|
|
|
18
15
|
isPreview,
|
|
19
16
|
showCorrectAnswer,
|
|
20
17
|
}: IMatchingActivityMaterialProps) => {
|
|
21
|
-
const [selectedValue, setSelectedValue] = useState(null);
|
|
22
|
-
const [
|
|
18
|
+
const [selectedValue, setSelectedValue] = useState<string | null>(null);
|
|
19
|
+
const [draggedValue, setDraggedValue] = useState<string | null>(null);
|
|
20
|
+
const [dropTargetKey, setDropTargetKey] = useState<string | null>(null);
|
|
21
|
+
const [draggedElement, setDraggedElement] = useState<HTMLElement | null>(
|
|
22
|
+
null
|
|
23
|
+
);
|
|
23
24
|
const [isShuffled, setIsShuffled] = useState(false);
|
|
24
|
-
const [shuffledMaterialList, setShuffledMaterialList] = useState([]);
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
const [shuffledMaterialList, setShuffledMaterialList] = useState<any[]>([]);
|
|
26
|
+
const dragElementRef = useRef<HTMLDivElement>(null);
|
|
27
|
+
const [mousePosition, setMousePosition] = useState<{ x: number; y: number }>({
|
|
28
|
+
x: 0,
|
|
29
|
+
y: 0,
|
|
30
|
+
});
|
|
31
|
+
const [touchPosition, setTouchPosition] = useState<{ x: number; y: number }>({
|
|
32
|
+
x: 0,
|
|
33
|
+
y: 0,
|
|
32
34
|
});
|
|
33
35
|
const itemsRef = useRef<HTMLDivElement>(null);
|
|
34
36
|
|
|
@@ -50,32 +52,20 @@ const MatchingActivityMaterialContent = ({
|
|
|
50
52
|
materialList.push(materialMap[materialKey]);
|
|
51
53
|
});
|
|
52
54
|
setShuffledMaterialList(shuffleArray(materialList));
|
|
53
|
-
}, []);
|
|
55
|
+
}, [materialMap, isShuffled]);
|
|
54
56
|
|
|
55
57
|
useEffect(() => {
|
|
56
58
|
if (!showCorrectAnswer) return;
|
|
57
59
|
answer.data.find(
|
|
58
60
|
(answerData: any) => answerData.type === "MATCHING"
|
|
59
61
|
).answerMap = materialMap;
|
|
60
|
-
}, [showCorrectAnswer]);
|
|
62
|
+
}, [showCorrectAnswer, answer, materialMap]);
|
|
61
63
|
|
|
62
64
|
const retrieveAnswerMap = () => {
|
|
63
65
|
const foundIndex = answer.data.findIndex(
|
|
64
66
|
(answerData: any) => answerData.type === "MATCHING"
|
|
65
67
|
);
|
|
66
68
|
return answer.data[foundIndex].answerMap;
|
|
67
|
-
// const sortedAnswerMapKeys = Object.keys(answerMap).sort((a, b) =>
|
|
68
|
-
// answerMap[a]
|
|
69
|
-
// ? answerMap[b]
|
|
70
|
-
// ? answerMap[a].localeCompare(answerMap[b])
|
|
71
|
-
// : 1
|
|
72
|
-
// : -1
|
|
73
|
-
// );
|
|
74
|
-
// const sortedAnswerMap: any = {};
|
|
75
|
-
// for (const answerMapKey of sortedAnswerMapKeys) {
|
|
76
|
-
// sortedAnswerMap[answerMapKey] = answerMap[answerMapKey];
|
|
77
|
-
// }
|
|
78
|
-
// return sortedAnswerMap;
|
|
79
69
|
};
|
|
80
70
|
|
|
81
71
|
const retrieveFilteredMaterialList = (answerMap: any) => {
|
|
@@ -100,12 +90,99 @@ const MatchingActivityMaterialContent = ({
|
|
|
100
90
|
return "INCORRECT";
|
|
101
91
|
};
|
|
102
92
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
93
|
+
// Mouse drag handlers
|
|
94
|
+
const handleMouseDown = (
|
|
95
|
+
e: React.MouseEvent,
|
|
96
|
+
materialValue: string
|
|
97
|
+
): void => {
|
|
98
|
+
if (!checkCanAnswerQuestion()) return;
|
|
99
|
+
e.preventDefault();
|
|
100
|
+
setDraggedValue(materialValue);
|
|
101
|
+
setSelectedValue(null);
|
|
102
|
+
setMousePosition({ x: e.clientX, y: e.clientY });
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const handleMouseMove = (e: React.MouseEvent): void => {
|
|
106
|
+
if (!draggedValue) return;
|
|
107
|
+
|
|
108
|
+
setMousePosition({ x: e.clientX, y: e.clientY });
|
|
109
|
+
|
|
110
|
+
// Find the element under the mouse point
|
|
111
|
+
const elementUnder = document.elementFromPoint(e.clientX, e.clientY);
|
|
112
|
+
const dropZone = elementUnder?.closest("[data-matching-drop-zone]");
|
|
113
|
+
|
|
114
|
+
if (dropZone) {
|
|
115
|
+
const dropKey = dropZone.getAttribute("data-matching-drop-zone");
|
|
116
|
+
setDropTargetKey(dropKey);
|
|
117
|
+
} else {
|
|
118
|
+
setDropTargetKey(null);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const handleMouseUp = (): void => {
|
|
123
|
+
if (dropTargetKey !== null && draggedValue !== null) {
|
|
124
|
+
onChange(answer, dropTargetKey, draggedValue);
|
|
125
|
+
}
|
|
126
|
+
setDraggedValue(null);
|
|
127
|
+
setDropTargetKey(null);
|
|
128
|
+
setMousePosition({ x: 0, y: 0 });
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// Touch drag handlers
|
|
132
|
+
const handleTouchStart = (
|
|
133
|
+
e: React.TouchEvent,
|
|
134
|
+
materialValue: string,
|
|
135
|
+
element: HTMLElement
|
|
136
|
+
): void => {
|
|
137
|
+
if (!checkCanAnswerQuestion()) return;
|
|
138
|
+
const touch = e.touches[0];
|
|
139
|
+
setDraggedValue(materialValue);
|
|
140
|
+
setDraggedElement(element);
|
|
141
|
+
setTouchPosition({ x: touch.clientX, y: touch.clientY });
|
|
142
|
+
setSelectedValue(null);
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const handleTouchMove = (e: React.TouchEvent): void => {
|
|
146
|
+
if (!draggedValue) return;
|
|
147
|
+
|
|
148
|
+
const touch = e.touches[0];
|
|
149
|
+
setTouchPosition({ x: touch.clientX, y: touch.clientY });
|
|
150
|
+
|
|
151
|
+
// Find the element under the touch point
|
|
152
|
+
const elementUnder = document.elementFromPoint(
|
|
153
|
+
touch.clientX,
|
|
154
|
+
touch.clientY
|
|
155
|
+
);
|
|
156
|
+
const dropZone = elementUnder?.closest("[data-matching-drop-zone]");
|
|
157
|
+
|
|
158
|
+
if (dropZone) {
|
|
159
|
+
const dropKey = dropZone.getAttribute("data-matching-drop-zone");
|
|
160
|
+
setDropTargetKey(dropKey);
|
|
161
|
+
} else {
|
|
162
|
+
setDropTargetKey(null);
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const handleTouchEnd = (): void => {
|
|
167
|
+
if (dropTargetKey !== null && draggedValue !== null) {
|
|
168
|
+
onChange(answer, dropTargetKey, draggedValue);
|
|
169
|
+
}
|
|
170
|
+
setDraggedValue(null);
|
|
171
|
+
setDropTargetKey(null);
|
|
172
|
+
setDraggedElement(null);
|
|
173
|
+
setTouchPosition({ x: 0, y: 0 });
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// Click/tap to select (for easier mobile interaction)
|
|
177
|
+
const handleSelectItem = (materialValue: string): void => {
|
|
178
|
+
if (!checkCanAnswerQuestion()) return;
|
|
179
|
+
setSelectedValue(materialValue);
|
|
180
|
+
setDraggedValue(null);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const handleDropZoneClick = (answerMapKey: string): void => {
|
|
184
|
+
if (selectedValue !== null) {
|
|
185
|
+
onChange(answer, answerMapKey, selectedValue);
|
|
109
186
|
setSelectedValue(null);
|
|
110
187
|
}
|
|
111
188
|
};
|
|
@@ -114,7 +191,103 @@ const MatchingActivityMaterialContent = ({
|
|
|
114
191
|
const filteredMaterialList = retrieveFilteredMaterialList(answerMap);
|
|
115
192
|
|
|
116
193
|
return (
|
|
117
|
-
|
|
194
|
+
<div onMouseMove={handleMouseMove} onMouseUp={handleMouseUp}>
|
|
195
|
+
{/* Floating drag preview for mouse */}
|
|
196
|
+
{draggedValue && mousePosition.x > 0 && (
|
|
197
|
+
<div
|
|
198
|
+
className="fixed pointer-events-none z-50 opacity-80"
|
|
199
|
+
style={{
|
|
200
|
+
left: `${mousePosition.x}px`,
|
|
201
|
+
top: `${mousePosition.y}px`,
|
|
202
|
+
transform: "translate(-50%, -50%)",
|
|
203
|
+
}}
|
|
204
|
+
>
|
|
205
|
+
{contentMap.type === "TEXT" ? (
|
|
206
|
+
<div className="border-catchup-blue border-2 rounded-catchup-xlarge bg-white shadow-lg">
|
|
207
|
+
<div className="flex flex-col items-center justify-center m-2 min-w-[200px] px-4">
|
|
208
|
+
<p className="text-lg whitespace-pre-wrap">
|
|
209
|
+
{constructInputWithSpecialExpressionList(draggedValue).map(
|
|
210
|
+
(inputPart, index) => (
|
|
211
|
+
<span
|
|
212
|
+
key={index}
|
|
213
|
+
className={`${inputPart.isBold ? "font-bold" : ""} ${
|
|
214
|
+
inputPart.isUnderline ? "underline" : ""
|
|
215
|
+
}`}
|
|
216
|
+
>
|
|
217
|
+
{inputPart.isEquation ? (
|
|
218
|
+
<span className="text-xl">
|
|
219
|
+
<InlineMath math={inputPart.value} />
|
|
220
|
+
</span>
|
|
221
|
+
) : (
|
|
222
|
+
inputPart.value
|
|
223
|
+
)}
|
|
224
|
+
</span>
|
|
225
|
+
)
|
|
226
|
+
)}
|
|
227
|
+
</p>
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
) : (
|
|
231
|
+
<div className="border-catchup-blue border-2 rounded-catchup-xlarge bg-white shadow-lg">
|
|
232
|
+
<ShowMaterialMediaByContentType
|
|
233
|
+
key={`${uniqueValue}-drag-mouse`}
|
|
234
|
+
contentType={contentMap.type}
|
|
235
|
+
src={draggedValue}
|
|
236
|
+
canFullScreen={false}
|
|
237
|
+
/>
|
|
238
|
+
</div>
|
|
239
|
+
)}
|
|
240
|
+
</div>
|
|
241
|
+
)}
|
|
242
|
+
|
|
243
|
+
{/* Floating drag preview for touch */}
|
|
244
|
+
{draggedValue && touchPosition.x > 0 && (
|
|
245
|
+
<div
|
|
246
|
+
className="fixed pointer-events-none z-50 opacity-80"
|
|
247
|
+
style={{
|
|
248
|
+
left: `${touchPosition.x}px`,
|
|
249
|
+
top: `${touchPosition.y}px`,
|
|
250
|
+
transform: "translate(-50%, -50%)",
|
|
251
|
+
}}
|
|
252
|
+
>
|
|
253
|
+
{contentMap.type === "TEXT" ? (
|
|
254
|
+
<div className="border-catchup-blue border-2 rounded-catchup-xlarge bg-white shadow-lg">
|
|
255
|
+
<div className="flex flex-col items-center justify-center m-2 min-w-[200px] px-4">
|
|
256
|
+
<p className="text-lg whitespace-pre-wrap">
|
|
257
|
+
{constructInputWithSpecialExpressionList(draggedValue).map(
|
|
258
|
+
(inputPart, index) => (
|
|
259
|
+
<span
|
|
260
|
+
key={index}
|
|
261
|
+
className={`${inputPart.isBold ? "font-bold" : ""} ${
|
|
262
|
+
inputPart.isUnderline ? "underline" : ""
|
|
263
|
+
}`}
|
|
264
|
+
>
|
|
265
|
+
{inputPart.isEquation ? (
|
|
266
|
+
<span className="text-xl">
|
|
267
|
+
<InlineMath math={inputPart.value} />
|
|
268
|
+
</span>
|
|
269
|
+
) : (
|
|
270
|
+
inputPart.value
|
|
271
|
+
)}
|
|
272
|
+
</span>
|
|
273
|
+
)
|
|
274
|
+
)}
|
|
275
|
+
</p>
|
|
276
|
+
</div>
|
|
277
|
+
</div>
|
|
278
|
+
) : (
|
|
279
|
+
<div className="border-catchup-blue border-2 rounded-catchup-xlarge bg-white shadow-lg">
|
|
280
|
+
<ShowMaterialMediaByContentType
|
|
281
|
+
key={`${uniqueValue}-drag-touch`}
|
|
282
|
+
contentType={contentMap.type}
|
|
283
|
+
src={draggedValue}
|
|
284
|
+
canFullScreen={false}
|
|
285
|
+
/>
|
|
286
|
+
</div>
|
|
287
|
+
)}
|
|
288
|
+
</div>
|
|
289
|
+
)}
|
|
290
|
+
|
|
118
291
|
{filteredMaterialList.length > 0 ? (
|
|
119
292
|
<>
|
|
120
293
|
<div
|
|
@@ -122,84 +295,68 @@ const MatchingActivityMaterialContent = ({
|
|
|
122
295
|
className="flex-shrink-0 flex flex-row gap-x-4 gap-y-4 overflow-x-auto py-2"
|
|
123
296
|
>
|
|
124
297
|
{filteredMaterialList.map((materialValue, index) => (
|
|
125
|
-
<
|
|
298
|
+
<div
|
|
126
299
|
key={index}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
: "h-catchup-activity-media-box-item"
|
|
139
|
-
} flex flex-col items-center justify-center border-2 rounded-catchup-xlarge cursor-pointer transition-all duration-300`}
|
|
140
|
-
onMouseDown={() => {
|
|
141
|
-
if (checkCanAnswerQuestion()) {
|
|
142
|
-
setSelectedValue(materialValue);
|
|
143
|
-
}
|
|
144
|
-
}}
|
|
145
|
-
onTouchEnd={() => {
|
|
146
|
-
if (checkCanAnswerQuestion()) {
|
|
147
|
-
setSelectedValue(materialValue);
|
|
148
|
-
}
|
|
149
|
-
}}
|
|
150
|
-
onMouseUp={() => {
|
|
151
|
-
if (checkCanAnswerQuestion()) {
|
|
152
|
-
setSelectedValue(null);
|
|
153
|
-
}
|
|
154
|
-
}}
|
|
155
|
-
onTouchStart={() => {
|
|
156
|
-
if (checkCanAnswerQuestion()) {
|
|
157
|
-
setSelectedValue(null);
|
|
158
|
-
}
|
|
159
|
-
}}
|
|
160
|
-
>
|
|
161
|
-
{contentMap.type === "TEXT" ? (
|
|
162
|
-
<div className="flex flex-col items-center justify-center m-2 min-w-[200px] overflow-y-auto px-4">
|
|
163
|
-
<p className="text-lg whitespace-pre-wrap">
|
|
164
|
-
{constructInputWithSpecialExpressionList(
|
|
165
|
-
materialValue
|
|
166
|
-
).map((inputPart, index) => (
|
|
167
|
-
<span
|
|
168
|
-
key={index}
|
|
169
|
-
className={`${
|
|
170
|
-
inputPart.isBold ? "font-bold" : ""
|
|
171
|
-
} ${inputPart.isUnderline ? "underline" : ""}`}
|
|
172
|
-
>
|
|
173
|
-
{inputPart.isEquation ? (
|
|
174
|
-
<span className="text-xl">
|
|
175
|
-
<InlineMath math={inputPart.value} />
|
|
176
|
-
</span>
|
|
177
|
-
) : (
|
|
178
|
-
inputPart.value
|
|
179
|
-
)}
|
|
180
|
-
</span>
|
|
181
|
-
))}
|
|
182
|
-
</p>
|
|
183
|
-
</div>
|
|
184
|
-
) : (
|
|
185
|
-
<ShowMaterialMediaByContentType
|
|
186
|
-
key={`${uniqueValue}-${index}`}
|
|
187
|
-
contentType={contentMap.type}
|
|
188
|
-
src={materialValue}
|
|
189
|
-
canFullScreen={true}
|
|
190
|
-
/>
|
|
191
|
-
)}
|
|
192
|
-
</div>
|
|
300
|
+
ref={draggedValue === materialValue ? dragElementRef : null}
|
|
301
|
+
className={`${
|
|
302
|
+
draggedValue === materialValue
|
|
303
|
+
? "opacity-40"
|
|
304
|
+
: selectedValue === materialValue
|
|
305
|
+
? "ring-2 ring-blue-500"
|
|
306
|
+
: "opacity-100"
|
|
307
|
+
} transition-all duration-200`}
|
|
308
|
+
onMouseDown={(e) => handleMouseDown(e, materialValue)}
|
|
309
|
+
onTouchStart={(e) =>
|
|
310
|
+
handleTouchStart(e, materialValue, e.currentTarget)
|
|
193
311
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
selectedValue
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
312
|
+
onTouchMove={handleTouchMove}
|
|
313
|
+
onTouchEnd={handleTouchEnd}
|
|
314
|
+
>
|
|
315
|
+
<div
|
|
316
|
+
className={`${
|
|
317
|
+
selectedValue === materialValue
|
|
318
|
+
? "border-catchup-blue"
|
|
319
|
+
: "border-catchup-lighter-gray"
|
|
320
|
+
} ${
|
|
321
|
+
contentMap.type === "TEXT"
|
|
322
|
+
? "h-catchup-activity-text-box-item"
|
|
323
|
+
: "h-catchup-activity-media-box-item"
|
|
324
|
+
} flex flex-col items-center justify-center border-2 rounded-catchup-xlarge cursor-pointer transition-all duration-300`}
|
|
325
|
+
onClick={() => handleSelectItem(materialValue)}
|
|
326
|
+
>
|
|
327
|
+
{contentMap.type === "TEXT" ? (
|
|
328
|
+
<div className="flex flex-col items-center justify-center m-2 min-w-[200px] overflow-y-auto px-4">
|
|
329
|
+
<p className="text-lg whitespace-pre-wrap">
|
|
330
|
+
{constructInputWithSpecialExpressionList(
|
|
331
|
+
materialValue
|
|
332
|
+
).map((inputPart, index) => (
|
|
333
|
+
<span
|
|
334
|
+
key={index}
|
|
335
|
+
className={`${
|
|
336
|
+
inputPart.isBold ? "font-bold" : ""
|
|
337
|
+
} ${inputPart.isUnderline ? "underline" : ""}`}
|
|
338
|
+
>
|
|
339
|
+
{inputPart.isEquation ? (
|
|
340
|
+
<span className="text-xl">
|
|
341
|
+
<InlineMath math={inputPart.value} />
|
|
342
|
+
</span>
|
|
343
|
+
) : (
|
|
344
|
+
inputPart.value
|
|
345
|
+
)}
|
|
346
|
+
</span>
|
|
347
|
+
))}
|
|
348
|
+
</p>
|
|
349
|
+
</div>
|
|
350
|
+
) : (
|
|
351
|
+
<ShowMaterialMediaByContentType
|
|
352
|
+
key={`${uniqueValue}-${index}`}
|
|
353
|
+
contentType={contentMap.type}
|
|
354
|
+
src={materialValue}
|
|
355
|
+
canFullScreen={true}
|
|
356
|
+
/>
|
|
357
|
+
)}
|
|
358
|
+
</div>
|
|
359
|
+
</div>
|
|
203
360
|
))}
|
|
204
361
|
</div>
|
|
205
362
|
<div className="flex-shrink-0">
|
|
@@ -260,11 +417,15 @@ const MatchingActivityMaterialContent = ({
|
|
|
260
417
|
<div className="mx-4 w-[2px] bg-catchup-lighter-gray"></div>
|
|
261
418
|
<div className="flex-1">
|
|
262
419
|
<div
|
|
420
|
+
data-matching-drop-zone={answerMapKey}
|
|
421
|
+
onMouseEnter={() =>
|
|
422
|
+
draggedValue && setDropTargetKey(answerMapKey)
|
|
423
|
+
}
|
|
424
|
+
onMouseLeave={() => setDropTargetKey(null)}
|
|
425
|
+
onClick={() => handleDropZoneClick(answerMapKey)}
|
|
263
426
|
className={`${
|
|
264
|
-
|
|
265
|
-
?
|
|
266
|
-
? "bg-catchup-light-blue"
|
|
267
|
-
: "bg-catchup-light-blue opacity-40"
|
|
427
|
+
dropTargetKey === answerMapKey
|
|
428
|
+
? "bg-catchup-light-blue ring-2 ring-blue-400"
|
|
268
429
|
: ""
|
|
269
430
|
} ${
|
|
270
431
|
contentMap.type === "TEXT"
|
|
@@ -279,71 +440,56 @@ const MatchingActivityMaterialContent = ({
|
|
|
279
440
|
? "border-catchup-red"
|
|
280
441
|
: "border-catchup-blue"
|
|
281
442
|
}`}
|
|
282
|
-
onClick={() => {
|
|
283
|
-
if (checkCanAnswerQuestion()) {
|
|
284
|
-
setSelectedValue(null);
|
|
285
|
-
}
|
|
286
|
-
}}
|
|
287
443
|
>
|
|
288
|
-
<
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
<ShowMaterialMediaByContentType
|
|
331
|
-
key={`${uniqueValue}-${index}`}
|
|
332
|
-
contentType={contentMap.type}
|
|
333
|
-
src={answerMap[answerMapKey]}
|
|
334
|
-
canFullScreen={false}
|
|
335
|
-
/>
|
|
336
|
-
)}
|
|
337
|
-
</div>
|
|
338
|
-
}
|
|
339
|
-
/>
|
|
444
|
+
<div
|
|
445
|
+
className="h-full flex-1 flex flex-row items-center justify-center px-4"
|
|
446
|
+
onClick={(e) => {
|
|
447
|
+
e.stopPropagation();
|
|
448
|
+
if (checkCanAnswerQuestion() && answerMap[answerMapKey]) {
|
|
449
|
+
onChange(answer, answerMapKey, null);
|
|
450
|
+
setSelectedValue(null);
|
|
451
|
+
}
|
|
452
|
+
}}
|
|
453
|
+
>
|
|
454
|
+
{answerMap[answerMapKey] ? (
|
|
455
|
+
contentMap.type === "TEXT" ? (
|
|
456
|
+
<p className="text-lg whitespace-pre-wrap">
|
|
457
|
+
{constructInputWithSpecialExpressionList(
|
|
458
|
+
answerMap[answerMapKey]
|
|
459
|
+
).map((inputPart, index) => (
|
|
460
|
+
<span
|
|
461
|
+
key={index}
|
|
462
|
+
className={`${
|
|
463
|
+
inputPart.isBold ? "font-bold" : ""
|
|
464
|
+
} ${inputPart.isUnderline ? "underline" : ""}`}
|
|
465
|
+
>
|
|
466
|
+
{inputPart.isEquation ? (
|
|
467
|
+
<span className="text-xl">
|
|
468
|
+
<InlineMath math={inputPart.value} />
|
|
469
|
+
</span>
|
|
470
|
+
) : (
|
|
471
|
+
inputPart.value
|
|
472
|
+
)}
|
|
473
|
+
</span>
|
|
474
|
+
))}
|
|
475
|
+
</p>
|
|
476
|
+
) : (
|
|
477
|
+
<ShowMaterialMediaByContentType
|
|
478
|
+
key={`${uniqueValue}-${index}`}
|
|
479
|
+
contentType={contentMap.type}
|
|
480
|
+
src={answerMap[answerMapKey]}
|
|
481
|
+
canFullScreen={false}
|
|
482
|
+
/>
|
|
483
|
+
)
|
|
484
|
+
) : null}
|
|
485
|
+
</div>
|
|
340
486
|
</div>
|
|
341
487
|
</div>
|
|
342
488
|
</div>
|
|
343
489
|
);
|
|
344
490
|
})}
|
|
345
491
|
</div>
|
|
346
|
-
|
|
492
|
+
</div>
|
|
347
493
|
);
|
|
348
494
|
};
|
|
349
495
|
|