From bedc7f1cc8d01809227a1b88f3966f2bd9fff355 Mon Sep 17 00:00:00 2001 From: shuaiplus <2327005759@qq.com> Date: Sat, 31 May 2025 14:17:29 +0800 Subject: [PATCH] =?UTF-8?q?=E7=95=A5=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/css/style.css | 73 +++++++++++++++++++++++++----------------- client/js/chat.js | 7 ++-- client/js/util.file.js | 49 ++++++++++++++++++++++++---- 3 files changed, 89 insertions(+), 40 deletions(-) diff --git a/client/css/style.css b/client/css/style.css index 4ca7b11..975952e 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -997,27 +997,13 @@ body { /* File message styles */ /* 文件消息样式 */ -.file-message { - max-width: 320px; - border-radius: 16px; - margin: 6px 0; - font-family: inherit; - background: rgba(255, 255, 255, 0.95); - border: 1px solid rgba(48, 168, 247, 0.1); - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); - transition: all 0.2s ease; -} - -.file-message:hover { - transform: translateY(-1px); - box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1); -} .file-main-content { display: flex; align-items: center; - padding: 12px 16px; + padding: 6px 6px; gap: 12px; + max-width: 200px; } .file-info { @@ -1058,21 +1044,49 @@ body { .file-download-btn { padding: 10px; - background: linear-gradient(135deg, #30a8f7, #4fc3f7); + background: linear-gradient(135deg, #52abff, #4fc3f7); color: white; border: none; border-radius: 12px; font-size: 12px; font-weight: 600; cursor: pointer; - transition: all 0.2s ease; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); display: none; align-items: center; justify-content: center; width: 40px; height: 40px; flex-shrink: 0; - box-shadow: 0 2px 8px rgba(48, 168, 247, 0.3); + opacity: 0; + transform: scale(0.8) translateY(5px); + position: relative; + overflow: hidden; +} + +.file-download-btn.show { + opacity: 1; + transform: scale(1) translateY(0); + display: flex; +} + +.file-download-btn.show.animate-in { + animation: downloadBtnAppear 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); +} + +@keyframes downloadBtnAppear { + 0% { + opacity: 0; + transform: scale(0.6) translateY(10px) rotate(-5deg); + } + 60% { + opacity: 1; + transform: scale(1.1) translateY(-2px) rotate(2deg); + } + 100% { + opacity: 1; + transform: scale(1) translateY(0) rotate(0deg); + } } .file-download-btn svg { @@ -1084,12 +1098,10 @@ body { .file-download-btn:hover { background: linear-gradient(135deg, #2196f3, #42a5f5); transform: translateY(-2px); - box-shadow: 0 4px 16px rgba(48, 168, 247, 0.4); } .file-download-btn:active { transform: translateY(0); - box-shadow: 0 2px 8px rgba(48, 168, 247, 0.3); } .file-download-btn:disabled { @@ -1102,6 +1114,16 @@ body { .file-progress-container { padding: 0 16px 12px; margin-top: -4px; + opacity: 1; + max-height: 60px; + overflow: hidden; + transition: opacity 0.4s ease, max-height 0.4s ease, padding 0.4s ease; +} + +.file-progress-container.fade-out { + opacity: 0; + max-height: 0; + padding: 0 16px 0; } .file-progress-bar { @@ -1112,6 +1134,7 @@ body { overflow: hidden; margin-bottom: 8px; box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); + transition: opacity 0.3s ease; } .file-progress { @@ -1160,9 +1183,6 @@ body { box-shadow: 0 2px 8px rgba(255, 193, 7, 0.1); } -.bubble.private-message .file-message:hover { - box-shadow: 0 4px 16px rgba(255, 193, 7, 0.2); -} .bubble.private-message .file-message .file-download-btn { background: linear-gradient(135deg, #ff9800, #ffb74d); @@ -1567,11 +1587,6 @@ body { } } -/* File message animation enhancements */ -/* 文件消息动画增强 */ -.file-message { - animation: fadeInUp 0.3s ease-out; -} @keyframes fadeInUp { from { diff --git a/client/js/chat.js b/client/js/chat.js index dc4f502..0de7532 100644 --- a/client/js/chat.js +++ b/client/js/chat.js @@ -306,12 +306,11 @@ function renderFileMessage(fileData, isSender) { } else if (transfer.status === 'completed') { // 完成时不显示任何状态,只显示下载按钮 downloadBtnStyle = isSender ? 'display: none;' : 'display: flex;'; - } - } else if (isSender) { + } } else if (isSender) { // 发送方历史消息,不显示状态和下载按钮 downloadBtnStyle = 'display: none;'; } else { - // 接收方历史消息,直接显示下载按钮 + // 接收方历史消息,直接显示下载按钮(带动画效果) downloadBtnStyle = 'display: flex;'; } // Different icon for archives vs single files @@ -327,7 +326,7 @@ function renderFileMessage(fileData, isSender) {
${displayMeta}
- diff --git a/client/js/util.file.js b/client/js/util.file.js index ac09dc3..d4ced1d 100644 --- a/client/js/util.file.js +++ b/client/js/util.file.js @@ -537,9 +537,9 @@ async function sendVolumes(fileId, volumes, onSend, updateProgress, fileName) { function updateFileProgress(fileId) { const transfer = window.fileTransfers.get(fileId); if (!transfer) return; - const elements = document.querySelectorAll(`[data-file-id="${fileId}"]`); elements.forEach(element => { + const progressContainer = element.querySelector('.file-progress-container'); const progressBar = element.querySelector('.file-progress'); const statusText = element.querySelector('.file-status'); const downloadBtn = element.querySelector('.file-download-btn'); @@ -549,24 +549,59 @@ function updateFileProgress(fileId) { if (transfer.status === 'sending') { const progress = (transfer.sentVolumes / transfer.totalVolumes) * 100; + if (progressContainer) { + progressContainer.style.display = 'block'; + progressContainer.classList.remove('fade-out'); + } if (progressBar) progressBar.style.width = `${progress}%`; if (statusText) statusText.textContent = `Sending ${transfer.sentVolumes}/${transfer.totalVolumes}`; - if (downloadBtn) downloadBtn.style.display = 'none'; + if (downloadBtn) { + downloadBtn.classList.remove('show', 'animate-in'); + downloadBtn.style.display = 'none'; + } } else if (transfer.status === 'receiving') { const progress = (transfer.receivedVolumes.size / transfer.totalVolumes) * 100; + if (progressContainer) { + progressContainer.style.display = 'block'; + progressContainer.classList.remove('fade-out'); + } if (progressBar) progressBar.style.width = `${progress}%`; if (statusText) statusText.textContent = `Receiving ${transfer.receivedVolumes.size}/${transfer.totalVolumes}`; - if (downloadBtn) downloadBtn.style.display = 'none'; + if (downloadBtn) { + downloadBtn.classList.remove('show', 'animate-in'); + downloadBtn.style.display = 'none'; + } } else if (transfer.status === 'completed') { - if (progressBar) progressBar.style.width = '100%'; - if (statusText) statusText.textContent = '✓ Completed'; + // 传输完成时的动画序列 + if (progressContainer) { + // 先添加淡出动画类 + progressContainer.classList.add('fade-out'); + // 延迟后完全隐藏 + setTimeout(() => { + progressContainer.style.display = 'none'; + }, 400); + } + if (downloadBtn) { // 只有接收方才显示下载按钮 if (isSender) { + downloadBtn.classList.remove('show', 'animate-in'); downloadBtn.style.display = 'none'; } else { - downloadBtn.style.display = 'inline-block'; - downloadBtn.disabled = false; + // 延迟显示下载按钮,等进度条消失动画完成 + setTimeout(() => { + downloadBtn.style.display = 'flex'; + downloadBtn.classList.add('show'); + downloadBtn.disabled = false; + // 添加进入动画 + setTimeout(() => { + downloadBtn.classList.add('animate-in'); + }, 50); + // 清理动画类 + setTimeout(() => { + downloadBtn.classList.remove('animate-in'); + }, 550); + }, 200); } } }