some fixes

This commit is contained in:
jahlib
2025-11-06 11:26:03 +03:00
committed by GitHub
parent 330b025107
commit e69bdabc15
4 changed files with 161 additions and 83 deletions
+13 -5
View File
@@ -169,7 +169,8 @@ class CardGame {
this.nicknameInput = document.getElementById('nickname-input');
this.createRoomBtn = document.getElementById('create-room-btn');
this.roomsList = document.getElementById('rooms-list');
this.privateRoomCheckbox = document.getElementById('private-room-checkbox');
this.privateRoomToggle = document.getElementById('private-room-toggle');
this.privateRoomSettings = document.getElementById('private-room-settings');
this.inviteLinkBlock = document.getElementById('invite-link-block');
this.inviteLink = document.getElementById('invite-link');
this.copyLinkBtn = document.getElementById('copy-link-btn');
@@ -260,8 +261,8 @@ class CardGame {
if (e.key === 'Enter') this.createRoom();
});
// Private room checkbox
this.privateRoomCheckbox.addEventListener('change', () => this.togglePrivateRoom());
// Private room toggle
this.privateRoomToggle.addEventListener('change', () => this.togglePrivateRoom());
// Copy and share link buttons
this.copyLinkBtn.addEventListener('click', () => this.copyInviteLink());
@@ -805,7 +806,7 @@ class CardGame {
}
togglePrivateRoom() {
const isChecked = this.privateRoomCheckbox.checked;
const isChecked = this.privateRoomToggle.checked;
// Отправляем на сервер изменение приватности
this.send({
@@ -982,7 +983,14 @@ class CardGame {
// Проверяем что ни у кого нет очков (игра ещё не начиналась)
const noScores = room.players.every(p => p.score === 0);
this.roomSettings.style.display = (isCreator && gameNotStarted && noScores) ? 'block' : 'none';
const shouldShow = isCreator && gameNotStarted && noScores;
this.roomSettings.style.display = shouldShow ? 'block' : 'none';
// Блок приватной комнаты показываем по той же логике
if (this.privateRoomSettings) {
this.privateRoomSettings.style.display = shouldShow ? 'block' : 'none';
}
// Устанавливаем текущий размер колоды
if (room.deck_size) {
+10 -8
View File
@@ -22,7 +22,7 @@
<!-- iOS Icons -->
<link rel="apple-touch-icon" href="/icon-192.png">
<link rel="stylesheet" href="/style.css?v=2">
<link rel="stylesheet" href="/style.css?v=3">
</head>
<body>
<div id="app">
@@ -94,12 +94,14 @@
<button id="ready-toggle-btn" class="btn btn-primary">Готов</button>
<p class="hint">Игра начнётся когда все игроки будут готовы (минимум 2 игрока)</p>
<div class="room-settings">
<!-- Чекбокс приватной комнаты -->
<div class="private-room-toggle">
<div class="room-settings" id="private-room-settings">
<!-- Переключатель приватной комнаты -->
<div class="deck-size-toggle">
<label>
<input type="checkbox" id="private-room-checkbox">
<span>Приватная комната</span>
<span class="deck-label">Публичная</span>
<input type="checkbox" id="private-room-toggle">
<span class="toggle-slider"></span>
<span class="deck-label">Приватная</span>
</label>
</div>
@@ -367,8 +369,8 @@
</div>
</div>
<script src="/marked.min.js?v=2"></script>
<script src="/game.js?v=2"></script>
<script src="/marked.min.js?v=3"></script>
<script src="/game.js?v=3"></script>
<!-- Service Worker Registration -->
<script>
-21
View File
@@ -133,27 +133,6 @@ input[type="text"]:focus {
margin-bottom: 40px;
}
/* Private Room Toggle */
.private-room-toggle {
margin: 15px 0;
text-align: center;
}
.private-room-toggle label {
display: inline-flex;
align-items: center;
gap: 8px;
cursor: pointer;
font-size: 14px;
color: #6f6f6f;
}
.private-room-toggle input[type="checkbox"] {
width: 18px;
height: 18px;
cursor: pointer;
}
/* Invite Link Block */
#invite-link-block {
margin: 15px 0;
+138 -49
View File
@@ -1,26 +1,84 @@
const CACHE_NAME = 'czech-fool-v1';
const CACHE_TIMESTAMP_KEY = 'cache-timestamps';
const CACHE_MAX_AGE = 60 * 60 * 1000; // 1 час в миллисекундах
const urlsToCache = [
'/',
'/index.html',
'/style.css',
'/game.js',
'/sounds/playcard.ogg',
'/sounds/drawcard.ogg',
'/sounds/eight.ogg',
'/sounds/change.ogg',
'/sounds/skip.ogg',
'/sounds/alert.ogg',
'/sounds/chat.ogg',
'/sounds/win.ogg',
'/sounds/lose.ogg',
'/sounds/two.ogg',
'/sounds/six.ogg',
'/sounds/seven.ogg',
'/sounds/shuffle.ogg',
'/sounds/ace.ogg',
'/sounds/eightplace.ogg'
'/sounds/playcard.aac',
'/sounds/drawcard.aac',
'/sounds/eight.aac',
'/sounds/change.aac',
'/sounds/skip.aac',
'/sounds/alert.aac',
'/sounds/chat.aac',
'/sounds/win.aac',
'/sounds/lose.aac',
'/sounds/two.aac',
'/sounds/six.aac',
'/sounds/seven.aac',
'/sounds/shuffle.aac',
'/sounds/ace.aac',
'/sounds/eightplace.aac'
];
// Функция для получения временных меток из IndexedDB
async function getTimestamps() {
try {
const cache = await caches.open(CACHE_TIMESTAMP_KEY);
const response = await cache.match('timestamps');
if (response) {
return await response.json();
}
} catch (e) {
console.log('Error reading timestamps:', e);
}
return {};
}
// Функция для сохранения временных меток
async function saveTimestamps(timestamps) {
try {
const cache = await caches.open(CACHE_TIMESTAMP_KEY);
const response = new Response(JSON.stringify(timestamps));
await cache.put('timestamps', response);
} catch (e) {
console.log('Error saving timestamps:', e);
}
}
// Функция для очистки старых записей кеша
async function cleanOldCache() {
try {
const timestamps = await getTimestamps();
const now = Date.now();
const cache = await caches.open(CACHE_NAME);
const requests = await cache.keys();
let cleaned = 0;
for (const request of requests) {
const url = request.url;
const timestamp = timestamps[url];
// Если запись старше часа - удаляем
if (timestamp && (now - timestamp) > CACHE_MAX_AGE) {
await cache.delete(request);
delete timestamps[url];
cleaned++;
}
}
if (cleaned > 0) {
console.log(`Cleaned ${cleaned} old cache entries`);
await saveTimestamps(timestamps);
}
} catch (e) {
console.log('Error cleaning cache:', e);
}
}
// Установка service worker
self.addEventListener('install', event => {
event.waitUntil(
@@ -35,16 +93,21 @@ self.addEventListener('install', event => {
// Активация service worker
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== CACHE_NAME) {
console.log('Deleting old cache:', cacheName);
return caches.delete(cacheName);
}
})
);
})
Promise.all([
// Удаляем старые версии кеша
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== CACHE_NAME && cacheName !== CACHE_TIMESTAMP_KEY) {
console.log('Deleting old cache:', cacheName);
return caches.delete(cacheName);
}
})
);
}),
// Очищаем записи старше часа
cleanOldCache()
])
);
});
@@ -56,33 +119,59 @@ self.addEventListener('fetch', event => {
}
event.respondWith(
caches.match(event.request)
.then(response => {
// Возвращаем из кеша если есть
if (response) {
(async () => {
// Проверяем кеш
const cachedResponse = await caches.match(event.request);
if (cachedResponse) {
// Проверяем возраст записи
const timestamps = await getTimestamps();
const url = event.request.url;
const timestamp = timestamps[url];
const now = Date.now();
// Если запись свежая (младше часа) - возвращаем из кеша
if (timestamp && (now - timestamp) < CACHE_MAX_AGE) {
return cachedResponse;
}
// Если запись старая - удаляем и загружаем заново
console.log('Cache expired for:', url);
const cache = await caches.open(CACHE_NAME);
await cache.delete(event.request);
delete timestamps[url];
await saveTimestamps(timestamps);
}
// Загружаем с сервера
try {
const fetchRequest = event.request.clone();
const response = await fetch(fetchRequest);
// Проверяем валидность ответа
if (!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
// Клонируем запрос
const fetchRequest = event.request.clone();
// Кешируем новый ресурс с временной меткой
const responseToCache = response.clone();
const cache = await caches.open(CACHE_NAME);
await cache.put(event.request, responseToCache);
return fetch(fetchRequest).then(response => {
// Проверяем валидность ответа
if (!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
// Клонируем ответ
const responseToCache = response.clone();
// Кешируем новый ресурс
caches.open(CACHE_NAME)
.then(cache => {
cache.put(event.request, responseToCache);
});
return response;
});
})
// Сохраняем временную метку
const timestamps = await getTimestamps();
timestamps[event.request.url] = Date.now();
await saveTimestamps(timestamps);
return response;
} catch (error) {
console.log('Fetch failed:', error);
// Если есть старый кеш - возвращаем его как fallback
if (cachedResponse) {
return cachedResponse;
}
throw error;
}
})()
);
});