v4: conversational teacher with context memory
This commit is contained in:
parent
f6cce5394a
commit
14a21dbcbe
308
script.js
308
script.js
@ -275,6 +275,7 @@ const levelsData = {
|
||||
// Текущее состояние
|
||||
let currentLevel = null;
|
||||
let chatSessionId = null;
|
||||
let chatHistory = []; // История переписки для контекста
|
||||
|
||||
// DOM элементы
|
||||
const levelsSection = document.getElementById('levels-section');
|
||||
@ -438,6 +439,12 @@ function toggleChat() {
|
||||
teacherChat.classList.toggle('hidden');
|
||||
if (!teacherChat.classList.contains('hidden')) {
|
||||
chatInput.focus();
|
||||
// Если чат открыли впервые - приветствуем
|
||||
if (chatHistory.length === 0) {
|
||||
setTimeout(() => {
|
||||
addMessage('Hi there! 👋 I\'m your English teacher! Let\'s have a conversation! Tell me about yourself - where are you from?', 'teacher');
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -448,26 +455,39 @@ async function sendMessage() {
|
||||
// Добавляем сообщение студента
|
||||
addMessage(text, 'student');
|
||||
chatInput.value = '';
|
||||
sendBtn.disabled = true;
|
||||
|
||||
// Показываем индикатор набора
|
||||
showTypingIndicator();
|
||||
|
||||
try {
|
||||
// Небольшая задержка для естественности
|
||||
await new Promise(resolve => setTimeout(resolve, 600));
|
||||
|
||||
// Получаем ответ от ИИ
|
||||
const response = await askTeacher(text);
|
||||
hideTypingIndicator();
|
||||
addMessage(response, 'teacher');
|
||||
} catch (error) {
|
||||
hideTypingIndicator();
|
||||
addMessage('Извини, я временно недоступен. Попробуй ещё раз!', 'teacher');
|
||||
addMessage('Hmm, I had trouble processing that. Try rephrasing? 😊', 'teacher');
|
||||
console.error('Teacher error:', error);
|
||||
}
|
||||
|
||||
sendBtn.disabled = false;
|
||||
chatInput.focus();
|
||||
}
|
||||
|
||||
function addMessage(text, type) {
|
||||
const messageDiv = document.createElement('div');
|
||||
messageDiv.className = `message ${type}`;
|
||||
messageDiv.innerHTML = `<div class="message-bubble">${text}</div>`;
|
||||
|
||||
// Добавляем аватарки
|
||||
const avatar = type === 'teacher' ? '👨🏫' : '👤';
|
||||
messageDiv.innerHTML = `
|
||||
<div class="message-avatar">${avatar}</div>
|
||||
<div class="message-bubble">${text}</div>
|
||||
`;
|
||||
chatMessages.appendChild(messageDiv);
|
||||
chatMessages.scrollTop = chatMessages.scrollHeight;
|
||||
}
|
||||
@ -494,135 +514,295 @@ function hideTypingIndicator() {
|
||||
if (typing) typing.remove();
|
||||
}
|
||||
|
||||
// Готовые ответы для статической версии (без сервера)
|
||||
// Готовые ответы для статической версии (без сервера) - РАЗГОВОРНЫЙ РЕЖИМ
|
||||
const teacherResponses = {
|
||||
greetings: {
|
||||
keywords: ['hello', 'hi', 'привет', 'здравствуй', 'good morning', 'good afternoon'],
|
||||
keywords: ['hello', 'hi', 'привет', 'здравствуй', 'good morning', 'good afternoon', 'hey'],
|
||||
answers: [
|
||||
'Hello! Great to see you! How can I help you with English today?',
|
||||
'Hi there! Ready to practice English? What would you like to work on?',
|
||||
'Hello! I\'m your English teacher. Ask me anything about grammar, vocabulary, or let\'s just chat!'
|
||||
]
|
||||
'Hello! Great to see you! 😊 How are you today? Tell me in English!',
|
||||
'Hi there! Ready to practice English? What have you been doing lately?',
|
||||
'Hello! I\'m your English teacher. Nice to meet you! What\'s your name?',
|
||||
'Hey! How\'s it going? Did you do anything interesting today?'
|
||||
],
|
||||
followUp: 'Tell me about yourself! Where are you from? What do you like to do?'
|
||||
},
|
||||
thanks: {
|
||||
keywords: ['thank', 'спасибо', 'thanks'],
|
||||
keywords: ['thank', 'спасибо', 'thanks', 'благодарю'],
|
||||
answers: [
|
||||
'You\'re welcome! Keep up the good work! 👍',
|
||||
'Anytime! That\'s what I\'m here for! 😊',
|
||||
'No problem! Feel free to ask more questions!'
|
||||
'You\'re welcome! 😊 You\'re making great progress! Keep it up!',
|
||||
'Anytime! That\'s what I\'m here for! Do you have more questions?',
|
||||
'No problem! I\'m happy to help! What else would you like to learn?'
|
||||
]
|
||||
},
|
||||
howAreYou: {
|
||||
keywords: ['how are you', 'как дела', 'how\'s it going', 'how are things'],
|
||||
answers: [
|
||||
'I\'m great, thank you for asking! 😊 I\'m here helping students learn English. How about you? How was your day?',
|
||||
'Doing well! Excited to practice English with you! What about you? Anything new?'
|
||||
]
|
||||
},
|
||||
name: {
|
||||
keywords: ['what is your name', 'как тебя зовут', 'your name', 'кто ты'],
|
||||
answers: [
|
||||
'I\'m your virtual English teacher! You can call me Teacher. 😊 What\'s YOUR name?',
|
||||
'I\'m your English learning companion! But I\'d love to know YOUR name. What should I call you?'
|
||||
]
|
||||
},
|
||||
help: {
|
||||
keywords: ['help', 'помощь', 'помоги', 'explain', 'объясни'],
|
||||
keywords: ['help', 'помощь', 'помоги', 'explain', 'объясни', 'assist'],
|
||||
answers: [
|
||||
'I can help you with: grammar rules, vocabulary, pronunciation tips, or just conversation practice. What do you need?',
|
||||
'Sure! I can explain grammar, check your sentences, or suggest words. What topic interests you?'
|
||||
'I\'d love to help! 🎯 I can: check your sentences, explain grammar, teach new words, or just chat. What do you prefer?',
|
||||
'Of course! What\'s troubling you? Grammar? Vocabulary? Or maybe you want conversation practice?'
|
||||
]
|
||||
},
|
||||
grammar: {
|
||||
keywords: ['grammar', 'грамматик', 'rule', 'правило', 'tense', 'время'],
|
||||
answers: [
|
||||
'Grammar is important! The key is practice. Start with Present Simple - it\'s the most common tense. Example: "I work every day." Want me to explain more?',
|
||||
'English grammar has 12 tenses, but you only need 5-6 for daily conversation. Which tense would you like to learn?'
|
||||
'Grammar time! 📚 Let me explain simply. Which tense confuses you? Present, Past, or Future?',
|
||||
'Great question! Grammar is like puzzle pieces. Once you get the pattern, it clicks! What specifically?'
|
||||
]
|
||||
},
|
||||
vocabulary: {
|
||||
keywords: ['word', 'слово', 'vocabulary', 'translate', 'перевод', 'meaning'],
|
||||
keywords: ['word', 'слово', 'vocabulary', 'translate', 'перевод', 'meaning', 'значит'],
|
||||
answers: [
|
||||
'Great question! Building vocabulary takes time. Try learning 5-10 new words daily and use them in sentences. What word interests you?',
|
||||
'I can help with translations! Just tell me the word you want to know.'
|
||||
'Vocabulary is key! 🔑 Tell me the word you want to know, or I can teach you a new one!',
|
||||
'I love teaching new words! What topic interests you? Food? Travel? Work? Emotions?'
|
||||
]
|
||||
},
|
||||
practice: {
|
||||
keywords: ['practice', 'практик', 'speak', 'говорить', 'chat', 'болтать'],
|
||||
keywords: ['practice', 'практик', 'speak', 'говорить', 'chat', 'болтать', 'conversation'],
|
||||
answers: [
|
||||
'Let\'s practice! Tell me about your day in English. Don\'t worry about mistakes - I\'ll help you correct them!',
|
||||
'Great! Let\'s have a conversation. What topics interest you? Hobbies, work, travel, movies?'
|
||||
'Awesome! Let\'s chat! 💬 Tell me - what did you do yesterday? Use past tense!',
|
||||
'Perfect! I love conversations! So... what are your hobbies? What do you enjoy doing?'
|
||||
]
|
||||
},
|
||||
mistake: {
|
||||
keywords: ['mistake', 'ошибка', 'wrong', 'correct', 'правильно'],
|
||||
keywords: ['mistake', 'ошибка', 'wrong', 'correct', 'правильно', 'right'],
|
||||
answers: [
|
||||
'Mistakes are how we learn! Don\'t be afraid to make them. Even native speakers make mistakes!',
|
||||
'Good catch! Let me explain the rule so you remember it better.'
|
||||
'Mistakes are GOLD! ✨ They show you\'re trying! Tell me what you\'re unsure about.',
|
||||
'Don\'t worry about mistakes - they\'re part of learning! Even natives make them! Let\'s figure it out together.'
|
||||
]
|
||||
},
|
||||
goodbye: {
|
||||
keywords: ['bye', 'goodbye', 'пока', 'до свидания', 'see you'],
|
||||
keywords: ['bye', 'goodbye', 'пока', 'до свидания', 'see you', 'gotta go', 'must go'],
|
||||
answers: [
|
||||
'Goodbye! Keep practicing and you\'ll improve fast! See you next time! 👋',
|
||||
'Bye! Great job today! Come back when you want to practice more!'
|
||||
'Bye! 🌟 You did great today! Come back soon for more practice!',
|
||||
'See you later! Keep thinking in English! See you next time! 👋',
|
||||
'Goodbye! Remember - consistency is key! Practice a little every day! 💪'
|
||||
]
|
||||
},
|
||||
encouragement: {
|
||||
keywords: ['hard', 'трудно', 'difficult', 'can\'t', 'не могу', 'impossible'],
|
||||
keywords: ['hard', 'трудно', 'difficult', 'can\'t', 'не могу', 'impossible', 'suck', 'bad at'],
|
||||
answers: [
|
||||
'Learning English takes time, but you\'re doing great! Every day you\'re getting better. Keep going! 💪',
|
||||
'I understand it can be challenging. Break it into small steps. What specifically is difficult? I\'ll help!'
|
||||
'Hey, listen - learning a language is HARD! 🎯 But you know what? You\'re capable! Every mistake makes you stronger!',
|
||||
'I get it, some days are tougher. But look how far you\'ve come! Want to take a break and chat about something fun?',
|
||||
'Don\'t be so hard on yourself! Even fluent speakers started from zero. You\'ve got this! 💪 What\'s specifically difficult?'
|
||||
]
|
||||
},
|
||||
level: {
|
||||
keywords: ['level', 'уровень', 'beginner', 'intermediate', 'advanced'],
|
||||
answers: [
|
||||
'Choose your level from the cards above! Each level has theory, vocabulary, and exercises. Start where you feel comfortable.',
|
||||
'Don\'t worry too much about levels. Just start practicing and you\'ll naturally progress!'
|
||||
'Levels are just guides! 📍 Start where you feel comfy. You can always move up or review. Which feels right?',
|
||||
'Don\'t stress about levels! Just pick one and start. The exercises will tell you if it\'s too easy or hard!'
|
||||
]
|
||||
},
|
||||
hobbies: {
|
||||
keywords: ['hobby', 'хобби', 'interest', 'like to do', 'enjoy', 'love doing'],
|
||||
answers: [
|
||||
'Hobbies are the best! 🎨 Mine is... well, teaching English! 😄 What do YOU enjoy? Sports? Music? Reading?',
|
||||
'I\'d love to hear about your hobbies! What gets you excited? What do you do in free time?'
|
||||
]
|
||||
},
|
||||
weather: {
|
||||
keywords: ['weather', 'погода', 'sunny', 'rain', 'cold', 'hot', 'snow'],
|
||||
answers: [
|
||||
'Weather talk - classic English topic! ☀️🌧️ What\'s the weather like where you are? I\'m curious!',
|
||||
'Ah, the British love talking about weather! 😄 Is it sunny? Rainy? Perfect weather for studying English!'
|
||||
]
|
||||
},
|
||||
family: {
|
||||
keywords: ['family', 'семья', 'mother', 'father', 'sister', 'brother', 'parents'],
|
||||
answers: [
|
||||
'Family is important! 👨👩👧👦 Tell me about yours! Do you have siblings? What are your parents like?',
|
||||
'I\'d love to hear about your family! Are you close with them? Do they speak English too?'
|
||||
]
|
||||
},
|
||||
work: {
|
||||
keywords: ['work', 'работа', 'job', 'study', 'учеба', 'university', 'school'],
|
||||
answers: [
|
||||
'Work/study keeps us busy! 💼📚 What do you do? What\'s your favorite part about it?',
|
||||
'Interesting! What field are you in? Or what are you studying? I\'m all ears!'
|
||||
]
|
||||
},
|
||||
yes: {
|
||||
keywords: ['yes', 'да', 'yeah', 'yep', 'sure', 'of course', 'конечно'],
|
||||
answers: [
|
||||
'Great! 😊 So, tell me more! I\'m listening!',
|
||||
'Awesome! Keep going! What else?',
|
||||
'Perfect! You\'re doing well! Continue!'
|
||||
]
|
||||
},
|
||||
no: {
|
||||
keywords: ['no', 'нет', 'nope', 'don\'t', 'не'],
|
||||
answers: [
|
||||
'That\'s okay! 😊 Maybe another time. What WOULD you like to talk about?',
|
||||
'No problem! Everyone has different preferences. What interests you more?'
|
||||
]
|
||||
},
|
||||
why: {
|
||||
keywords: ['why', 'почему', 'wherefore'],
|
||||
answers: [
|
||||
'Good question! 🤔 "Why" questions are great for learning! Let me explain...',
|
||||
'Why indeed! Curiosity is the key to learning! Let\'s figure this out together.'
|
||||
]
|
||||
},
|
||||
what: {
|
||||
keywords: ['what', 'что', 'какой', 'which'],
|
||||
answers: [
|
||||
'Hmm, let me think... 🤔 What do YOU think? Try to answer in English!',
|
||||
'Great question! Let me help you figure it out. What\'s your guess?'
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
const fallbackAnswers = [
|
||||
'Interesting! Tell me more about it in English. Practice makes perfect! 😊',
|
||||
'I see! Can you give me an example sentence? I\'ll help you check it.',
|
||||
'That\'s a great topic! What specific aspect would you like to discuss?',
|
||||
'Good question! Let me think... Actually, the best way to learn is through practice. Try making a sentence with this!',
|
||||
'Hmm, I\'m not sure I understand completely. Can you rephrase that? Or ask me something more specific about English.'
|
||||
'Interesting! 😊 Tell me more! I\'m curious about your thoughts!',
|
||||
'I see! Can you give me an example? That helps me understand better!',
|
||||
'That\'s a great topic! What specifically interests you about it?',
|
||||
'Hmm, tell me more! Try to use English - I\'ll help if you get stuck! 💬',
|
||||
'Nice! So... what else? Ask me something or tell me about your day!',
|
||||
'Got it! 🎯 Now, here\'s a question for YOU: [asks question about the topic]'
|
||||
];
|
||||
|
||||
// Вопросы для поддержания разговора
|
||||
const conversationStarters = [
|
||||
'So, what did you do today?',
|
||||
'What\'s your favorite hobby? Why do you like it?',
|
||||
'Do you have any plans for the weekend?',
|
||||
'What\'s your favorite movie? Tell me about it!',
|
||||
'Do you prefer coffee or tea? Why?',
|
||||
'What\'s the best place you\'ve ever visited?',
|
||||
'Do you have any pets? Tell me about them!',
|
||||
'What\'s your favorite food? Can you describe it?',
|
||||
'Do you like music? What kind?',
|
||||
'What\'s something you\'re proud of?'
|
||||
];
|
||||
|
||||
function getFollowUpQuestion() {
|
||||
return conversationStarters[Math.floor(Math.random() * conversationStarters.length)];
|
||||
}
|
||||
|
||||
function getStaticResponse(message) {
|
||||
const lower = message.toLowerCase();
|
||||
|
||||
// Сохраняем в историю
|
||||
chatHistory.push({ role: 'user', content: message });
|
||||
if (chatHistory.length > 10) chatHistory.shift(); // Храним последние 10 сообщений
|
||||
|
||||
// Ищем совпадения по ключевым словам
|
||||
for (const [category, data] of Object.entries(teacherResponses)) {
|
||||
if (data.keywords.some(kw => lower.includes(kw))) {
|
||||
const answers = data.answers;
|
||||
return answers[Math.floor(Math.random() * answers.length)];
|
||||
let response = answers[Math.floor(Math.random() * answers.length)];
|
||||
|
||||
// Добавляем follow-up вопрос для продолжения разговора
|
||||
if (data.followUp && Math.random() > 0.5) {
|
||||
response += ' ' + data.followUp;
|
||||
} else if (Math.random() > 0.6) {
|
||||
response += ' ' + getFollowUpQuestion();
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
// Определяем язык
|
||||
const isRussian = /[а-яА-ЯёЁ]/.test(message);
|
||||
|
||||
// Проверяем последние сообщения в истории
|
||||
const lastUserMessage = chatHistory.filter(m => m.role === 'user').slice(-2, -1)[0];
|
||||
const lastTeacherMessage = chatHistory.filter(m => m.role === 'assistant').slice(-1)[0];
|
||||
|
||||
if (isRussian) {
|
||||
// Ответы на русском с английскими вставками
|
||||
const ruResponses = [
|
||||
'Отличный вопрос! Попробуй задать его на английском - я помогу с переводом и грамматикой.',
|
||||
'Интересно! Расскажи подробнее. Не бойся делать ошибки - я помогу их исправить.',
|
||||
'Хорошо! Давай обсудим это. Какой аспект тебя интересует?',
|
||||
'Вопрос понятен! Лучший способ выучить - практиковаться. Попробуй составить предложение на эту тему!',
|
||||
'Я тут, чтобы помочь! Спроси что-то конкретное о грамматике, словах или давай поболтаем на английском.'
|
||||
'Отлично! 😊 Теперь попробуй сказать это на английском! Я помогу.',
|
||||
'Интересно! Расскажи подробнее на английском. Не бойся ошибок!',
|
||||
'Хороший вопрос! Как ты думаешь, какой будет ответ? Попробуй угадать!',
|
||||
'Понятно! А что ты думаешь об этом? Tell me in English!',
|
||||
'Я тебя понимаю! Давай попробуем сказать это по-английски вместе!'
|
||||
];
|
||||
return ruResponses[Math.floor(Math.random() * ruResponses.length)];
|
||||
|
||||
let response = ruResponses[Math.floor(Math.random() * ruResponses.length)];
|
||||
|
||||
// Добавляем вопрос для продолжения
|
||||
if (Math.random() > 0.5) {
|
||||
const ruQuestions = [
|
||||
'А как ты это скажешь на английском?',
|
||||
'Что ты думаешь об этом?',
|
||||
'Расскажи подробнее!',
|
||||
'А что было потом?',
|
||||
'Почему ты так решил?'
|
||||
];
|
||||
response += ' ' + ruQuestions[Math.floor(Math.random() * ruQuestions.length)];
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
// English fallback
|
||||
return fallbackAnswers[Math.floor(Math.random() * fallbackAnswers.length)];
|
||||
// English fallback с поддержкой разговора
|
||||
let response = fallbackAnswers[Math.floor(Math.random() * fallbackAnswers.length)];
|
||||
|
||||
// Если это длинное сообщение - задаём уточняющий вопрос
|
||||
if (message.length > 30 || message.split(' ').length > 5) {
|
||||
const followUps = [
|
||||
' Why do you think so?',
|
||||
' Tell me more!',
|
||||
' What happened next?',
|
||||
' How did that make you feel?',
|
||||
' Really? That\'s interesting! Go on!',
|
||||
' What do you mean by that?',
|
||||
' Can you give me an example?'
|
||||
];
|
||||
response += followUps[Math.floor(Math.random() * followUps.length)];
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
async function askTeacher(message) {
|
||||
// Пробуем серверный ИИ (если есть)
|
||||
// Сохраняем сообщение пользователя в историю
|
||||
chatHistory.push({ role: 'user', content: message, timestamp: Date.now() });
|
||||
|
||||
// Пробуем серверный ИИ (если есть) - с полной историей диалога
|
||||
try {
|
||||
const levelContext = currentLevel ? `Current student level: ${currentLevel}. ` : '';
|
||||
const levelContext = currentLevel ? `Student level: ${currentLevel}. ` : '';
|
||||
|
||||
// Формируем контекст из истории
|
||||
const conversationContext = chatHistory.slice(-8).map(m =>
|
||||
`${m.role === 'user' ? 'Student' : 'Teacher'}: ${m.content}`
|
||||
).join('\n');
|
||||
|
||||
const messages = [
|
||||
{
|
||||
role: 'system',
|
||||
content: `You are a friendly and supportive English teacher. Your tasks:
|
||||
1. Communicate at the student's level
|
||||
2. Correct mistakes gently and explain grammar rules
|
||||
3. Help with vocabulary and constructions
|
||||
4. Encourage and motivate
|
||||
5. Answer grammar questions
|
||||
content: `You are a friendly, conversational English teacher. Have a NATURAL conversation with the student.
|
||||
|
||||
${levelContext}Respond briefly (2-4 sentences), in a friendly manner. If the student writes in Russian, respond in Russian with English examples. If in English, respond in English but you can add translations of difficult words.`
|
||||
${levelContext}
|
||||
YOUR STYLE:
|
||||
- Be warm, encouraging, and curious
|
||||
- Ask follow-up questions to keep conversation going
|
||||
- Show genuine interest in their life, opinions, experiences
|
||||
- Correct mistakes gently by rephrasing correctly
|
||||
- Use emoji occasionally 😊
|
||||
- Keep responses conversational (2-4 sentences)
|
||||
- If they write in Russian, respond in Russian with English examples
|
||||
- Always end with a question or invitation to share more
|
||||
|
||||
RECENT CONVERSATION:
|
||||
${conversationContext}
|
||||
|
||||
Now respond naturally to: "${message}"`
|
||||
},
|
||||
{
|
||||
role: 'user',
|
||||
@ -636,7 +816,7 @@ ${levelContext}Respond briefly (2-4 sentences), in a friendly manner. If the stu
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ messages }),
|
||||
timeout: 5000
|
||||
timeout: 8000
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@ -650,11 +830,19 @@ ${levelContext}Respond briefly (2-4 sentences), in a friendly manner. If the stu
|
||||
throw new Error('Empty AI response');
|
||||
}
|
||||
|
||||
// Сохраняем ответ учителя
|
||||
chatHistory.push({ role: 'assistant', content: answer, timestamp: Date.now() });
|
||||
|
||||
return answer.replace(/\n/g, '<br>');
|
||||
} catch (error) {
|
||||
// Фолбэк на статические ответы
|
||||
// Фолбэк на статические ответы с разговорной логикой
|
||||
console.log('Using static responses:', error.message);
|
||||
return getStaticResponse(message);
|
||||
const response = getStaticResponse(message);
|
||||
|
||||
// Сохраняем ответ в историю
|
||||
chatHistory.push({ role: 'assistant', content: response, timestamp: Date.now() });
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
14
style.css
14
style.css
@ -175,21 +175,35 @@ body {
|
||||
.message {
|
||||
margin-bottom: 16px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.message.student {
|
||||
justify-content: flex-end;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.message.teacher {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.message-avatar {
|
||||
font-size: 24px;
|
||||
flex-shrink: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.message-bubble {
|
||||
max-width: 80%;
|
||||
padding: 12px 16px;
|
||||
border-radius: 16px;
|
||||
line-height: 1.5;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.message.teacher .message-bubble {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user