Add 2 files
Browse files- index.html +100 -4
- prompts.txt +2 -1
index.html
CHANGED
|
@@ -115,6 +115,25 @@
|
|
| 115 |
.copy-btn.copied {
|
| 116 |
background-color: #10b981;
|
| 117 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
</style>
|
| 119 |
</head>
|
| 120 |
<body class="font-sans bg-dark-900 text-dark-100 min-h-screen">
|
|
@@ -223,10 +242,15 @@
|
|
| 223 |
<div class="bg-dark-700 p-4 border-t border-dark-600">
|
| 224 |
<div class="flex space-x-2">
|
| 225 |
<div class="flex-1 relative">
|
| 226 |
-
<input type="text" id="message-input" placeholder="Type your message..." class="w-full px-4 py-3 pr-
|
| 227 |
-
<
|
| 228 |
-
<
|
| 229 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 230 |
</div>
|
| 231 |
</div>
|
| 232 |
|
|
@@ -295,6 +319,7 @@
|
|
| 295 |
const copyLinkBtn = document.getElementById('copy-link');
|
| 296 |
const copyCodeBtn = document.getElementById('copy-code');
|
| 297 |
const closeModalBtn = document.getElementById('close-modal');
|
|
|
|
| 298 |
|
| 299 |
// App State
|
| 300 |
let userLanguage = null;
|
|
@@ -304,6 +329,8 @@
|
|
| 304 |
let participants = [];
|
| 305 |
let isPartnerTyping = false;
|
| 306 |
let chatId = null;
|
|
|
|
|
|
|
| 307 |
|
| 308 |
// Language data
|
| 309 |
const languageData = {
|
|
@@ -315,6 +342,70 @@
|
|
| 315 |
'ja': { name: 'Japanese', flag: '🇯🇵', code: 'ja' }
|
| 316 |
};
|
| 317 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 318 |
// Event Listeners
|
| 319 |
languageItems.forEach(item => {
|
| 320 |
item.addEventListener('click', function() {
|
|
@@ -368,6 +459,11 @@
|
|
| 368 |
copyCodeBtn.addEventListener('click', copyToClipboard.bind(null, shareCode, copyCodeBtn));
|
| 369 |
closeModalBtn.addEventListener('click', () => joinModal.classList.add('hidden'));
|
| 370 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 371 |
// Functions
|
| 372 |
function generateChatId() {
|
| 373 |
// Generate a random 6-character alphanumeric code
|
|
|
|
| 115 |
.copy-btn.copied {
|
| 116 |
background-color: #10b981;
|
| 117 |
}
|
| 118 |
+
.mic-btn {
|
| 119 |
+
transition: all 0.2s ease;
|
| 120 |
+
}
|
| 121 |
+
.mic-btn.listening {
|
| 122 |
+
background-color: #ef4444;
|
| 123 |
+
color: white;
|
| 124 |
+
animation: pulse 1.5s infinite;
|
| 125 |
+
}
|
| 126 |
+
@keyframes pulse {
|
| 127 |
+
0% {
|
| 128 |
+
box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
|
| 129 |
+
}
|
| 130 |
+
70% {
|
| 131 |
+
box-shadow: 0 0 0 10px rgba(239, 68, 68, 0);
|
| 132 |
+
}
|
| 133 |
+
100% {
|
| 134 |
+
box-shadow: 0 0 0 0 rgba(239, 68, 68, 0);
|
| 135 |
+
}
|
| 136 |
+
}
|
| 137 |
</style>
|
| 138 |
</head>
|
| 139 |
<body class="font-sans bg-dark-900 text-dark-100 min-h-screen">
|
|
|
|
| 242 |
<div class="bg-dark-700 p-4 border-t border-dark-600">
|
| 243 |
<div class="flex space-x-2">
|
| 244 |
<div class="flex-1 relative">
|
| 245 |
+
<input type="text" id="message-input" placeholder="Type your message..." class="w-full px-4 py-3 pr-20 bg-dark-600 border border-dark-500 rounded-full focus:ring-2 focus:ring-primary-500 focus:border-transparent text-dark-100 placeholder-dark-400">
|
| 246 |
+
<div class="absolute right-3 top-3 flex space-x-2">
|
| 247 |
+
<button id="mic-button" class="mic-btn text-dark-300 hover:text-white p-2 rounded-full">
|
| 248 |
+
<i class="fas fa-microphone"></i>
|
| 249 |
+
</button>
|
| 250 |
+
<button id="send-message" class="text-primary-500 hover:text-primary-400">
|
| 251 |
+
<i class="fas fa-paper-plane"></i>
|
| 252 |
+
</button>
|
| 253 |
+
</div>
|
| 254 |
</div>
|
| 255 |
</div>
|
| 256 |
|
|
|
|
| 319 |
const copyLinkBtn = document.getElementById('copy-link');
|
| 320 |
const copyCodeBtn = document.getElementById('copy-code');
|
| 321 |
const closeModalBtn = document.getElementById('close-modal');
|
| 322 |
+
const micButton = document.getElementById('mic-button');
|
| 323 |
|
| 324 |
// App State
|
| 325 |
let userLanguage = null;
|
|
|
|
| 329 |
let participants = [];
|
| 330 |
let isPartnerTyping = false;
|
| 331 |
let chatId = null;
|
| 332 |
+
let recognition = null;
|
| 333 |
+
let isListening = false;
|
| 334 |
|
| 335 |
// Language data
|
| 336 |
const languageData = {
|
|
|
|
| 342 |
'ja': { name: 'Japanese', flag: '🇯🇵', code: 'ja' }
|
| 343 |
};
|
| 344 |
|
| 345 |
+
// Initialize speech recognition
|
| 346 |
+
function initSpeechRecognition() {
|
| 347 |
+
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
| 348 |
+
|
| 349 |
+
if (!SpeechRecognition) {
|
| 350 |
+
console.warn('Speech recognition not supported in this browser');
|
| 351 |
+
micButton.style.display = 'none';
|
| 352 |
+
return;
|
| 353 |
+
}
|
| 354 |
+
|
| 355 |
+
recognition = new SpeechRecognition();
|
| 356 |
+
recognition.continuous = false;
|
| 357 |
+
recognition.interimResults = false;
|
| 358 |
+
|
| 359 |
+
recognition.onstart = function() {
|
| 360 |
+
isListening = true;
|
| 361 |
+
micButton.classList.add('listening');
|
| 362 |
+
messageInput.placeholder = "Listening...";
|
| 363 |
+
};
|
| 364 |
+
|
| 365 |
+
recognition.onend = function() {
|
| 366 |
+
isListening = false;
|
| 367 |
+
micButton.classList.remove('listening');
|
| 368 |
+
messageInput.placeholder = "Type your message...";
|
| 369 |
+
};
|
| 370 |
+
|
| 371 |
+
recognition.onresult = function(event) {
|
| 372 |
+
const transcript = event.results[0][0].transcript;
|
| 373 |
+
messageInput.value = transcript;
|
| 374 |
+
updateCharCount();
|
| 375 |
+
};
|
| 376 |
+
|
| 377 |
+
recognition.onerror = function(event) {
|
| 378 |
+
console.error('Speech recognition error', event.error);
|
| 379 |
+
addSystemMessage('Speech recognition error: ' + event.error);
|
| 380 |
+
};
|
| 381 |
+
}
|
| 382 |
+
|
| 383 |
+
// Toggle speech recognition
|
| 384 |
+
function toggleSpeechRecognition() {
|
| 385 |
+
if (!recognition) {
|
| 386 |
+
addSystemMessage('Speech recognition is not supported or initialized');
|
| 387 |
+
return;
|
| 388 |
+
}
|
| 389 |
+
|
| 390 |
+
if (isListening) {
|
| 391 |
+
recognition.stop();
|
| 392 |
+
} else {
|
| 393 |
+
// Set recognition language based on user's selected language
|
| 394 |
+
if (userLanguage) {
|
| 395 |
+
recognition.lang = languageData[userLanguage].code;
|
| 396 |
+
} else {
|
| 397 |
+
recognition.lang = 'en-US'; // Default to English
|
| 398 |
+
}
|
| 399 |
+
|
| 400 |
+
try {
|
| 401 |
+
recognition.start();
|
| 402 |
+
} catch (e) {
|
| 403 |
+
console.error('Speech recognition start error:', e);
|
| 404 |
+
addSystemMessage('Could not start speech recognition: ' + e.message);
|
| 405 |
+
}
|
| 406 |
+
}
|
| 407 |
+
}
|
| 408 |
+
|
| 409 |
// Event Listeners
|
| 410 |
languageItems.forEach(item => {
|
| 411 |
item.addEventListener('click', function() {
|
|
|
|
| 459 |
copyCodeBtn.addEventListener('click', copyToClipboard.bind(null, shareCode, copyCodeBtn));
|
| 460 |
closeModalBtn.addEventListener('click', () => joinModal.classList.add('hidden'));
|
| 461 |
|
| 462 |
+
micButton.addEventListener('click', toggleSpeechRecognition);
|
| 463 |
+
|
| 464 |
+
// Initialize speech recognition when the page loads
|
| 465 |
+
initSpeechRecognition();
|
| 466 |
+
|
| 467 |
// Functions
|
| 468 |
function generateChatId() {
|
| 469 |
// Generate a random 6-character alphanumeric code
|
prompts.txt
CHANGED
|
@@ -8,4 +8,5 @@ complete
|
|
| 8 |
the one opens t4he chat ju5st choose his language
|
| 9 |
design dark
|
| 10 |
translation not work
|
| 11 |
-
when the chat opens after the one user started show link and code to join for the other part
|
|
|
|
|
|
| 8 |
the one opens t4he chat ju5st choose his language
|
| 9 |
design dark
|
| 10 |
translation not work
|
| 11 |
+
when the chat opens after the one user started show link and code to join for the other part
|
| 12 |
+
add speech to text
|