diff --git a/game.js b/game.js
index bab6ed4..40a3483 100644
--- a/game.js
+++ b/game.js
@@ -220,7 +220,14 @@ function customConfirm(msg, onYes) {
btnInvite.textContent = '📤 Пригласить друзей';
btnInvite.onclick = () => {
const code = worldId || generateShortWorldCode();
- Telegram.WebApp.switchInlineQuery('play ' + code);
+ // 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);
@@ -234,69 +241,145 @@ function customConfirm(msg, onYes) {
try {
const resp = await fetch(SERVER_URL + '/api/tg/friends?tg_id=' + tgUser.id);
const data = await resp.json();
- if (!data.ok || !data.friends || !data.friends.length) {
- showToast('👥 Нет друзей. Поделись своим TG ID: ' + tgUser.id);
- return;
- }
- let html = '
';
- for (const f of data.friends) {
- if (f.online) {
- html += '
🟢 ' + f.name + ' — мир ' + f.world_id + '
';
- } else {
- html += '
⚫ ' + f.name + '
';
- }
- }
- html += '
';
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);
- const list = document.createElement('div');
- list.innerHTML = html;
- box.appendChild(list);
- // Add friend by TG ID
+ // Show nickname
+ 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);
+ } else {
+ // No nickname yet — set one
+ const nickDiv = document.createElement('div');
+ nickDiv.style.cssText = 'margin-bottom:12px;';
+ nickDiv.innerHTML = 'Задай ник, чтобы друзья могли тебя найти:
';
+ const nickInput = document.createElement('input');
+ 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.textContent = '✓';
+ nickBtn.onclick = async () => {
+ const n = nickInput.value.trim().toLowerCase();
+ if (!n || n.length < 2) { showToast('❌ Минимум 2 символа'); return; }
+ const check = await fetch(SERVER_URL + '/api/nick/check?nick=' + encodeURIComponent(n));
+ const cd = await check.json();
+ if (!cd.available) { showToast('❌ Ник занят'); return; }
+ const set = await fetch(SERVER_URL + '/api/nick/set', {method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({tg_id:tgUser.id,nickname:n})});
+ const sd = await set.json();
+ if (sd.ok) { showToast('✅ Ник: ' + sd.nickname); btnFriends.onclick(); } else { showToast('❌ Ошибка'); }
+ };
+ nickDiv.appendChild(nickInput);
+ nickDiv.appendChild(nickBtn);
+ box.appendChild(nickDiv);
+ }
+ // Friends list
+ if (data.friends && data.friends.length) {
+ const list = document.createElement('div');
+ list.style.cssText = 'margin-bottom:12px;';
+ 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;';
+ const statusDot = f.online ? '🟢' : '⚫';
+ const info = statusDot + ' ' + f.nickname + '' + (f.world_id ? ' — мир ' + f.world_id : '');
+ fDiv.innerHTML = '' + info + '
';
+ 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.textContent = '🎮 Вступить';
+ joinBtn.onclick = () => { worldId = f.world_id; overlay.remove(); resolve(worldId); };
+ fDiv.appendChild(joinBtn);
+ }
+ list.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.textContent = 'Пока нет друзей';
+ box.appendChild(noFriends);
+ }
+ // Pending friend requests
+ if (data.pending && data.pending.length) {
+ const pDiv = document.createElement('div');
+ pDiv.style.cssText = 'margin-bottom:12px;';
+ pDiv.innerHTML = '📨 Запросы в друзья:
';
+ 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;';
+ const span = document.createElement('span');
+ span.textContent = p.from;
+ pItem.appendChild(span);
+ const btns = document.createElement('div');
+ 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.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})});
+ const d = await r.json();
+ 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.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})});
+ showToast('Отклонено');
+ btnFriends.onclick();
+ };
+ btns.appendChild(acceptBtn);
+ btns.appendChild(declineBtn);
+ pItem.appendChild(btns);
+ pDiv.appendChild(pItem);
+ }
+ box.appendChild(pDiv);
+ }
+ // Add friend by nickname
const addDiv = document.createElement('div');
- addDiv.style.cssText = 'margin-top:16px;';
- addDiv.innerHTML = 'Добавить друга по TG ID:
';
+ addDiv.style.cssText = 'margin-top:12px;';
+ addDiv.innerHTML = 'Добавить друга по нику:
';
const addInput = document.createElement('input');
- addInput.type = 'number';
- addInput.placeholder = 'TG ID друга';
- addInput.style.cssText = 'width:70%;padding:10px;border:2px solid #f39c12;border-radius:8px;background:#16213e;color:#fff;font-size:16px;';
+ 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:25%;padding:10px;background:#f39c12;color:#fff;border:none;border-radius:8px;font-size:16px;cursor:pointer;margin-left:4px;';
+ 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.textContent = '+';
addBtn.onclick = async () => {
- const fid = parseInt(addInput.value);
- if (!fid) return;
- const r = await fetch(SERVER_URL + '/api/tg/friends/add', {method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({tg_id:tgUser.id,friend_id:fid})});
+ const nick = addInput.value.trim().toLowerCase();
+ if (!nick || nick.length < 2) { showToast('❌ Минимум 2 символа'); return; }
+ const r = await fetch(SERVER_URL + '/api/friends/request', {method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({tg_id:tgUser.id,nickname:nick})});
const d = await r.json();
- if (d.ok) { showToast('✅ Друг добавлен!'); btnFriends.click(); }
- else { showToast('❌ Ошибка'); }
+ if (d.ok) { showToast(d.message === 'Already friends' ? '✅ Уже друзья!' : '📨 Запрос отправлен!'); }
+ else { showToast('❌ ' + (d.error || 'Ошибка')); }
};
addDiv.appendChild(addInput);
addDiv.appendChild(addBtn);
box.appendChild(addDiv);
- // My TG ID
- const myId = document.createElement('div');
- myId.style.cssText = 'margin-top:12px;color:#888;font-size:13px;';
- myId.textContent = '🆔 Твой ID: ' + tgUser.id + ' — отправь другу, чтобы он добавил тебя';
- box.appendChild(myId);
- // Join online friend buttons
- const onlineFriends = (data.friends||[]).filter(f => f.online);
- if (onlineFriends.length) {
- for (const of2 of onlineFriends) {
- const joinBtn = document.createElement('button');
- joinBtn.style.cssText = 'width:100%;padding:12px;margin-top:8px;background:#27ae60;color:#fff;border:none;border-radius:10px;font-size:16px;cursor:pointer;';
- joinBtn.textContent = '🎮 Вступить к ' + of2.name + ' (мир ' + of2.world_id + ')';
- joinBtn.onclick = () => {
- worldId = of2.world_id;
- overlay.remove();
- resolve(worldId);
- };
- box.appendChild(joinBtn);
- }
- }
+ // Privacy settings
+ 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;';
+ const reqLabel = document.createElement('label');
+ reqLabel.style.cssText = 'cursor:pointer;';
+ const reqCb = document.createElement('input');
+ 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;';
diff --git a/index.html b/index.html
index 09875a8..0c3b89d 100644
--- a/index.html
+++ b/index.html
@@ -95,6 +95,6 @@
-
+