diff --git a/SHARING_GUIDE.md b/SHARING_GUIDE.md new file mode 100644 index 0000000..8c49eb4 --- /dev/null +++ b/SHARING_GUIDE.md @@ -0,0 +1,76 @@ +# πŸ”— Руководство ΠΏΠΎ ΡˆΠ°Ρ€ΠΈΠ½Π³Ρƒ ΠΊΠΎΠΌΠ½Π°Ρ‚ + +## Как ΠΏΡ€ΠΈΠ³Π»Π°ΡΠΈΡ‚ΡŒ Π΄Ρ€ΡƒΠ·Π΅ΠΉ Π² ΠΈΠ³Ρ€Ρƒ + +### Бпособ 1: ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ссылки +1. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ ΠΊΠΎΠΌΠ½Π°Ρ‚Ρƒ ΠΈΠ»ΠΈ Π·Π°ΠΉΠ΄ΠΈΡ‚Π΅ Π² ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ +2. Π’ Π»ΠΎΠ±Π±ΠΈ ΠΊΠΎΠΌΠ½Π°Ρ‚Ρ‹ Π½Π°ΠΆΠΌΠΈΡ‚Π΅ Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡƒ **πŸ“‹** рядом со ссылкой +3. ΠžΡ‚ΠΏΡ€Π°Π²ΡŒΡ‚Π΅ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ ссылку Π΄Ρ€ΡƒΠ·ΡŒΡΠΌ Π»ΡŽΠ±Ρ‹ΠΌ ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΌ способом + +### Бпособ 2: ΠŸΡ€ΡΠΌΠΎΠΉ ΡˆΠ°Ρ€ΠΈΠ½Π³ Π² Telegram +1. Π’ Π»ΠΎΠ±Π±ΠΈ ΠΊΠΎΠΌΠ½Π°Ρ‚Ρ‹ Π½Π°ΠΆΠΌΠΈΡ‚Π΅ ΠΊΠ½ΠΎΠΏΠΊΡƒ **πŸ“± Telegram** +2. Π’Ρ‹Π±Π΅Ρ€ΠΈΡ‚Π΅ Ρ‡Π°Ρ‚ ΠΈΠ»ΠΈ ΠΊΠΎΠ½Ρ‚Π°ΠΊΡ‚ для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ +3. Π’Π°Ρˆ Π΄Ρ€ΡƒΠ³ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ ссылку с ΠΏΡ€ΠΈΠ³Π»Π°ΡˆΠ΅Π½ΠΈΠ΅ΠΌ + +### Бпособ 3: ΠŸΡ€ΡΠΌΠΎΠΉ ΡˆΠ°Ρ€ΠΈΠ½Π³ Π² WhatsApp +1. Π’ Π»ΠΎΠ±Π±ΠΈ ΠΊΠΎΠΌΠ½Π°Ρ‚Ρ‹ Π½Π°ΠΆΠΌΠΈΡ‚Π΅ ΠΊΠ½ΠΎΠΏΠΊΡƒ **πŸ’¬ WhatsApp** +2. Π’Ρ‹Π±Π΅Ρ€ΠΈΡ‚Π΅ Ρ‡Π°Ρ‚ ΠΈΠ»ΠΈ ΠΊΠΎΠ½Ρ‚Π°ΠΊΡ‚ для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ +3. Π’Π°Ρˆ Π΄Ρ€ΡƒΠ³ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ ссылку с ΠΏΡ€ΠΈΠ³Π»Π°ΡˆΠ΅Π½ΠΈΠ΅ΠΌ + +### Бпособ 4: Π£Π½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΡˆΠ°Ρ€ΠΈΠ½Π³ (Π½Π° ΠΌΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹Ρ… устройствах) +1. Π’ Π»ΠΎΠ±Π±ΠΈ ΠΊΠΎΠΌΠ½Π°Ρ‚Ρ‹ Π½Π°ΠΆΠΌΠΈΡ‚Π΅ ΠΊΠ½ΠΎΠΏΠΊΡƒ **πŸ”— ΠŸΠΎΠ΄Π΅Π»ΠΈΡ‚ΡŒΡΡ** +2. Π’Ρ‹Π±Π΅Ρ€ΠΈΡ‚Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ (доступно Π½Π° Android/iOS) +3. ΠžΡ‚ΠΏΡ€Π°Π²ΡŒΡ‚Π΅ ссылку Ρ‡Π΅Ρ€Π΅Π· Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ + +## Как ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ ΠΏΠΎ ссылкС + +### Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ A: АвтоматичСскоС присоСдинСниС +1. ΠŸΠ΅Ρ€Π΅ΠΉΠ΄ΠΈΡ‚Π΅ ΠΏΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠΉ ссылкС +2. Π’ΠΎΠΉΠ΄ΠΈΡ‚Π΅ Π² ΠΈΠ³Ρ€Ρƒ ΠΈΠ»ΠΈ Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΡƒΠΉΡ‚Π΅ΡΡŒ +3. Π’Ρ‹ автоматичСски ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚Π΅ΡΡŒ ΠΊ ΠΊΠΎΠΌΠ½Π°Ρ‚Π΅ + +### Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ B: Π ΡƒΡ‡Π½ΠΎΠ΅ присоСдинСниС +1. Π’ΠΎΠΉΠ΄ΠΈΡ‚Π΅ Π² ΠΈΠ³Ρ€Ρƒ +2. ΠŸΠ΅Ρ€Π΅ΠΉΠ΄ΠΈΡ‚Π΅ Π² Ρ€Π°Π·Π΄Π΅Π» "ΠœΡƒΠ»ΡŒΡ‚ΠΈΠΏΠ»Π΅Π΅Ρ€" +3. НайдитС ΠΊΠΎΠΌΠ½Π°Ρ‚Ρƒ Π² спискС ΠΈ ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚Π΅ΡΡŒ + +## Π€ΠΎΡ€ΠΌΠ°Ρ‚ ссылки + +Бсылка Π½Π° ΠΊΠΎΠΌΠ½Π°Ρ‚Ρƒ ΠΈΠΌΠ΅Π΅Ρ‚ Π²ΠΈΠ΄: +``` +http://localhost:3000/?room=room_1234567890_abc123 +``` + +Π“Π΄Π΅ `room_1234567890_abc123` - ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ ID ΠΊΠΎΠΌΠ½Π°Ρ‚Ρ‹. + +## ΠžΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΠΈ + +- βœ… Бсылка Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΊΠΎΠΌΠ½Π°Ρ‚Π° Π°ΠΊΡ‚ΠΈΠ²Π½Π° +- βœ… По ΠΎΠ΄Π½ΠΎΠΉ ссылкС ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ нСсколько ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ² +- βœ… ΠšΠΎΠΌΠ½Π°Ρ‚Π° закрываСтся, ΠΊΠΎΠ³Π΄Π° всС ΠΈΠ³Ρ€ΠΎΠΊΠΈ выходят +- βœ… МаксимальноС количСство ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ² устанавливаСтся ΠΏΡ€ΠΈ создании ΠΊΠΎΠΌΠ½Π°Ρ‚Ρ‹ + +## Π‘ΠΎΠ²Π΅Ρ‚Ρ‹ + +1. **БыстроС ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅**: ΠšΠ»ΠΈΠΊΠ½ΠΈΡ‚Π΅ Π½Π° ΠΏΠΎΠ»Π΅ со ссылкой - тСкст выдСлится автоматичСски +2. **ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ссылки**: Бсылка обновляСтся автоматичСски ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΠΊΠΎΠΌΠ½Π°Ρ‚Ρ‹ +3. **ΠœΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹Π΅ устройства**: Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΊΠ½ΠΎΠΏΠΊΡƒ "ΠŸΠΎΠ΄Π΅Π»ΠΈΡ‚ΡŒΡΡ" для быстрого ΡˆΠ°Ρ€ΠΈΠ½Π³Π° +4. **Telegram/WhatsApp**: Π Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΊΠ°ΠΊ Π½Π° дСсктопС, Ρ‚Π°ΠΊ ΠΈ Π½Π° ΠΌΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹Ρ… устройствах + +## ВСхничСская информация + +### ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Ρ‹ +- Chrome/Edge: всС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ +- Firefox: всС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ +- Safari (iOS): всС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ Web Share API +- ΠœΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹Π΅ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Ρ‹: полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° + +### API +- **Clipboard API** - для копирования ссылки +- **Web Share API** - для ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΡˆΠ°Ρ€ΠΈΠ½Π³Π° (ΠΌΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹Π΅ устройства) +- **URL Parameters** - для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ID ΠΊΠΎΠΌΠ½Π°Ρ‚Ρ‹ + +### Π‘Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ +- ID ΠΊΠΎΠΌΠ½Π°Ρ‚Ρ‹ гСнСрируСтся Π½Π° сСрвСрС +- НСвозмоТно ΠΏΠΎΠ΄Π΄Π΅Π»Π°Ρ‚ΡŒ ΠΈΠ»ΠΈ ΡƒΠ³Π°Π΄Π°Ρ‚ΡŒ ID +- ΠšΠΎΠΌΠ½Π°Ρ‚Π° доступна Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ diff --git a/database.js b/database.js index e97c905..0a67caa 100644 --- a/database.js +++ b/database.js @@ -40,6 +40,9 @@ async function initDatabase() { // Π‘ΠΎΠ·Π΄Π°Ρ‘ΠΌ Π°Π΄ΠΌΠΈΠ½Π° ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ await createDefaultAdmin(); + // ВсСгда провСряСм ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ админскиС настройки + initDefaultAdminSettings(); + return db; } @@ -150,9 +153,6 @@ async function createDefaultAdmin() { saveDatabase(); console.log('πŸ‘‘ Π‘ΠΎΠ·Π΄Π°Π½ администратор ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: admin / admin123'); } - - // Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π΄Π΅Ρ„ΠΎΠ»Ρ‚Π½Ρ‹Π΅ админскиС настройки - initDefaultAdminSettings(); } /** diff --git a/poker.db b/poker.db index 31a3e37..abb938f 100644 Binary files a/poker.db and b/poker.db differ diff --git a/public/auth.js b/public/auth.js index 7843631..fbfe201 100644 --- a/public/auth.js +++ b/public/auth.js @@ -188,6 +188,11 @@ function onAuthSuccess() { if (!isGuest && authToken) { loadUserSettingsFromServer(); } + + // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ ΠΊΠΎΠΌΠ½Π°Ρ‚Ρ‹ Π² URL для автоматичСского присоСдинСния + if (typeof checkRoomInUrl === 'function') { + checkRoomInUrl(); + } } /** @@ -198,6 +203,7 @@ function updateUserDisplay() { const badgeEl = document.getElementById('user-role-badge'); const adminBtn = document.getElementById('admin-btn'); const serverUrlGroup = document.getElementById('server-url-group'); + const adminLlmButtonGroup = document.getElementById('admin-llm-button-group'); if (currentUser) { nameEl.textContent = currentUser.username; @@ -207,10 +213,12 @@ function updateUserDisplay() { badgeEl.textContent = 'ADMIN'; if (adminBtn) adminBtn.style.display = 'block'; if (serverUrlGroup) serverUrlGroup.style.display = 'block'; + if (adminLlmButtonGroup) adminLlmButtonGroup.style.display = 'block'; } else { badgeEl.style.display = 'none'; if (adminBtn) adminBtn.style.display = 'none'; if (serverUrlGroup) serverUrlGroup.style.display = 'none'; + if (adminLlmButtonGroup) adminLlmButtonGroup.style.display = 'none'; } // ОбновляСм поля ΠΈΠΌΠ΅Π½ΠΈ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ… @@ -363,7 +371,12 @@ function switchAdminTab(tab) { * Π—Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ админскиС настройки */ async function loadAdminSettings() { - if (!authToken || currentUser?.role !== 'admin') return; + if (!authToken || currentUser?.role !== 'admin') { + console.log('❌ НСт ΠΏΡ€Π°Π² для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π°Π΄ΠΌΠΈΠ½ настроСк'); + return; + } + + console.log('πŸ“₯ Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° админских настроСк...'); try { const response = await fetch('/api/settings/admin', { @@ -374,14 +387,18 @@ async function loadAdminSettings() { const data = await response.json(); const s = data.settings; + console.log('βœ… ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½Ρ‹ настройки:', s); + document.getElementById('admin-llm-enabled').checked = s.llmEnabled; document.getElementById('admin-llm-provider').value = s.llmProvider || 'ollama'; document.getElementById('admin-llm-url').value = s.llmApiUrl || 'http://localhost:11434'; document.getElementById('admin-llm-model').value = s.llmModel || 'llama3.2'; document.getElementById('admin-llm-apikey').value = s.llmApiKey || ''; + } else { + console.error('❌ Ошибка ΠΎΡ‚Π²Π΅Ρ‚Π° сСрвСра:', response.status); } } catch (error) { - console.error('Ошибка Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π°Π΄ΠΌΠΈΠ½ настроСк:', error); + console.error('❌ Ошибка Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π°Π΄ΠΌΠΈΠ½ настроСк:', error); } } @@ -399,6 +416,8 @@ async function saveAdminSettings() { llmApiKey: document.getElementById('admin-llm-apikey').value }; + console.log('πŸ’Ύ Π‘ΠΎΡ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ админских настроСк:', settings); + try { const response = await fetch('/api/settings/admin', { method: 'POST', @@ -411,9 +430,14 @@ async function saveAdminSettings() { if (response.ok) { showNotification('Настройки сохранСны', 'success'); + // ОбновляСм статус LLM для отобраТСния Π² настройках + loadLLMStatus(); + } else { + showNotification('Ошибка сохранСния', 'error'); } } catch (error) { showNotification('Ошибка сохранСния', 'error'); + console.error('Ошибка:', error); } } diff --git a/public/index.html b/public/index.html index 5db2e67..d86f008 100644 --- a/public/index.html +++ b/public/index.html @@ -221,6 +221,27 @@

ΠšΠΎΠΌΠ½Π°Ρ‚Π°

+ +
+ +
+ + + +
+
+
@@ -461,6 +482,13 @@ LLM Ρ‡Π°Ρ‚: Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ°... + + +
diff --git a/public/main.js b/public/main.js index 465e4fe..d9c1f65 100644 --- a/public/main.js +++ b/public/main.js @@ -495,6 +495,9 @@ function showRoomLobby(room) { document.getElementById('lobby-room-name').textContent = room.name; document.getElementById('lobby-blinds').textContent = `${room.smallBlind}/${room.bigBlind}`; + // Π“Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ ΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌ ссылку Π½Π° ΠΊΠΎΠΌΠ½Π°Ρ‚Ρƒ + updateRoomLink(room.id); + updateLobbyPlayers(room); } @@ -519,6 +522,11 @@ function updateLobbyPlayers(room) { const startBtn = document.getElementById('start-game-btn'); startBtn.style.display = room.players[0]?.id === currentPlayerId ? 'block' : 'none'; startBtn.disabled = room.players.length < 2; + + // ОбновляСм ссылку Π½Π° ΠΊΠΎΠΌΠ½Π°Ρ‚Ρƒ (Ссли ID измСнился) + if (room.id) { + updateRoomLink(room.id); + } } /** @@ -2000,3 +2008,136 @@ function showNotification(message, type = 'info') { notification.remove(); }, 3000); } + +// ============================================================================= +// Π¨ΠΠ Π˜ΠΠ“ КОМНАВЫ +// ============================================================================= + +/** + * ΠžΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ ссылку Π½Π° ΠΊΠΎΠΌΠ½Π°Ρ‚Ρƒ + */ +function updateRoomLink(roomId) { + const baseUrl = window.location.origin + window.location.pathname; + const roomUrl = `${baseUrl}?room=${roomId}`; + + const input = document.getElementById('room-link-input'); + if (input) { + input.value = roomUrl; + } + + // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ Web Share API + const shareBtn = document.getElementById('share-generic-btn'); + if (shareBtn) { + if (navigator.share) { + shareBtn.style.display = 'inline-flex'; + } else { + shareBtn.style.display = 'none'; + } + } +} + +/** + * ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ссылку Π½Π° ΠΊΠΎΠΌΠ½Π°Ρ‚Ρƒ + */ +async function copyRoomLink() { + const input = document.getElementById('room-link-input'); + const url = input.value; + + try { + if (navigator.clipboard) { + await navigator.clipboard.writeText(url); + showNotification('Бсылка скопирована!', 'success'); + } else { + // Запасной Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ для старых Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠ² + input.select(); + document.execCommand('copy'); + showNotification('Бсылка скопирована!', 'success'); + } + } catch (error) { + console.error('Ошибка копирования:', error); + showNotification('НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ссылку', 'error'); + } +} + +/** + * ΠŸΠΎΠ΄Π΅Π»ΠΈΡ‚ΡŒΡΡ Π² Telegram + */ +function shareToTelegram() { + const input = document.getElementById('room-link-input'); + const url = input.value; + const roomName = document.getElementById('lobby-room-name').textContent; + + const text = `ΠŸΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΡΠΉΡΡ ΠΊ ΠΈΠ³Ρ€Π΅ Π² ΠΏΠΎΠΊΠ΅Ρ€ "${roomName}"!`; + const telegramUrl = `https://t.me/share/url?url=${encodeURIComponent(url)}&text=${encodeURIComponent(text)}`; + + window.open(telegramUrl, '_blank'); +} + +/** + * ΠŸΠΎΠ΄Π΅Π»ΠΈΡ‚ΡŒΡΡ Π² WhatsApp + */ +function shareToWhatsApp() { + const input = document.getElementById('room-link-input'); + const url = input.value; + const roomName = document.getElementById('lobby-room-name').textContent; + + const text = `ΠŸΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΡΠΉΡΡ ΠΊ ΠΈΠ³Ρ€Π΅ Π² ΠΏΠΎΠΊΠ΅Ρ€ "${roomName}"!\n${url}`; + const whatsappUrl = `https://wa.me/?text=${encodeURIComponent(text)}`; + + window.open(whatsappUrl, '_blank'); +} + +/** + * ΠŸΠΎΠ΄Π΅Π»ΠΈΡ‚ΡŒΡΡ Ρ‡Π΅Ρ€Π΅Π· Web Share API + */ +async function shareGeneric() { + const input = document.getElementById('room-link-input'); + const url = input.value; + const roomName = document.getElementById('lobby-room-name').textContent; + + if (navigator.share) { + try { + await navigator.share({ + title: 'Texas Hold\'em Poker', + text: `ΠŸΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΡΠΉΡΡ ΠΊ ΠΈΠ³Ρ€Π΅ Π² ΠΏΠΎΠΊΠ΅Ρ€ "${roomName}"!`, + url: url + }); + showNotification('Бсылка ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½Π°!', 'success'); + } catch (error) { + if (error.name !== 'AbortError') { + console.error('Ошибка ΡˆΠ°Ρ€ΠΈΠ½Π³Π°:', error); + showNotification('НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΏΠΎΠ΄Π΅Π»ΠΈΡ‚ΡŒΡΡ', 'error'); + } + } + } else { + showNotification('Π’Π°Ρˆ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ', 'info'); + } +} + +/** + * ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ ΠΈ ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ ΠΊ ΠΊΠΎΠΌΠ½Π°Ρ‚Π΅ ΠΈΠ· URL + */ +function checkRoomInUrl() { + const urlParams = new URLSearchParams(window.location.search); + const roomId = urlParams.get('room'); + + if (roomId && currentPlayerId) { + // Если Π΅ΡΡ‚ΡŒ ID ΠΊΠΎΠΌΠ½Π°Ρ‚Ρ‹ Π² URL, пытаСмся ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ + showNotification('ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ ΠΊΠΎΠΌΠ½Π°Ρ‚Π΅...', 'info'); + + // ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π² ΠΌΡƒΠ»ΡŒΡ‚ΠΈΠΏΠ»Π΅Π΅Ρ€ ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌΡΡ + setTimeout(() => { + showScreen('multiplayer-menu'); + + // Π–Π΄Ρ‘ΠΌ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ WebSocket + if (ws && ws.readyState === WebSocket.OPEN) { + joinRoom(roomId); + } else { + connectWebSocket().then(() => { + setTimeout(() => joinRoom(roomId), 500); + }); + } + }, 500); + } +} + diff --git a/public/styles.css b/public/styles.css index 37c2ea0..4d1c31b 100644 --- a/public/styles.css +++ b/public/styles.css @@ -568,6 +568,40 @@ body::before { font-size: 14px; } +/* Π‘Π»ΠΎΠΊ ΡˆΠ°Ρ€ΠΈΠ½Π³Π° ΠΊΠΎΠΌΠ½Π°Ρ‚Ρ‹ */ +.room-share-section { + margin-bottom: 24px; + padding: 16px; + background: var(--bg-secondary); + border-radius: var(--border-radius); + border: 1px solid var(--glass-border); +} + +.room-link-display { + display: flex; + gap: 8px; + margin-bottom: 12px; +} + +.room-link-display .input { + flex: 1; + font-size: 13px; + font-family: monospace; + cursor: pointer; +} + +.share-buttons { + display: flex; + gap: 8px; + justify-content: center; + flex-wrap: wrap; +} + +.share-buttons .btn { + flex: 1; + min-width: 100px; +} + .lobby-chat { margin-top: 24px; border-top: 1px solid var(--glass-border); diff --git a/server.js b/server.js index 03a8941..62df453 100644 --- a/server.js +++ b/server.js @@ -122,6 +122,7 @@ app.post('/api/settings/user', authMiddleware, (req, res) => { // ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ админскиС настройки app.get('/api/settings/admin', authMiddleware, adminMiddleware, (req, res) => { const settings = database.getAdminSettings(); + console.log('πŸ“€ ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° админских настроСк:', settings); res.json({ settings }); });