some fixes
This commit is contained in:
+13
-5
@@ -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
@@ -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>
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
})()
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user