From 4ff7a490d9c709072fd1b2455ff288700169f0e0 Mon Sep 17 00:00:00 2001 From: kicer Date: Wed, 22 Jul 2026 11:35:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E5=8F=8C=E5=87=BB=E6=94=BE?= =?UTF-8?q?=E5=A4=A7=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/public/index.html | 164 +++++++++++++++++++++++++++++++++------ 1 file changed, 142 insertions(+), 22 deletions(-) diff --git a/server/public/index.html b/server/public/index.html index 1879d5a..848bd0f 100644 --- a/server/public/index.html +++ b/server/public/index.html @@ -5,45 +5,49 @@ 小财记账 + + + @@ -104,6 +123,7 @@

+
v2.2
@@ -118,7 +138,7 @@

小财记账

- @@ -288,12 +308,14 @@ messageCache = msgs || []; messagesContainer.innerHTML = messageCache.map(renderMessageHTML).join(''); scrollToBottom(); + bindMessageEvents(); } function appendMessage(msg) { messageCache.push(msg); messagesContainer.insertAdjacentHTML('beforeend', renderMessageHTML(msg)); scrollToBottom(); + bindMessageEvents(); } function replaceMessage(msgId, newMsg) { @@ -305,11 +327,52 @@ } else { appendMessage(newMsg); } + bindMessageEvents(); } function scrollToBottom() { messagesContainer.scrollTop = messagesContainer.scrollHeight; } - // WebSocket + // 双击全屏相关 + function bindMessageEvents() { + // 图片双击全屏 + document.querySelectorAll('.msg-img').forEach(img => { + img.removeEventListener('dblclick', onImageDblClick); + img.addEventListener('dblclick', onImageDblClick); + }); + // 气泡双击全屏 + document.querySelectorAll('.msg-bubble').forEach(bubble => { + bubble.removeEventListener('dblclick', onBubbleDblClick); + bubble.addEventListener('dblclick', onBubbleDblClick); + }); + } + + function onImageDblClick(e) { + e.stopPropagation(); + const imgSrc = e.target.src; + const overlay = document.createElement('div'); + overlay.className = 'fullscreen-overlay'; + overlay.innerHTML = ``; + overlay.addEventListener('click', () => overlay.remove()); + document.body.appendChild(overlay); + } + + function onBubbleDblClick(e) { + e.stopPropagation(); + const bubble = e.currentTarget; + // 克隆气泡内容,去掉事件 + const clone = bubble.cloneNode(true); + // 移除可能有的链接行为 + const overlay = document.createElement('div'); + overlay.className = 'fullscreen-overlay'; + const container = document.createElement('div'); + container.className = 'fullscreen-text'; + container.innerHTML = clone.innerHTML; + overlay.appendChild(container); + overlay.addEventListener('click', () => overlay.remove()); + document.body.appendChild(overlay); + } + + // WebSocket 重连 let wsReconnectTimer = null; let reconnectAttempts = 0; const MAX_RECONNECT_DELAY = 30000; @@ -381,11 +444,14 @@ document.getElementById('login-page').classList.add('hidden'); document.getElementById('main-page').classList.remove('hidden'); if (localStorage.getItem('isAdmin') === 'true') { - document.getElementById('create-room-btn').style.display = 'flex'; + document.getElementById('create-room-btn').classList.add('visible'); + } else { + document.getElementById('create-room-btn').classList.remove('visible'); } initWebSocket(); loadRooms(); updateSummaryPreview(); + initSwipeGestures(); return; } } catch(e) {} @@ -407,16 +473,68 @@ saveAuth(data); document.getElementById('login-page').classList.add('hidden'); document.getElementById('main-page').classList.remove('hidden'); - if (data.isAdmin) document.getElementById('create-room-btn').style.display = 'flex'; + if (data.isAdmin) { + document.getElementById('create-room-btn').classList.add('visible'); + } else { + document.getElementById('create-room-btn').classList.remove('visible'); + } initWebSocket(); loadRooms(); updateSummaryPreview(); + initSwipeGestures(); } else { const err = await res.json(); document.getElementById('login-error').textContent = err.error || '登录失败'; } } + // 修正滑动手势方向 + function initSwipeGestures() { + const chatPage = document.getElementById('chat-page'); + const purchaseOverlay = document.getElementById('purchase-panel-overlay'); + let startX = 0; + let startY = 0; + + function handleTouchStart(e) { + startX = e.touches[0].clientX; + startY = e.touches[0].clientY; + } + + function handleTouchEnd(e, target) { + if (!startX) return; + const endX = e.changedTouches[0].clientX; + const endY = e.changedTouches[0].clientY; + const diffX = endX - startX; + const diffY = endY - startY; + if (Math.abs(diffX) > Math.abs(diffY) && Math.abs(diffX) > 50) { + if (target === chatPage && !purchaseOverlay.classList.contains('hidden')) { + // 采购清单打开时,任意水平滑动都关闭 + if (Math.abs(diffX) > 30) { + closePurchasePanel(); + } + } else if (target === chatPage) { + // 右滑返回列表,左滑打开采购清单 + if (diffX > 30) { + showList(); + } else if (diffX < -30) { + openPurchasePanel(); + } + } else if (target === purchaseOverlay) { + // 采购清单上任意滑动都关闭 + if (Math.abs(diffX) > 30) { + closePurchasePanel(); + } + } + } + startX = 0; startY = 0; + } + + chatPage.addEventListener('touchstart', handleTouchStart, { passive: true }); + chatPage.addEventListener('touchend', (e) => handleTouchEnd(e, chatPage), { passive: true }); + purchaseOverlay.addEventListener('touchstart', handleTouchStart, { passive: true }); + purchaseOverlay.addEventListener('touchend', (e) => handleTouchEnd(e, purchaseOverlay), { passive: true }); + } + async function loadRooms() { const token = getToken(); const res = await fetch(API + '/api/rooms', { headers: { 'Authorization': `Bearer ${token}` } }); @@ -438,11 +556,14 @@
${room.name}
${escapeHtml(lastMsg)}
-
${lastTime}
- ${isAdmin ? ` - ` : ''} +
+
${lastTime}
+ ${isAdmin ? `
+ +
` : ''} +
`; }).join(''); } @@ -622,7 +743,6 @@ loadRooms(); } - // 群聊管理 function openManageRoom(roomId) { const room = rooms.find(r => r.id === roomId); if (!room) return;