py-learn / src /app /findword /findword.component.ts
Anupriya
shared button component
04830fa
import { Component, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';
import { FindwordService } from '../findword/findword.service';
import { Router } from '@angular/router';
import { HeaderComponent } from '../shared/header/header.component';
import { ButtonComponent } from '../shared/button/button.component';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-findword',
templateUrl: './findword.component.html',
styleUrl: './findword.component.css',
standalone: true,
imports: [ButtonComponent, CommonModule, FormsModule, HeaderComponent]
})
export class FindwordComponent {
@ViewChild('audioPlayer', { static: false }) audioPlayer?: ElementRef<HTMLAudioElement>;
@ViewChild('audioPlayer') audioRef!: ElementRef<HTMLAudioElement>;
step: number = 1;
progress: number = 0;
audioUrl: string | null = null;
userInput: string = '';
validationMessage: string = '';
isCorrect: boolean = false;
isLoading: boolean = false;
attemptsLeft: number = 3;
correctWord: string | null = null;
isGenerateDisabled: boolean = false;
wordMeaning: string | null = null;
wordSentence: string | null = null;
showMeaning: boolean = false;
showSentence: boolean = false;
isPopupVisible: boolean = false;
popupMessage: string = '';
audioFinished: boolean = false;
canSubmit: boolean = false;
isPlaying: boolean = false;
currentTimeDisplay = '0:00';
durationDisplay = '0:00';
constructor(
private findwordService: FindwordService,
private cd: ChangeDetectorRef,
private router: Router
) { }
fetchAudio() {
this.isLoading = true;
this.correctWord = null;
this.attemptsLeft = 3;
this.validationMessage = '';
this.userInput = '';
this.isGenerateDisabled = true;
this.wordMeaning = null;
this.wordSentence = null;
this.showMeaning = true;
this.showSentence = true;
this.audioFinished = false;
this.canSubmit = false;
console.log("🎀 Fetching new vocabulary...");
this.findwordService.fetchAudio().subscribe((response: any) => {
if (!response || !response.audio_file_path || !response.word) {
console.error("❌ Invalid response from backend:", response);
return;
}
this.correctWord = response.word.trim();
this.wordMeaning = response.meaning;
this.wordSentence = response.sentence;
console.log("βœ… Correct Word Set:", this.correctWord);
this.audioUrl = this.findwordService.buildAssetUrl(response.audio_file_path);
this.cd.detectChanges();
setTimeout(() => {
if (this.audioPlayer && this.audioPlayer.nativeElement) {
console.log("πŸ”„ Loading new audio...");
this.audioPlayer.nativeElement.load();
this.audioPlayer.nativeElement.onended = () => {
console.log("πŸ”Š Audio finished playing");
this.audioFinished = true;
};
} else {
console.error("❌ Audio player not found!");
}
}, 500);
}, error => {
console.error('❌ Error fetching audio:', error);
this.isLoading = false;
});
}
onInputChange(): void {
this.canSubmit = this.userInput.trim().length > 0;
}
startGame(): void {
this.resetStep2State();
this.step = 2;
this.progress = 0;
}
getMeaning() {
if (this.wordMeaning) {
this.popupMessage = `Meaning: ${this.wordMeaning}`;
} else {
this.popupMessage = 'Meaning not available for this word.';
}
this.isPopupVisible = true;
}
getSentence() {
if (this.wordSentence) {
this.popupMessage = `Example Sentence: ${this.wordSentence}`;
} else {
this.popupMessage = 'Example sentence not available for this word.';
}
this.isPopupVisible = true;
}
validateWord() {
if (this.attemptsLeft <= 0) {
this.showMeaning = true;
this.showSentence = true;
return;
}
console.log(`πŸ“ Validating answer: ${this.userInput} (Attempts left: ${this.attemptsLeft})`);
if (!this.correctWord) {
console.error("❌ Error: No correct word set for validation!");
this.validationMessage = 'Error validating word: Missing correct word.';
this.showMeaning = true;
this.showSentence = true;
return;
}
const requestData = {
user_input: this.userInput.trim(),
correct_word: this.correctWord.trim().replace('.', '')
};
console.log("πŸ“€ Sending validation request:", requestData);
this.findwordService.validateWord(this.userInput, this.correctWord).subscribe(response => {
console.log("πŸ“₯ Validation Response:", response);
if (response.status === 'success') {
this.validationMessage = "βœ… Correct!";
this.isCorrect = true;
this.ui.pulseOk = true;
setTimeout(() => (this.ui.pulseOk = false), 1200);
this.attemptsLeft = 0;
this.popupMessage = this.validationMessage;
this.isGenerateDisabled = true;
} else {
this.attemptsLeft--;
if (this.attemptsLeft === 0) {
this.validationMessage = `❌ Incorrect! The correct word was '${this.correctWord}'.`;
this.correctWord = response.correct_word;
this.isGenerateDisabled = true;
this.showMeaning = true;
this.showSentence = true;
} else {
this.validationMessage = `❌ Incorrect! You have ${this.attemptsLeft} attempt(s) left.`;
}
this.isCorrect = false;
this.ui.shake = true;
setTimeout(() => (this.ui.shake = false), 400);
}
}, error => {
console.error("❌ Validation API Error:", error);
this.validationMessage = 'Error validating word: API failed.';
});
}
onAudioReady() {
console.log("🎧 Audio is ready, trying to play...");
if (this.audioPlayer) {
this.audioPlayer.nativeElement.play().then(() => {
console.log("βœ… Audio played successfully.");
}).catch((error: any) => {
console.error("❌ Play failed:", error);
});
}
}
pauseAudio() {
if (this.audioPlayer?.nativeElement) {
this.audioPlayer.nativeElement.pause();
}
}
playAudio() {
if (this.audioPlayer?.nativeElement) {
this.audioPlayer.nativeElement.play();
}
console.log("🎡 Play button clicked. Trying to play audio:", this.audioUrl);
if (this.audioPlayer && this.audioPlayer.nativeElement) {
this.audioPlayer.nativeElement.play().then(() => {
console.log("βœ… Audio played successfully.");
}).catch((error: any) => {
console.error("❌ Manual play failed:", error);
});
} else {
console.error("❌ Audio player not found!");
}
}
nextQuestion() {
this.isGenerateDisabled = false;
this.audioUrl = null;
this.userInput = '';
this.validationMessage = '';
this.attemptsLeft = 3;
this.correctWord = null;
this.showMeaning = false;
this.showSentence = false;
this.isCorrect = false;
this.isLoading = false;
this.fetchAudio();
}
goToHome() {
this.router.navigate(['/home']);
}
goBack(): void {
const audio = this.audioRef?.nativeElement;
if (audio) { try { audio.pause(); } catch { } }
this.step = 1;
}
showMeaningPanel() {
if (this.wordMeaning) {
this.popupMessage = `πŸ“– Meaning: ${this.wordMeaning}`;
} else {
this.popupMessage = 'Meaning not available for this word.';
}
this.isPopupVisible = true;
this.ui.showMeaning = true;
this.ui.showExample = false;
this.ui.meaningText = (this as any).meaningText || (this as any).meaning || '';
}
showSentencePanel() {
if (this.wordSentence) {
this.popupMessage = `✍ Example Sentence: ${this.wordSentence}`;
} else {
this.popupMessage = 'Example sentence not available for this word.';
}
this.isPopupVisible = true;
this.ui.showExample = true;
this.ui.showMeaning = false;
this.ui.exampleText = (this as any).exampleText || (this as any).sentence || (this as any).exampleSentence || '';
}
closePopup() {
console.log("❌ Closing popup...");
this.isPopupVisible = false;
}
get isMeaningButtonDisabled(): boolean {
return !(this.isCorrect || this.attemptsLeft <= 2);
}
get isExampleButtonDisabled(): boolean {
return !(this.isCorrect || this.attemptsLeft === 0);
}
bars = Array.from({ length: 12 });
togglePlayback(): void {
const audio = this.audioRef?.nativeElement;
if (!audio || !this.audioUrl) { return; }
if (audio.paused) {
audio.play().then(() => {
this.isPlaying = true;
}).catch(() => {
this.isPlaying = false;
});
} else {
audio.pause();
this.isPlaying = false;
}
}
onLoadedMeta(): void {
const audio = this.audioRef?.nativeElement;
if (!audio) { return; }
this.durationDisplay = this.formatTime(audio.duration);
this.currentTimeDisplay = '0:00';
this.progress = 0;
this.isPlaying = false;
if (typeof this.audioFinished !== 'undefined') {
this.audioFinished = false;
}
}
onTimeUpdate(): void {
const audio = this.audioRef?.nativeElement;
if (!audio) { return; }
const current = isFinite(audio.currentTime) ? audio.currentTime : 0;
const dur = isFinite(audio.duration) ? audio.duration : 0.00001;
this.currentTimeDisplay = this.formatTime(current);
this.progress = Math.min(100, (current / dur) * 100);
}
onAudioEnded(): void {
this.isPlaying = false;
this.progress = 100;
if (typeof this.audioFinished !== 'undefined') {
this.audioFinished = true;
}
}
private formatTime(sec: number): string {
if (!isFinite(sec)) { return '0:00'; }
const m = Math.floor(sec / 60);
const s = Math.floor(sec % 60);
return `${m}:${s.toString().padStart(2, '0')}`;
}
private resetPlayerUI(): void {
this.isPlaying = false;
this.progress = 0;
this.currentTimeDisplay = '0:00';
this.durationDisplay = '0:00';
}
ui = {
pulseOk: false,
shake: false,
showMeaning: false,
showExample: false,
meaningText: '',
exampleText: ''
};
private resetStep2State(): void {
const audio = this.audioRef?.nativeElement;
if (audio) {
try { audio.pause(); } catch { }
audio.currentTime = 0;
}
this.audioUrl = null;
this.isPlaying = false;
this.progress = 0;
this.currentTimeDisplay = '0:00';
this.durationDisplay = '0:00';
this.userInput = '';
this.validationMessage = '';
this.isCorrect = false;
this.attemptsLeft = 3;
this.canSubmit = false;
this.audioFinished = false;
this.correctWord = null;
this.wordMeaning = null;
this.wordSentence = null;
this.isGenerateDisabled = false;
this.isLoading = false;
this.showMeaning = false;
this.showSentence = false;
if (this.ui) {
this.ui.pulseOk = false;
this.ui.shake = false;
this.ui.showMeaning = false;
this.ui.showExample = false;
this.ui.meaningText = '';
this.ui.exampleText = '';
}
this.isPopupVisible = false;
this.popupMessage = '';
}
closeToStart(): void {
const audio = this.audioRef?.nativeElement;
if (audio) {
try { audio.pause(); } catch { }
audio.currentTime = 0;
}
this.isPlaying = false;
this.audioUrl = null;
this.userInput = '';
this.validationMessage = '';
this.isCorrect = false;
this.attemptsLeft = 3;
this.canSubmit = false;
this.audioFinished = false;
this.isGenerateDisabled = false;
this.isLoading = false;
this.showMeaning = false;
this.showSentence = false;
this.isPopupVisible = false;
this.popupMessage = '';
this.step = 1;
}
}