Update src/app/generate-questions/generate-questions.component.ts
Browse files
src/app/generate-questions/generate-questions.component.ts
CHANGED
|
@@ -95,8 +95,6 @@ export class GenerateQuestionsComponent {
|
|
| 95 |
return `${percent}%`;
|
| 96 |
}
|
| 97 |
|
| 98 |
-
|
| 99 |
-
|
| 100 |
generateQuestions() {
|
| 101 |
this.hints = [];
|
| 102 |
this.isQuestionsGenerated = false;
|
|
@@ -121,8 +119,10 @@ export class GenerateQuestionsComponent {
|
|
| 121 |
(response) => {
|
| 122 |
console.log("Response from backend:", response);
|
| 123 |
|
| 124 |
-
|
| 125 |
-
|
|
|
|
|
|
|
| 126 |
console.log("Raw Questions:", rawQuestions);
|
| 127 |
this.isQuestionsGenerated = true;
|
| 128 |
|
|
@@ -142,11 +142,11 @@ export class GenerateQuestionsComponent {
|
|
| 142 |
const afterBlankRaw = (match[2] ?? ""); // text after the blank
|
| 143 |
const correctAnswer = (match[3] ?? "").trim(); // answer in parentheses
|
| 144 |
|
| 145 |
-
//
|
| 146 |
const afterBlankClean = afterBlankRaw
|
| 147 |
-
.replace(/^[_-]+/, "")
|
| 148 |
-
.replace(/^\s+/, " ")
|
| 149 |
-
.replace(/\s{2,}/g, " ");
|
| 150 |
|
| 151 |
if (questionText && correctAnswer) {
|
| 152 |
this.questionsWithAnswers.push({
|
|
@@ -160,12 +160,10 @@ export class GenerateQuestionsComponent {
|
|
| 160 |
|
| 161 |
// Build renderable questions (parts before/after the blank)
|
| 162 |
this.questions = this.questionsWithAnswers.map((q, index) => {
|
| 163 |
-
// NEW: normalize any odd spacing around the marker
|
| 164 |
const normalized = q.question.replace(/\s*_{3,}\s*/g, "_______");
|
| 165 |
const parts = normalized.split("_______");
|
| 166 |
|
| 167 |
if (parts.length === 2) {
|
| 168 |
-
// NEW: remove any stray underscores touching the gap
|
| 169 |
parts[0] = parts[0].replace(/_+$/, "").trim();
|
| 170 |
parts[1] = parts[1].replace(/^_+/, "").trim();
|
| 171 |
}
|
|
@@ -199,8 +197,6 @@ export class GenerateQuestionsComponent {
|
|
| 199 |
);
|
| 200 |
}
|
| 201 |
|
| 202 |
-
|
| 203 |
-
|
| 204 |
resetTopic() {
|
| 205 |
this.topic = "";
|
| 206 |
this.questions = [];
|
|
@@ -236,7 +232,6 @@ export class GenerateQuestionsComponent {
|
|
| 236 |
this.showCountdown = [];
|
| 237 |
this.stopGlobalCountdown();
|
| 238 |
this.stopOverlay()
|
| 239 |
-
|
| 240 |
}
|
| 241 |
|
| 242 |
areAllAnswersFilled(): boolean {
|
|
@@ -249,16 +244,11 @@ export class GenerateQuestionsComponent {
|
|
| 249 |
this.isResetDisabled = false;
|
| 250 |
}
|
| 251 |
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
// Hint icon one-time flags (ADD THESE)
|
| 255 |
showHintIcon: boolean = false; // controls rendering of the “i” button
|
| 256 |
hasShownHintIcon: boolean = false; // remembers if it was shown once
|
| 257 |
-
|
| 258 |
-
// If you call toggleHintMenu(), also ensure this exists:
|
| 259 |
isHintMenuVisible: boolean = false; // remove if you already have it
|
| 260 |
|
| 261 |
-
|
| 262 |
checkAllAnswers() {
|
| 263 |
this.isChecked = true;
|
| 264 |
this.isValidationInProgress = true;
|
|
@@ -382,7 +372,6 @@ export class GenerateQuestionsComponent {
|
|
| 382 |
}
|
| 383 |
|
| 384 |
// --- ONE-TIME “i” icon reveal right after the first validation ---
|
| 385 |
-
// Show once if there are any hints OR there were wrong attempts this cycle.
|
| 386 |
const hasAnyHint = Array.isArray(this.hints) && this.hints.some(h => !!h && h.trim() !== "");
|
| 387 |
const shouldRevealIconOnce = hasAnyHint || hadFirstAttemptWrong || hadSecondAttemptWrong;
|
| 388 |
|
|
@@ -431,8 +420,6 @@ export class GenerateQuestionsComponent {
|
|
| 431 |
);
|
| 432 |
}
|
| 433 |
|
| 434 |
-
|
| 435 |
-
|
| 436 |
isLastLevel(): boolean {
|
| 437 |
return (
|
| 438 |
this.currentDifficulty ===
|
|
@@ -558,7 +545,6 @@ export class GenerateQuestionsComponent {
|
|
| 558 |
this.resetTopic();
|
| 559 |
}
|
| 560 |
|
| 561 |
-
|
| 562 |
selectTopic(suggestion: string): void {
|
| 563 |
this.topic = suggestion;
|
| 564 |
this.showSuggestions = false;
|
|
@@ -602,7 +588,6 @@ export class GenerateQuestionsComponent {
|
|
| 602 |
if (this.isHintMenuVisible) this.showHintIcon = false; // hide after first use
|
| 603 |
}
|
| 604 |
|
| 605 |
-
|
| 606 |
onInput(event: any, index: number) {
|
| 607 |
const value = event.target.value;
|
| 608 |
const filteredValue = value.replace(/[^a-zA-Z]/g, "");
|
|
@@ -610,9 +595,6 @@ export class GenerateQuestionsComponent {
|
|
| 610 |
event.target.value = filteredValue;
|
| 611 |
}
|
| 612 |
|
| 613 |
-
|
| 614 |
-
|
| 615 |
-
|
| 616 |
//timer implemetation
|
| 617 |
|
| 618 |
// --- Countdown state (per question) ---
|
|
@@ -628,9 +610,6 @@ export class GenerateQuestionsComponent {
|
|
| 628 |
|
| 629 |
overlayCaption = '';
|
| 630 |
|
| 631 |
-
|
| 632 |
-
|
| 633 |
-
|
| 634 |
private beginResetCountdown(index: number, seconds: number = this.COUNTDOWN_SECS): void {
|
| 635 |
// avoid duplicate timers for the same question
|
| 636 |
if (this.countdownTimers[index]) { return; }
|
|
@@ -648,23 +627,23 @@ export class GenerateQuestionsComponent {
|
|
| 648 |
}
|
| 649 |
|
| 650 |
/** Stop timer, hide badge, clear the wrong input, and allow retry. */
|
| 651 |
-
|
| 652 |
-
|
| 653 |
-
|
| 654 |
-
|
| 655 |
-
|
| 656 |
-
|
|
|
|
| 657 |
|
| 658 |
-
|
| 659 |
-
|
| 660 |
|
| 661 |
-
|
| 662 |
-
|
| 663 |
|
| 664 |
-
|
| 665 |
-
|
| 666 |
-
|
| 667 |
-
}
|
| 668 |
|
| 669 |
private startGlobalCountdown(): void {
|
| 670 |
if (this.globalCountdownActive) return; // prevent duplicates
|
|
@@ -732,24 +711,10 @@ export class GenerateQuestionsComponent {
|
|
| 732 |
this.ringDashoffset = this.ringCircumference;
|
| 733 |
}
|
| 734 |
|
| 735 |
-
|
| 736 |
-
|
| 737 |
-
|
| 738 |
-
|
| 739 |
ringRadius = 90;
|
| 740 |
ringCircumference = 2 * Math.PI * this.ringRadius;
|
| 741 |
ringDashoffset = this.ringCircumference;
|
| 742 |
|
| 743 |
-
|
| 744 |
private overlayTicker: any = null;
|
| 745 |
private overlayEndTs = 0;
|
| 746 |
-
|
| 747 |
-
|
| 748 |
-
|
| 749 |
-
|
| 750 |
-
|
| 751 |
-
|
| 752 |
-
|
| 753 |
}
|
| 754 |
-
|
| 755 |
-
|
|
|
|
| 95 |
return `${percent}%`;
|
| 96 |
}
|
| 97 |
|
|
|
|
|
|
|
| 98 |
generateQuestions() {
|
| 99 |
this.hints = [];
|
| 100 |
this.isQuestionsGenerated = false;
|
|
|
|
| 119 |
(response) => {
|
| 120 |
console.log("Response from backend:", response);
|
| 121 |
|
| 122 |
+
// --- Minimal change: accept new shape { text } and fall back to old generations[0].text ---
|
| 123 |
+
const rawQuestions = (response?.text ?? response?.generations?.[0]?.text ?? '').trim();
|
| 124 |
+
|
| 125 |
+
if (rawQuestions) {
|
| 126 |
console.log("Raw Questions:", rawQuestions);
|
| 127 |
this.isQuestionsGenerated = true;
|
| 128 |
|
|
|
|
| 142 |
const afterBlankRaw = (match[2] ?? ""); // text after the blank
|
| 143 |
const correctAnswer = (match[3] ?? "").trim(); // answer in parentheses
|
| 144 |
|
| 145 |
+
// clean any stray "_" or "-" right after the blank
|
| 146 |
const afterBlankClean = afterBlankRaw
|
| 147 |
+
.replace(/^[_-]+/, "")
|
| 148 |
+
.replace(/^\s+/, " ")
|
| 149 |
+
.replace(/\s{2,}/g, " ");
|
| 150 |
|
| 151 |
if (questionText && correctAnswer) {
|
| 152 |
this.questionsWithAnswers.push({
|
|
|
|
| 160 |
|
| 161 |
// Build renderable questions (parts before/after the blank)
|
| 162 |
this.questions = this.questionsWithAnswers.map((q, index) => {
|
|
|
|
| 163 |
const normalized = q.question.replace(/\s*_{3,}\s*/g, "_______");
|
| 164 |
const parts = normalized.split("_______");
|
| 165 |
|
| 166 |
if (parts.length === 2) {
|
|
|
|
| 167 |
parts[0] = parts[0].replace(/_+$/, "").trim();
|
| 168 |
parts[1] = parts[1].replace(/^_+/, "").trim();
|
| 169 |
}
|
|
|
|
| 197 |
);
|
| 198 |
}
|
| 199 |
|
|
|
|
|
|
|
| 200 |
resetTopic() {
|
| 201 |
this.topic = "";
|
| 202 |
this.questions = [];
|
|
|
|
| 232 |
this.showCountdown = [];
|
| 233 |
this.stopGlobalCountdown();
|
| 234 |
this.stopOverlay()
|
|
|
|
| 235 |
}
|
| 236 |
|
| 237 |
areAllAnswersFilled(): boolean {
|
|
|
|
| 244 |
this.isResetDisabled = false;
|
| 245 |
}
|
| 246 |
|
| 247 |
+
// Hint icon one-time flags
|
|
|
|
|
|
|
| 248 |
showHintIcon: boolean = false; // controls rendering of the “i” button
|
| 249 |
hasShownHintIcon: boolean = false; // remembers if it was shown once
|
|
|
|
|
|
|
| 250 |
isHintMenuVisible: boolean = false; // remove if you already have it
|
| 251 |
|
|
|
|
| 252 |
checkAllAnswers() {
|
| 253 |
this.isChecked = true;
|
| 254 |
this.isValidationInProgress = true;
|
|
|
|
| 372 |
}
|
| 373 |
|
| 374 |
// --- ONE-TIME “i” icon reveal right after the first validation ---
|
|
|
|
| 375 |
const hasAnyHint = Array.isArray(this.hints) && this.hints.some(h => !!h && h.trim() !== "");
|
| 376 |
const shouldRevealIconOnce = hasAnyHint || hadFirstAttemptWrong || hadSecondAttemptWrong;
|
| 377 |
|
|
|
|
| 420 |
);
|
| 421 |
}
|
| 422 |
|
|
|
|
|
|
|
| 423 |
isLastLevel(): boolean {
|
| 424 |
return (
|
| 425 |
this.currentDifficulty ===
|
|
|
|
| 545 |
this.resetTopic();
|
| 546 |
}
|
| 547 |
|
|
|
|
| 548 |
selectTopic(suggestion: string): void {
|
| 549 |
this.topic = suggestion;
|
| 550 |
this.showSuggestions = false;
|
|
|
|
| 588 |
if (this.isHintMenuVisible) this.showHintIcon = false; // hide after first use
|
| 589 |
}
|
| 590 |
|
|
|
|
| 591 |
onInput(event: any, index: number) {
|
| 592 |
const value = event.target.value;
|
| 593 |
const filteredValue = value.replace(/[^a-zA-Z]/g, "");
|
|
|
|
| 595 |
event.target.value = filteredValue;
|
| 596 |
}
|
| 597 |
|
|
|
|
|
|
|
|
|
|
| 598 |
//timer implemetation
|
| 599 |
|
| 600 |
// --- Countdown state (per question) ---
|
|
|
|
| 610 |
|
| 611 |
overlayCaption = '';
|
| 612 |
|
|
|
|
|
|
|
|
|
|
| 613 |
private beginResetCountdown(index: number, seconds: number = this.COUNTDOWN_SECS): void {
|
| 614 |
// avoid duplicate timers for the same question
|
| 615 |
if (this.countdownTimers[index]) { return; }
|
|
|
|
| 627 |
}
|
| 628 |
|
| 629 |
/** Stop timer, hide badge, clear the wrong input, and allow retry. */
|
| 630 |
+
/** Stop timer, hide badge, clear the wrong input, and allow retry. */
|
| 631 |
+
private finishCountdown(index: number): void {
|
| 632 |
+
const t = this.countdownTimers[index]; // FIX: use `this`, not `self`
|
| 633 |
+
if (t) {
|
| 634 |
+
clearInterval(t);
|
| 635 |
+
delete this.countdownTimers[index];
|
| 636 |
+
}
|
| 637 |
|
| 638 |
+
this.showCountdown[index] = false;
|
| 639 |
+
this.countdowns[index] = 0;
|
| 640 |
|
| 641 |
+
// Clear only the wrong answer and allow the learner to try again.
|
| 642 |
+
this.userAnswers[index] = '';
|
| 643 |
|
| 644 |
+
// Turn off the global "checked" flag so inputs are not stuck red.
|
| 645 |
+
this.isChecked = false;
|
| 646 |
+
}
|
|
|
|
| 647 |
|
| 648 |
private startGlobalCountdown(): void {
|
| 649 |
if (this.globalCountdownActive) return; // prevent duplicates
|
|
|
|
| 711 |
this.ringDashoffset = this.ringCircumference;
|
| 712 |
}
|
| 713 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 714 |
ringRadius = 90;
|
| 715 |
ringCircumference = 2 * Math.PI * this.ringRadius;
|
| 716 |
ringDashoffset = this.ringCircumference;
|
| 717 |
|
|
|
|
| 718 |
private overlayTicker: any = null;
|
| 719 |
private overlayEndTs = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 720 |
}
|
|
|
|
|
|