diff --git a/resources/views/chat/partials/scripts.blade.php b/resources/views/chat/partials/scripts.blade.php index 2f2472c..dd41d19 100644 --- a/resources/views/chat/partials/scripts.blade.php +++ b/resources/views/chat/partials/scripts.blade.php @@ -653,7 +653,9 @@ // ── 好友系统私有频道监听(仅本人可见) ──────────────── /** * 监听当前用户的私有频道 `user.{username}`, - * 收到 FriendAdded / FriendRemoved 事件时用任务弹窗通知。 + * 收到 FriendAdded / FriendRemoved 事件时用弹窗通知。 + * FriendAdded → 居中大卡弹窗(同任命公告风格) + * FriendRemoved → 右下角 Toast 通知 */ function setupFriendNotification() { if (!window.Echo || !window.chatContext) { @@ -663,30 +665,14 @@ const myName = window.chatContext.username; window.Echo.private(`user.${myName}`) .listen('.FriendAdded', (e) => { - if (e.has_added_back) { - // 我已经把对方加了,现在对方也加了我 → 双向好友 - showFriendToast( - `💚 ${e.from_username} 将你加为好友了!
你们现在互为好友 🎉`, - '#16a34a' - ); - } else { - // 对方加了我,但我还没加对方 → 提示可以回加 - showFriendToast( - `💚 ${e.from_username} 将你加为好友了!
- 但你还没有添加对方为好友。`, - '#16a34a', { - label: `➕ 回加 ${e.from_username}`, - username: e.from_username, - action: 'add' - } - ); - } + // 用居中大卡弹窗通知(有无互相好友显示不同文案和按钮) + showFriendBanner(e.from_username, e.has_added_back); }) .listen('.FriendRemoved', (e) => { if (e.had_added_back) { // 之前是互相好友,现在对方删除了我 → 提示可以同步删除 showFriendToast( - `💔 ${e.from_username} 已将你从好友列表移除。
+ `� ${e.from_username} 已将你从好友列表移除。
你的好友列表中仍保留对方,可点击同步移除。`, '#6b7280', { label: `🗑️ 同步移除 ${e.from_username}`, @@ -695,9 +681,8 @@ } ); } else { - // 对方删我,但原来就是单向的 showFriendToast( - `💔 ${e.from_username} 已将你从他的好友列表移除。`, + `� ${e.from_username} 已将你从他的好友列表移除。`, '#9ca3af' ); } @@ -705,6 +690,126 @@ } document.addEventListener('DOMContentLoaded', setupFriendNotification); + /** + * 显示好友添加居中大卡弹窗(同任命公告风格)。 + * 互相好友 → 绿色渐变 + 互为好友文案 + * 单向添加 → 蓝绿渐变 + 提示回加 + [➕ 回加好友] 按钮 + * + * @param {string} fromUsername 添加者用户名 + * @param {boolean} hasAddedBack 接收方是否已将添加者加为好友 + */ + function showFriendBanner(fromUsername, hasAddedBack) { + // 移除已有的好友弹窗(防止重叠) + const old = document.getElementById('friend-banner'); + if (old) old.remove(); + + const banner = document.createElement('div'); + banner.id = 'friend-banner'; + banner.style.cssText = ` + position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); + z-index: 99999; text-align: center; + animation: appoint-pop 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); + `; + + if (hasAddedBack) { + // 已互相好友 → 绿色渐变卡片 + banner.innerHTML = ` +
+
🎉💚🎉
+
+ ══ 好友通知 ══ +
+
+ ${escapeHtml(fromUsername)} +
+
+ 将你加为好友!你们现在互为好友 🎊 +
+
+ ${new Date().toLocaleTimeString('zh-CN')} +
+
+ `; + } else { + // 单向添加 → 蓝绿渐变 + 回加按钮(可点击) + const btnId = 'friend-banner-btn-' + Date.now(); + banner.style.pointerEvents = 'auto'; // 允许点击按钮 + banner.innerHTML = ` +
+
💚📩
+
+ ══ 好友申请 ══ +
+
+ ${escapeHtml(fromUsername)} +
+
+ 将你加为好友! +
+
+ 但你还没有回加对方为好友 +
+
+ + +
+
+ ${new Date().toLocaleTimeString('zh-CN')} +
+
+ `; + + // 等 DOM 插入后再绑定按钮事件 + setTimeout(() => { + const btn = document.getElementById(btnId); + if (btn) { + btn.addEventListener('click', () => quickFriendAction('add', fromUsername, btn)); + } + }, 50); + } + + document.body.appendChild(banner); + + // 确保动画关键帧已注入 + if (!document.getElementById('appoint-keyframes')) { + const style = document.createElement('style'); + style.id = 'appoint-keyframes'; + style.textContent = ` + @keyframes appoint-pop { + 0% { opacity: 0; transform: translate(-50%,-50%) scale(0.5); } + 70% { transform: translate(-50%,-50%) scale(1.05); } + 100% { opacity: 1; transform: translate(-50%,-50%) scale(1); } + } + @keyframes appoint-fade-out { + from { opacity: 1; } + to { opacity: 0; transform: translate(-50%,-50%) scale(0.9); } + } + `; + document.head.appendChild(style); + } + + // 非单向(互相好友):5 秒后自动淡出;单向:需手动关闭(有按钮) + if (hasAddedBack) { + setTimeout(() => { + banner.style.animation = 'appoint-fade-out 0.5s ease forwards'; + setTimeout(() => banner.remove(), 500); + }, 5000); + } + } + /** * 显示好友事件通知浮窗(右下角淡入淡出)。 *