From 547ad869893b8583dea9ffa14fdbe676c82eaab4 Mon Sep 17 00:00:00 2001 From: Mk Date: Wed, 27 May 2026 04:54:39 +0000 Subject: [PATCH] feat: minecraft-style start menu with proper spacing --- game.js | 330 ++++++++++++++++++++++++++++++++++------------------- index.html | 2 +- 2 files changed, 211 insertions(+), 121 deletions(-) diff --git a/game.js b/game.js index 40a3483..7f1bd07 100644 --- a/game.js +++ b/game.js @@ -106,87 +106,143 @@ function customConfirm(msg, onYes) { return; } + // ===== Minecraft-style CSS ===== + const mcCSS = ` + .mc-overlay { position:fixed;top:0;left:0;width:100%;height:100%;z-index:99999; + display:flex;align-items:center;justify-content:center;font-family:'Courier New',monospace; + image-rendering:pixelated; } + .mc-bg { position:absolute;inset:0;background:#000;opacity:0.75; } + .mc-dirt { position:absolute;bottom:0;left:0;right:0;height:40%; + background:repeating-linear-gradient(0deg,#8B6914 0px,#8B6914 2px,#7A5B12 2px,#7A5B12 4px);opacity:0.3; } + .mc-box { position:relative;z-index:1;background:#C6C6C6;border:4px solid #000; + padding:0;max-width:420px;width:92%;box-shadow:4px 4px 0 #000; } + .mc-titlebar { background:#1a1a2e;padding:12px 16px;text-align:center; + border-bottom:4px solid #000; } + .mc-title { font-size:24px;font-weight:bold;color:#FFAA00;text-shadow:2px 2px 0 #000; + letter-spacing:2px; } + .mc-subtitle { font-size:13px;color:#AAA;margin-top:4px; } + .mc-body { padding:16px;background:#C6C6C6; } + .mc-btn { display:block;width:100%;padding:10px 16px;margin-bottom:8px; + font-family:'Courier New',monospace;font-size:16px;font-weight:bold; + cursor:pointer;text-align:center;border:3px solid #000; + image-rendering:pixelated;box-shadow:3px 3px 0 #000; + transition:transform 0.05s,box-shadow 0.05s; } + .mc-btn:active { transform:translate(2px,2px);box-shadow:1px 1px 0 #000; } + .mc-btn-green { background:#5A8F3C;color:#E0E0E0;border-color:#3A5F1C;text-shadow:1px 1px 0 #222; } + .mc-btn-green:hover { background:#6DAF4E; } + .mc-btn-blue { background:#3C5F9E;color:#E0E0E0;border-color:#2A4070;text-shadow:1px 1px 0 #222; } + .mc-btn-blue:hover { background:#4B73BE; } + .mc-btn-purple { background:#7B3FA0;color:#E0E0E0;border-color:#5A2C78;text-shadow:1px 1px 0 #222; } + .mc-btn-purple:hover { background:#9555BE; } + .mc-btn-orange { background:#B86E00;color:#E0E0E0;border-color:#8A5200;text-shadow:1px 1px 0 #222; } + .mc-btn-orange:hover { background:#DA8500; } + .mc-btn-red { background:#9E2B2B;color:#E0E0E0;border-color:#6E1B1B;text-shadow:1px 1px 0 #222; } + .mc-btn-red:hover { background:#BE3B3B; } + .mc-btn-gray { background:#555;color:#AAA;border-color:#333;text-shadow:1px 1px 0 #111; } + .mc-btn-gray:hover { background:#666;color:#DDD; } + .mc-btn-outline { background:transparent;color:#555;border-color:#555; + text-shadow:none;box-shadow:2px 2px 0 #333; } + .mc-btn-outline:hover { background:#DDD;color:#222; } + .mc-input { width:100%;padding:8px 12px;font-family:'Courier New',monospace; + font-size:16px;background:#FFF;border:3px solid #000;color:#222; + box-shadow:inset 2px 2px 0 #999;margin:4px 0; } + .mc-input:focus { outline:none;border-color:#FFAA00; } + .mc-label { font-size:13px;color:#444;font-weight:bold;margin:8px 0 4px; } + .mc-divider { border:none;border-top:2px solid #999;margin:12px 0; } + .mc-friend-row { display:flex;justify-content:space-between;align-items:center; + padding:6px 8px;margin-bottom:4px;background:#E8E8E8;border:2px solid #999; + box-shadow:2px 2px 0 #999; } + .mc-friend-btn { padding:4px 10px;font-family:'Courier New',monospace; + font-size:13px;font-weight:bold;cursor:pointer;border:2px solid #000; + box-shadow:1px 1px 0 #000; } + .mc-friend-btn:active { transform:translate(1px,1px);box-shadow:none; } + .mc-friend-btn-green { background:#5A8F3C;color:#E0E0E0; } + .mc-friend-btn-red { background:#9E2B2B;color:#E0E0E0; } + .mc-checkbox-row { display:flex;align-items:center;gap:8px;font-size:13px;color:#444;cursor:pointer; } + .mc-checkbox { width:18px;height:18px;accent-color:#5A8F3C; } + `; + + const styleEl = document.createElement('style'); + styleEl.textContent = mcCSS; + document.head.appendChild(styleEl); + const overlay = document.createElement('div'); + overlay.className = 'mc-overlay'; overlay.id = 'startMenu'; - overlay.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.85);display:flex;align-items:center;justify-content:center;z-index:99999;font-family:Arial,sans-serif;'; + overlay.innerHTML = '
'; const box = document.createElement('div'); - box.style.cssText = 'background:#1a1a2e;border:2px solid #e94560;border-radius:16px;padding:32px;max-width:400px;width:90%;text-align:center;color:#eee;'; + box.className = 'mc-box'; - // Title - const title = document.createElement('div'); - title.style.cssText = 'font-size:28px;font-weight:bold;margin-bottom:8px;color:#e94560;'; - title.textContent = '🏗️ GrechkaCraft'; - box.appendChild(title); + // Title bar + const titleBar = document.createElement('div'); + titleBar.className = 'mc-titlebar'; + titleBar.innerHTML = '
⛏️ GrechkaCraft
' + + '
' + (isTgWebApp ? ('Привет, ' + (tgUser?.first_name || 'Игрок') + '!') : 'Voxel-мир в браузере') + '
'; + box.appendChild(titleBar); - const subtitle = document.createElement('div'); - subtitle.style.cssText = 'font-size:14px;color:#888;margin-bottom:24px;'; - subtitle.textContent = isTgWebApp ? ('Привет, ' + (tgUser?.first_name || 'Игрок') + '!') : 'Voxel-мир в браузере'; - box.appendChild(subtitle); + const body = document.createElement('div'); + body.className = 'mc-body'; - // New World button + // === Buttons === + // New World const btnNew = document.createElement('button'); - btnNew.style.cssText = 'width:100%;padding:14px;margin-bottom:12px;background:#27ae60;color:#fff;border:none;border-radius:10px;font-size:18px;cursor:pointer;font-weight:bold;'; + btnNew.className = 'mc-btn mc-btn-green'; btnNew.textContent = '🌍 Новый мир'; - btnNew.onmouseover = () => btnNew.style.background = '#2ecc71'; - btnNew.onmouseout = () => btnNew.style.background = '#27ae60'; btnNew.onclick = () => { worldId = generateShortWorldCode(); overlay.remove(); + styleEl.remove(); resolve(worldId); }; - box.appendChild(btnNew); + body.appendChild(btnNew); - // Join World button + // Join by code const btnJoin = document.createElement('button'); - btnJoin.style.cssText = 'width:100%;padding:14px;margin-bottom:12px;background:#2980b9;color:#fff;border:none;border-radius:10px;font-size:18px;cursor:pointer;font-weight:bold;'; + btnJoin.className = 'mc-btn mc-btn-blue'; btnJoin.textContent = '🔗 Вступить по коду'; - btnJoin.onmouseover = () => btnJoin.style.background = '#3498db'; - btnJoin.onmouseout = () => btnJoin.style.background = '#2980b9'; btnJoin.onclick = () => { + body.innerHTML = ''; + const lbl = document.createElement('div'); + lbl.className = 'mc-label'; + lbl.textContent = 'Код мира:'; + body.appendChild(lbl); const codeInput = document.createElement('input'); + codeInput.className = 'mc-input'; codeInput.type = 'text'; - codeInput.placeholder = 'Введите код мира (например: bkh237)'; - codeInput.style.cssText = 'width:90%;padding:12px;margin:12px 0;border:2px solid #3498db;border-radius:8px;background:#16213e;color:#fff;font-size:16px;text-align:center;text-transform:lowercase;'; + codeInput.placeholder = 'bkh237'; codeInput.maxLength = 12; - box.innerHTML = ''; - const backTitle = document.createElement('div'); - backTitle.style.cssText = 'font-size:20px;font-weight:bold;margin-bottom:16px;color:#3498db;'; - backTitle.textContent = '🔗 Вступить в мир'; - box.appendChild(backTitle); - box.appendChild(codeInput); + body.appendChild(codeInput); const btnGo = document.createElement('button'); - btnGo.style.cssText = 'width:100%;padding:14px;margin-top:12px;background:#2980b9;color:#fff;border:none;border-radius:10px;font-size:18px;cursor:pointer;font-weight:bold;'; - btnGo.textContent = 'Войти'; + btnGo.className = 'mc-btn mc-btn-blue'; + btnGo.textContent = 'Войти →'; btnGo.onclick = () => { const code = codeInput.value.trim().toLowerCase(); if (code.length >= 3) { worldId = code; overlay.remove(); + styleEl.remove(); resolve(worldId); } }; - box.appendChild(btnGo); + body.appendChild(btnGo); const btnBack = document.createElement('button'); - btnBack.style.cssText = 'width:100%;padding:10px;margin-top:8px;background:transparent;color:#888;border:1px solid #444;border-radius:8px;cursor:pointer;font-size:14px;'; + btnBack.className = 'mc-btn mc-btn-gray'; btnBack.textContent = '← Назад'; - btnBack.onclick = () => { overlay.remove(); showStartMenu().then(resolve); }; - box.appendChild(btnBack); + btnBack.onclick = () => { overlay.remove(); styleEl.remove(); showStartMenu().then(resolve); }; + body.appendChild(btnBack); codeInput.focus(); codeInput.addEventListener('keydown', (e) => { if (e.key === 'Enter') btnGo.click(); }); }; - box.appendChild(btnJoin); + body.appendChild(btnJoin); - // History / Continue button (only if TG user with saved game OR localStorage save) + // Continue saved game const hasLocalSave = !!localStorage.getItem('minegrechka_save'); if (isTgWebApp || hasLocalSave) { const btnHistory = document.createElement('button'); - btnHistory.style.cssText = 'width:100%;padding:14px;margin-bottom:12px;background:#8e44ad;color:#fff;border:none;border-radius:10px;font-size:18px;cursor:pointer;font-weight:bold;'; + btnHistory.className = 'mc-btn mc-btn-purple'; btnHistory.textContent = '💾 Продолжить игру'; - btnHistory.onmouseover = () => btnHistory.style.background = '#9b59b6'; - btnHistory.onmouseout = () => btnHistory.style.background = '#8e44ad'; btnHistory.onclick = async () => { - // TG user: load save from server if (isTgWebApp && tgUser) { try { const resp = await fetch(SERVER_URL + '/api/tg/save?tg_id=' + tgUser.id); @@ -195,75 +251,89 @@ function customConfirm(msg, onYes) { worldId = data.world_id; tgSaveLoaded = true; overlay.remove(); + styleEl.remove(); resolve(worldId); return; } } catch(e) { console.warn('[TG] Load save failed:', e); } } - // Fallback: load from latest localStorage save if (hasLocalSave) { - // Generate world from save (worldSeed based) worldId = generateShortWorldCode(); overlay.remove(); + styleEl.remove(); resolve(worldId); return; } customAlert('Сохранений не найдено'); }; - box.appendChild(btnHistory); + body.appendChild(btnHistory); } - // TG Share button (only in TG context) + // === TG-only buttons === if (isTgWebApp && window.Telegram && Telegram.WebApp.switchInlineQuery) { + // Invite friends — with margin const btnInvite = document.createElement('button'); - btnInvite.style.cssText = 'width:100%;padding:10px;margin-top:8px;background:transparent;color:#3498db;border:1px solid #3498db;border-radius:8px;cursor:pointer;font-size:14px;'; + btnInvite.className = 'mc-btn mc-btn-outline'; + btnInvite.style.marginTop = '16px'; btnInvite.textContent = '📤 Пригласить друзей'; btnInvite.onclick = () => { const code = worldId || generateShortWorldCode(); - // Share: open TG share dialog with game link const url = 'https://t.me/Grechkacraft_bot/app?startapp=' + encodeURIComponent(code); if (Telegram.WebApp && Telegram.WebApp.openTelegramLink) { Telegram.WebApp.openTelegramLink('https://t.me/share/url?url=' + encodeURIComponent(url) + '&text=' + encodeURIComponent('🏗️ Заходи в GrechkaCraft! Мир: ' + code)); } else { - // Fallback: copy invite link navigator.clipboard.writeText(url).then(() => showToast('📋 Скопировано!')).catch(() => showToast(url)); } }; - box.appendChild(btnInvite); + body.appendChild(btnInvite); - // Friends button (TG only) + // Friends — with margin const btnFriends = document.createElement('button'); - btnFriends.style.cssText = 'width:100%;padding:14px;margin-bottom:12px;background:#f39c12;color:#fff;border:none;border-radius:10px;font-size:18px;cursor:pointer;font-weight:bold;'; + btnFriends.className = 'mc-btn mc-btn-orange'; + btnFriends.style.marginTop = '8px'; btnFriends.textContent = '👥 Друзья'; - btnFriends.onmouseover = () => btnFriends.style.background = '#e67e22'; - btnFriends.onmouseout = () => btnFriends.style.background = '#f39c12'; btnFriends.onclick = async () => { try { const resp = await fetch(SERVER_URL + '/api/tg/friends?tg_id=' + tgUser.id); const data = await resp.json(); - box.innerHTML = ''; - const ft = document.createElement('div'); - ft.style.cssText = 'font-size:20px;font-weight:bold;margin-bottom:8px;color:#f39c12;'; - ft.textContent = '👥 Друзья'; - box.appendChild(ft); - // Show nickname + body.innerHTML = ''; + + // Back button at top + const btnBackTop = document.createElement('button'); + btnBackTop.className = 'mc-btn mc-btn-gray'; + btnBackTop.textContent = '← Назад'; + btnBackTop.style.marginBottom = '12px'; + btnBackTop.onclick = () => { overlay.remove(); styleEl.remove(); showStartMenu().then(resolve); }; + body.appendChild(btnBackTop); + + // Nickname section if (data.nickname) { const nickDiv = document.createElement('div'); - nickDiv.style.cssText = 'color:#2ecc71;font-size:14px;margin-bottom:12px;'; - nickDiv.textContent = '🔗 Твой ник: ' + data.nickname; - box.appendChild(nickDiv); + nickDiv.className = 'mc-friend-row'; + nickDiv.innerHTML = '🔗 Твой ник: ' + data.nickname + ''; + nickDiv.style.background = '#D5E8C5'; + body.appendChild(nickDiv); } else { - // No nickname yet — set one - const nickDiv = document.createElement('div'); - nickDiv.style.cssText = 'margin-bottom:12px;'; - nickDiv.innerHTML = '
Задай ник, чтобы друзья могли тебя найти:
'; + const nickLabel = document.createElement('div'); + nickLabel.className = 'mc-label'; + nickLabel.style.color = '#9E2B2B'; + nickLabel.textContent = '⚡ Задай ник, чтобы друзья могли тебя найти:'; + body.appendChild(nickLabel); + const nickRow = document.createElement('div'); + nickRow.style.display = 'flex'; + nickRow.style.gap = '4px'; + nickRow.style.marginBottom = '8px'; const nickInput = document.createElement('input'); + nickInput.className = 'mc-input'; + nickInput.style.flex = '1'; nickInput.type = 'text'; nickInput.maxLength = 16; nickInput.placeholder = 'Твой ник'; - nickInput.style.cssText = 'width:65%;padding:10px;border:2px solid #f39c12;border-radius:8px;background:#16213e;color:#fff;font-size:16px;'; const nickBtn = document.createElement('button'); - nickBtn.style.cssText = 'width:28%;padding:10px;background:#f39c12;color:#fff;border:none;border-radius:8px;font-size:16px;cursor:pointer;margin-left:4px;'; + nickBtn.className = 'mc-btn mc-btn-green'; + nickBtn.style.width = 'auto'; + nickBtn.style.marginBottom = '0'; + nickBtn.style.padding = '8px 16px'; nickBtn.textContent = '✓'; nickBtn.onclick = async () => { const n = nickInput.value.trim().toLowerCase(); @@ -275,50 +345,61 @@ function customConfirm(msg, onYes) { const sd = await set.json(); if (sd.ok) { showToast('✅ Ник: ' + sd.nickname); btnFriends.onclick(); } else { showToast('❌ Ошибка'); } }; - nickDiv.appendChild(nickInput); - nickDiv.appendChild(nickBtn); - box.appendChild(nickDiv); + nickRow.appendChild(nickInput); + nickRow.appendChild(nickBtn); + body.appendChild(nickRow); } + // Friends list if (data.friends && data.friends.length) { - const list = document.createElement('div'); - list.style.cssText = 'margin-bottom:12px;'; + const listLabel = document.createElement('div'); + listLabel.className = 'mc-label'; + listLabel.textContent = '👥 Друзья:'; + body.appendChild(listLabel); for (const f of data.friends) { const fDiv = document.createElement('div'); - fDiv.style.cssText = 'padding:6px 0;border-bottom:1px solid #333;display:flex;justify-content:space-between;align-items:center;'; + fDiv.className = 'mc-friend-row'; const statusDot = f.online ? '🟢' : '⚫'; - const info = statusDot + ' ' + f.nickname + '' + (f.world_id ? ' — мир ' + f.world_id : ''); - fDiv.innerHTML = '
' + info + '
'; + let info = statusDot + ' ' + f.nickname + ''; + if (f.online && f.world_id) info += ' — мир ' + f.world_id; + const fInfo = document.createElement('div'); + fInfo.innerHTML = info; + fDiv.appendChild(fInfo); if (f.online && f.world_id) { const joinBtn = document.createElement('button'); - joinBtn.style.cssText = 'padding:4px 10px;background:#27ae60;color:#fff;border:none;border-radius:6px;font-size:12px;cursor:pointer;'; + joinBtn.className = 'mc-friend-btn mc-friend-btn-green'; joinBtn.textContent = '🎮 Вступить'; - joinBtn.onclick = () => { worldId = f.world_id; overlay.remove(); resolve(worldId); }; + joinBtn.onclick = () => { worldId = f.world_id; overlay.remove(); styleEl.remove(); resolve(worldId); }; fDiv.appendChild(joinBtn); } - list.appendChild(fDiv); + body.appendChild(fDiv); } - box.appendChild(list); } else if (data.friends && !data.friends.length) { const noFriends = document.createElement('div'); - noFriends.style.cssText = 'color:#888;font-size:14px;margin-bottom:12px;'; + noFriends.className = 'mc-label'; + noFriends.style.color = '#888'; noFriends.textContent = 'Пока нет друзей'; - box.appendChild(noFriends); + body.appendChild(noFriends); } - // Pending friend requests + + // Pending requests if (data.pending && data.pending.length) { - const pDiv = document.createElement('div'); - pDiv.style.cssText = 'margin-bottom:12px;'; - pDiv.innerHTML = '
📨 Запросы в друзья:
'; + const pLabel = document.createElement('div'); + pLabel.className = 'mc-label'; + pLabel.style.color = '#B86E00'; + pLabel.textContent = '📨 Запросы в друзья:'; + body.appendChild(pLabel); for (const p of data.pending) { const pItem = document.createElement('div'); - pItem.style.cssText = 'display:flex;justify-content:space-between;align-items:center;padding:4px 0;border-bottom:1px solid #222;'; + pItem.className = 'mc-friend-row'; const span = document.createElement('span'); span.textContent = p.from; pItem.appendChild(span); const btns = document.createElement('div'); + btns.style.display = 'flex'; + btns.style.gap = '4px'; const acceptBtn = document.createElement('button'); - acceptBtn.style.cssText = 'padding:4px 8px;background:#27ae60;color:#fff;border:none;border-radius:4px;font-size:12px;cursor:pointer;margin-right:4px;'; + acceptBtn.className = 'mc-friend-btn mc-friend-btn-green'; acceptBtn.textContent = '✓'; acceptBtn.onclick = async () => { const r = await fetch(SERVER_URL + '/api/friends/accept', {method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({tg_id:tgUser.id,request_id:p.id})}); @@ -326,7 +407,7 @@ function customConfirm(msg, onYes) { if (d.ok) { showToast('✅ Друг добавлен!'); btnFriends.onclick(); } else { showToast('❌ Ошибка'); } }; const declineBtn = document.createElement('button'); - declineBtn.style.cssText = 'padding:4px 8px;background:#e74c3c;color:#fff;border:none;border-radius:4px;font-size:12px;cursor:pointer;'; + declineBtn.className = 'mc-friend-btn mc-friend-btn-red'; declineBtn.textContent = '✕'; declineBtn.onclick = async () => { await fetch(SERVER_URL + '/api/friends/decline', {method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({tg_id:tgUser.id,request_id:p.id})}); @@ -336,21 +417,31 @@ function customConfirm(msg, onYes) { btns.appendChild(acceptBtn); btns.appendChild(declineBtn); pItem.appendChild(btns); - pDiv.appendChild(pItem); + body.appendChild(pItem); } - box.appendChild(pDiv); } - // Add friend by nickname - const addDiv = document.createElement('div'); - addDiv.style.cssText = 'margin-top:12px;'; - addDiv.innerHTML = '
Добавить друга по нику:
'; + + // Add friend + body.appendChild(document.createElement('hr')); + body.className = 'mc-label'; + const addLabel = document.createElement('div'); + addLabel.className = 'mc-label'; + addLabel.textContent = '➕ Добавить друга по нику:'; + body.appendChild(addLabel); + const addRow = document.createElement('div'); + addRow.style.display = 'flex'; + addRow.style.gap = '4px'; const addInput = document.createElement('input'); + addInput.className = 'mc-input'; + addInput.style.flex = '1'; addInput.type = 'text'; addInput.maxLength = 16; addInput.placeholder = 'Ник друга'; - addInput.style.cssText = 'width:65%;padding:10px;border:2px solid #f39c12;border-radius:8px;background:#16213e;color:#fff;font-size:16px;'; const addBtn = document.createElement('button'); - addBtn.style.cssText = 'width:28%;padding:10px;background:#3498db;color:#fff;border:none;border-radius:8px;font-size:16px;cursor:pointer;margin-left:4px;'; + addBtn.className = 'mc-btn mc-btn-blue'; + addBtn.style.width = 'auto'; + addBtn.style.marginBottom = '0'; + addBtn.style.padding = '8px 16px'; addBtn.textContent = '+'; addBtn.onclick = async () => { const nick = addInput.value.trim().toLowerCase(); @@ -360,68 +451,67 @@ function customConfirm(msg, onYes) { if (d.ok) { showToast(d.message === 'Already friends' ? '✅ Уже друзья!' : '📨 Запрос отправлен!'); } else { showToast('❌ ' + (d.error || 'Ошибка')); } }; - addDiv.appendChild(addInput); - addDiv.appendChild(addBtn); - box.appendChild(addDiv); - // Privacy settings + addRow.appendChild(addInput); + addRow.appendChild(addBtn); + body.appendChild(addRow); + + // Privacy checkboxes const settings = data.settings || { allow_requests: 1, notify_online: 1 }; const settingsDiv = document.createElement('div'); - settingsDiv.style.cssText = 'margin-top:12px;display:flex;gap:12px;font-size:13px;color:#888;'; + settingsDiv.style.marginTop = '12px'; const reqLabel = document.createElement('label'); - reqLabel.style.cssText = 'cursor:pointer;'; + reqLabel.className = 'mc-checkbox-row'; const reqCb = document.createElement('input'); + reqCb.className = 'mc-checkbox'; reqCb.type = 'checkbox'; reqCb.checked = settings.allow_requests; - reqCb.style.cssText = 'margin-right:4px;'; reqCb.onchange = async () => { await fetch(SERVER_URL + '/api/friends/settings', {method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({tg_id:tgUser.id,allow_requests:reqCb.checked?1:0,notify_online:settings.notify_online})}); }; reqLabel.appendChild(reqCb); reqLabel.appendChild(document.createTextNode(' Запросы в друзья')); settingsDiv.appendChild(reqLabel); - box.appendChild(settingsDiv); - // Back button - const btnBackF = document.createElement('button'); - btnBackF.style.cssText = 'width:100%;padding:10px;margin-top:12px;background:transparent;color:#888;border:1px solid #444;border-radius:8px;cursor:pointer;font-size:14px;'; - btnBackF.textContent = '← Назад'; - btnBackF.onclick = () => { overlay.remove(); showStartMenu().then(resolve); }; - box.appendChild(btnBackF); + body.appendChild(settingsDiv); } catch(e) { showToast('❌ Ошибка загрузки друзей'); console.error(e); } }; - box.appendChild(btnFriends); + body.appendChild(btnFriends); } - // Player name input (if not set) + // Player name input if (!playerName) { + const nameDivider = document.createElement('hr'); + nameDivider.className = 'mc-divider'; + body.appendChild(nameDivider); + const nameLabel = document.createElement('div'); + nameLabel.className = 'mc-label'; + nameLabel.textContent = 'Твоё имя:'; + body.appendChild(nameLabel); const nameInput = document.createElement('input'); + nameInput.className = 'mc-input'; nameInput.type = 'text'; nameInput.placeholder = 'Ваше имя'; - nameInput.style.cssText = 'width:90%;padding:10px;margin:16px 0 8px;border:2px solid #e94560;border-radius:8px;background:#16213e;color:#fff;font-size:16px;text-align:center;'; nameInput.value = tgUser ? (tgUser.username || tgUser.first_name || '') : ''; nameInput.maxLength = 20; - box.appendChild(nameInput); - - // Update playerName on input nameInput.addEventListener('input', () => { if (nameInput.value.trim()) { playerName = nameInput.value.trim(); localStorage.setItem('minegrechka_playerName', playerName); } }); - box.appendChild(document.createElement('br')); + body.appendChild(nameInput); } + box.appendChild(body); overlay.appendChild(box); document.body.appendChild(overlay); - // If TG user without world in URL, also try to auto-load their save + // Auto-load TG save if (isTgWebApp && tgUser && !worldParam) { fetch(SERVER_URL + '/api/tg/save?tg_id=' + tgUser.id) .then(r => r.json()) .then(data => { if (data.ok && data.world_id) { - // Update the "Continue" button to show the world code - const historyBtn = box.querySelector('button:nth-child(5)'); // rough + // could update UI but menu is already shown } }) .catch(() => {}); diff --git a/index.html b/index.html index 0c3b89d..a0a81ad 100644 --- a/index.html +++ b/index.html @@ -95,6 +95,6 @@ - +