迁移聊天室Toast通知脚本
This commit is contained in:
@@ -7,6 +7,7 @@ export { bindDailySignInControls } from "./chat-room/daily-sign-in.js";
|
|||||||
export { applyFontSize, bindChatFontSizeControl, CHAT_FONT_SIZE_STORAGE_KEY, restoreChatFontSize } from "./chat-room/font-size.js";
|
export { applyFontSize, bindChatFontSizeControl, CHAT_FONT_SIZE_STORAGE_KEY, restoreChatFontSize } from "./chat-room/font-size.js";
|
||||||
export { bindChatImageUploadControl } from "./chat-room/image-upload.js";
|
export { bindChatImageUploadControl } from "./chat-room/image-upload.js";
|
||||||
export { bindChatComposerControls } from "./chat-room/composer.js";
|
export { bindChatComposerControls } from "./chat-room/composer.js";
|
||||||
|
export { bindChatToast } from "./chat-room/toast.js";
|
||||||
export { bindFriendPanelControls, closeFriendPanel, friendSearch, loadFriends, openFriendPanel, quickFriendAction } from "./chat-room/friend-panel.js";
|
export { bindFriendPanelControls, closeFriendPanel, friendSearch, loadFriends, openFriendPanel, quickFriendAction } from "./chat-room/friend-panel.js";
|
||||||
export { closeChatImageLightbox, initChatImageLightboxEvents, openChatImageLightbox } from "./chat-room/lightbox.js";
|
export { closeChatImageLightbox, initChatImageLightboxEvents, openChatImageLightbox } from "./chat-room/lightbox.js";
|
||||||
export {
|
export {
|
||||||
@@ -82,6 +83,7 @@ import { bindDailySignInControls } from "./chat-room/daily-sign-in.js";
|
|||||||
import { applyFontSize, bindChatFontSizeControl, CHAT_FONT_SIZE_STORAGE_KEY, restoreChatFontSize } from "./chat-room/font-size.js";
|
import { applyFontSize, bindChatFontSizeControl, CHAT_FONT_SIZE_STORAGE_KEY, restoreChatFontSize } from "./chat-room/font-size.js";
|
||||||
import { bindChatImageUploadControl } from "./chat-room/image-upload.js";
|
import { bindChatImageUploadControl } from "./chat-room/image-upload.js";
|
||||||
import { bindChatComposerControls } from "./chat-room/composer.js";
|
import { bindChatComposerControls } from "./chat-room/composer.js";
|
||||||
|
import { bindChatToast } from "./chat-room/toast.js";
|
||||||
import { bindFriendPanelControls, closeFriendPanel, friendSearch, loadFriends, openFriendPanel, quickFriendAction } from "./chat-room/friend-panel.js";
|
import { bindFriendPanelControls, closeFriendPanel, friendSearch, loadFriends, openFriendPanel, quickFriendAction } from "./chat-room/friend-panel.js";
|
||||||
import { closeChatImageLightbox, initChatImageLightboxEvents, openChatImageLightbox } from "./chat-room/lightbox.js";
|
import { closeChatImageLightbox, initChatImageLightboxEvents, openChatImageLightbox } from "./chat-room/lightbox.js";
|
||||||
import {
|
import {
|
||||||
@@ -162,6 +164,7 @@ if (typeof window !== "undefined") {
|
|||||||
bindChatFontSizeControl,
|
bindChatFontSizeControl,
|
||||||
bindChatImageUploadControl,
|
bindChatImageUploadControl,
|
||||||
bindChatComposerControls,
|
bindChatComposerControls,
|
||||||
|
bindChatToast,
|
||||||
bindFriendPanelControls,
|
bindFriendPanelControls,
|
||||||
closeFriendPanel,
|
closeFriendPanel,
|
||||||
friendSearch,
|
friendSearch,
|
||||||
@@ -271,6 +274,7 @@ if (typeof window !== "undefined") {
|
|||||||
bindChatFontSizeControl();
|
bindChatFontSizeControl();
|
||||||
bindChatImageUploadControl();
|
bindChatImageUploadControl();
|
||||||
bindChatComposerControls();
|
bindChatComposerControls();
|
||||||
|
bindChatToast();
|
||||||
bindFriendPanelControls();
|
bindFriendPanelControls();
|
||||||
bindToolbarControls();
|
bindToolbarControls();
|
||||||
bindAdminMenuControls();
|
bindAdminMenuControls();
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
// 聊天室右下角 Toast 通知组件,提供 window.chatToast.show 兼容入口。
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 淡出并移除 Toast 卡片。
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} card
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function dismissToast(card) {
|
||||||
|
card.style.opacity = "0";
|
||||||
|
window.setTimeout(() => card.remove(), 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建右下角 Toast 通知 API。
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} container
|
||||||
|
* @returns {{show: Function}}
|
||||||
|
*/
|
||||||
|
function createChatToast(container) {
|
||||||
|
return {
|
||||||
|
/**
|
||||||
|
* 显示一条 Toast 通知卡片。
|
||||||
|
*
|
||||||
|
* @param {object} options
|
||||||
|
* @param {string} options.title 标题文字
|
||||||
|
* @param {string} options.message 内容 HTML
|
||||||
|
* @param {string} [options.icon] 左侧 Emoji
|
||||||
|
* @param {string} [options.color] 强调色
|
||||||
|
* @param {number} [options.duration] 自动消失毫秒,0 表示不自动消失
|
||||||
|
* @param {object|null} [options.action] 操作按钮 { label, onClick }
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
show({
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
icon = "💬",
|
||||||
|
color = "#336699",
|
||||||
|
duration = 6000,
|
||||||
|
action = null,
|
||||||
|
}) {
|
||||||
|
const card = document.createElement("div");
|
||||||
|
card.style.cssText = `
|
||||||
|
background:#fff; border-radius:10px; overflow:hidden;
|
||||||
|
box-shadow:0 8px 32px rgba(0,0,0,.18);
|
||||||
|
min-width:260px; max-width:320px;
|
||||||
|
font-size:13px; color:#374151; line-height:1.6;
|
||||||
|
pointer-events:all;
|
||||||
|
animation:toastSlideIn .3s ease;
|
||||||
|
opacity:1; transition:opacity .4s;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const actionHtml = action ? `
|
||||||
|
<div style="margin-top:8px;">
|
||||||
|
<button class="chat-toast-action-btn"
|
||||||
|
style="background:${color}; color:#fff; border:none; border-radius:6px;
|
||||||
|
padding:5px 14px; font-size:12px; font-weight:bold; cursor:pointer;">
|
||||||
|
${action.label}
|
||||||
|
</button>
|
||||||
|
</div>` : "";
|
||||||
|
|
||||||
|
card.innerHTML = `
|
||||||
|
<div style="background:${color}; padding:8px 14px;
|
||||||
|
display:flex; align-items:center; justify-content:space-between;">
|
||||||
|
<span style="color:#fff; font-weight:bold; font-size:13px;">
|
||||||
|
${icon} ${title}
|
||||||
|
</span>
|
||||||
|
<button class="chat-toast-close"
|
||||||
|
style="background:rgba(255,255,255,.25); border:none; color:#fff;
|
||||||
|
width:22px; height:22px; border-radius:50%; cursor:pointer;
|
||||||
|
font-size:14px; line-height:22px; text-align:center; padding:0;">×</button>
|
||||||
|
</div>
|
||||||
|
<div style="padding:12px 14px 10px;">
|
||||||
|
<div>${message}</div>
|
||||||
|
${actionHtml}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
card.querySelector(".chat-toast-close")?.addEventListener("click", () => dismissToast(card));
|
||||||
|
|
||||||
|
if (action) {
|
||||||
|
card.querySelector(".chat-toast-action-btn")?.addEventListener("click", () => {
|
||||||
|
action.onClick?.();
|
||||||
|
dismissToast(card);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
container.appendChild(card);
|
||||||
|
|
||||||
|
// Toast 出现时沿用旧体验播放提示音。
|
||||||
|
window.chatSound?.ding?.();
|
||||||
|
|
||||||
|
if (duration > 0) {
|
||||||
|
window.setTimeout(() => dismissToast(card), duration);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定全局 Toast API。
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
export function bindChatToast() {
|
||||||
|
if (typeof document === "undefined" || window.chatToast) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const container = document.getElementById("chat-toast-container");
|
||||||
|
if (!container) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.chatToast = createChatToast(container);
|
||||||
|
}
|
||||||
@@ -25,107 +25,6 @@
|
|||||||
display:flex; flex-direction:column-reverse; gap:10px; pointer-events:none;">
|
display:flex; flex-direction:column-reverse; gap:10px; pointer-events:none;">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
|
||||||
/**
|
|
||||||
* 全局右下角 Toast 小卡片通知系统。
|
|
||||||
*
|
|
||||||
* 可在聊天室任何 JS 代码中调用:
|
|
||||||
* window.chatToast.show({ title, message, icon, color, duration, action });
|
|
||||||
*/
|
|
||||||
window.chatToast = (function() {
|
|
||||||
const container = document.getElementById('chat-toast-container');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示一条 Toast 通知卡片。
|
|
||||||
*
|
|
||||||
* @param {object} opts
|
|
||||||
* @param {string} opts.title 标题文字
|
|
||||||
* @param {string} opts.message 内容(支持 HTML)
|
|
||||||
* @param {string} [opts.icon] 左侧 Emoji(默认 💬)
|
|
||||||
* @param {string} [opts.color] 强调色(默认 #336699)
|
|
||||||
* @param {number} [opts.duration] 自动消失毫秒,0 表示不自动消失(默认 6000)
|
|
||||||
* @param {object} [opts.action] 操作按钮 { label: string, onClick: function }
|
|
||||||
*/
|
|
||||||
function show({
|
|
||||||
title,
|
|
||||||
message,
|
|
||||||
icon = '💬',
|
|
||||||
color = '#336699',
|
|
||||||
duration = 6000,
|
|
||||||
action = null
|
|
||||||
}) {
|
|
||||||
const card = document.createElement('div');
|
|
||||||
card.style.cssText = `
|
|
||||||
background:#fff; border-radius:10px; overflow:hidden;
|
|
||||||
box-shadow:0 8px 32px rgba(0,0,0,.18);
|
|
||||||
min-width:260px; max-width:320px;
|
|
||||||
font-size:13px; color:#374151; line-height:1.6;
|
|
||||||
pointer-events:all;
|
|
||||||
animation:toastSlideIn .3s ease;
|
|
||||||
opacity:1; transition:opacity .4s;
|
|
||||||
`;
|
|
||||||
|
|
||||||
// 操作按钮 HTML
|
|
||||||
const actionHtml = action ? `
|
|
||||||
<div style="margin-top:8px;">
|
|
||||||
<button class="chat-toast-action-btn"
|
|
||||||
style="background:${color}; color:#fff; border:none; border-radius:6px;
|
|
||||||
padding:5px 14px; font-size:12px; font-weight:bold; cursor:pointer;">
|
|
||||||
${action.label}
|
|
||||||
</button>
|
|
||||||
</div>` : '';
|
|
||||||
|
|
||||||
card.innerHTML = `
|
|
||||||
<div style="background:${color}; padding:8px 14px;
|
|
||||||
display:flex; align-items:center; justify-content:space-between;">
|
|
||||||
<span style="color:#fff; font-weight:bold; font-size:13px;">
|
|
||||||
${icon} ${title}
|
|
||||||
</span>
|
|
||||||
<button class="chat-toast-close"
|
|
||||||
style="background:rgba(255,255,255,.25); border:none; color:#fff;
|
|
||||||
width:22px; height:22px; border-radius:50%; cursor:pointer;
|
|
||||||
font-size:14px; line-height:22px; text-align:center; padding:0;">×</button>
|
|
||||||
</div>
|
|
||||||
<div style="padding:12px 14px 10px;">
|
|
||||||
<div>${message}</div>
|
|
||||||
${actionHtml}
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
// 关闭按钮
|
|
||||||
card.querySelector('.chat-toast-close').addEventListener('click', () => dismiss(card));
|
|
||||||
|
|
||||||
// 操作按钮
|
|
||||||
if (action) {
|
|
||||||
card.querySelector('.chat-toast-action-btn').addEventListener('click', () => {
|
|
||||||
action.onClick?.();
|
|
||||||
dismiss(card);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
container.appendChild(card);
|
|
||||||
|
|
||||||
// 弹出时播放叮咚通知音
|
|
||||||
if (window.chatSound) window.chatSound.ding();
|
|
||||||
|
|
||||||
// 自动消失
|
|
||||||
if (duration > 0) {
|
|
||||||
setTimeout(() => dismiss(card), duration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 淡出并移除 Toast 卡片 */
|
|
||||||
function dismiss(card) {
|
|
||||||
card.style.opacity = '0';
|
|
||||||
setTimeout(() => card.remove(), 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
show
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@keyframes toastSlideIn {
|
@keyframes toastSlideIn {
|
||||||
from {
|
from {
|
||||||
|
|||||||
Reference in New Issue
Block a user