class AIDialog extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.partnerVideo = null;
this.userVideo = null;
this.mediaStream = null;
this.peerConnection = null;
this.aiMessages = [];
this.userMessages = [];
this.dialogAnalysis = null;
}
connectedCallback() {
this.shadowRoot.innerHTML = `
Practice conversational skills with our AI partner. The system will analyze your performance.
Dialog Analysis
Fluency
0%
Vocabulary
0%
Pronunciation
0%
Feedback:
Complete a conversation to receive feedback.
`;
this.partnerVideo = this.shadowRoot.getElementById('partnerVideo');
this.userVideo = this.shadowRoot.getElementById('userVideo');
this.startBtn = this.shadowRoot.getElementById('startBtn');
this.endBtn = this.shadowRoot.getElementById('endBtn');
this.analysisSection = this.shadowRoot.getElementById('analysis');
this.setupEventListeners();
}
setupEventListeners() {
this.startBtn.addEventListener('click', () => this.startConversation());
this.endBtn.addEventListener('click', () => this.endConversation());
}
async startConversation() {
try {
// Start user media
this.mediaStream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
this.userVideo.srcObject = this.mediaStream;
// Initialize WebRTC connection (simplified for demo)
this.peerConnection = new RTCPeerConnection();
this.mediaStream.getTracks().forEach(track => {
this.peerConnection.addTrack(track, this.mediaStream);
});
// Simulate AI partner video (in real app this would be WebRTC stream)
this.partnerVideo.src = 'https://static.photos/people/640x360/1';
this.startBtn.disabled = true;
this.endBtn.disabled = false;
// Start conversation with AI
this.simulateAIDialog();
} catch (error) {
console.error('Error starting conversation:', error);
alert('Could not access camera/microphone. Please check permissions.');
}
}
async endConversation() {
// Stop media tracks
if (this.mediaStream) {
this.mediaStream.getTracks().forEach(track => track.stop());
}
// Close WebRTC connection
if (this.peerConnection) {
this.peerConnection.close();
}
this.userVideo.srcObject = null;
this.partnerVideo.src = null;
this.startBtn.disabled = false;
this.endBtn.disabled = true;
// Analyze dialog
this.analyzeDialog();
}
simulateAIDialog() {
// Simulate AI responses (in real app this would use GPT API)
const aiResponses = [
"Hello! How are you today?",
"That's interesting. Tell me more about that.",
"I understand how you feel. What would you like to discuss next?",
"Your pronunciation is improving! Keep practicing.",
"Let's try to use some new vocabulary words."
];
let responseIndex = 0;
this.aiMessages = [];
const aiInterval = setInterval(() => {
if (!this.endBtn.disabled) {
const response = aiResponses[responseIndex % aiResponses.length];
this.aiMessages.push(response);
responseIndex++;
// Update UI with AI response
const feedback = this.shadowRoot.getElementById('feedbackText');
feedback.textContent = `AI: ${response}`;
} else {
clearInterval(aiInterval);
}
}, 8000);
}
analyzeDialog() {
// Simulate dialog analysis (in real app this would use speech-to-text and NLP)
this.dialogAnalysis = {
fluency: Math.floor(Math.random() * 30) + 70,
vocabulary: Math.floor(Math.random() * 30) + 70,
pronunciation: Math.floor(Math.random() * 30) + 70,
feedback: "Good job! You showed improvement in fluency. Try to use more complex sentences next time."
};
// Display analysis
this.analysisSection.style.display = 'block';
this.shadowRoot.getElementById('fluencyScore').textContent = `${this.dialogAnalysis.fluency}%`;
this.shadowRoot.getElementById('fluencyBar').style.width = `${this.dialogAnalysis.fluency}%`;
this.shadowRoot.getElementById('vocabularyScore').textContent = `${this.dialogAnalysis.vocabulary}%`;
this.shadowRoot.getElementById('vocabularyBar').style.width = `${this.dialogAnalysis.vocabulary}%`;
this.shadowRoot.getElementById('pronunciationScore').textContent = `${this.dialogAnalysis.pronunciation}%`;
this.shadowRoot.getElementById('pronunciationBar').style.width = `${this.dialogAnalysis.pronunciation}%`;
this.shadowRoot.getElementById('feedbackText').textContent = this.dialogAnalysis.feedback;
}
}
customElements.define('ai-dialog', AIDialog);