/**
* 礼物功能模块
* 支持发送普通礼物和情趣玩具
* 情趣玩具支持配送流程和控制界面
*/
import { getSettings } from './config.js';
import { requestSave } from './save-manager.js';
import { showToast, showNotificationBanner } from './toast.js';
import { escapeHtml } from './utils.js';
import { refreshChatList } from './ui.js';
import { currentChatIndex, appendMessage, showTypingIndicator, hideTypingIndicator } from './chat.js';
import { callAI } from './ai.js';
import { splitAIMessages } from './config.js';
// SVG图标定义
const ICON_GIFT_CHARACTER = ``;
const ICON_GIFT_USER = ``;
const ICON_GIFT_BOTH = ``;
// 礼物分类数据
const GIFT_CATEGORIES = {
normal: {
name: '普通礼物',
icon: ``,
items: [
{ id: 'flower', name: '鲜花', emoji: '💐', desc: '一束美丽的鲜花', hasControl: false },
{ id: 'chocolate', name: '巧克力', emoji: '🍫', desc: '精美的巧克力礼盒', hasControl: false },
{ id: 'ring', name: '戒指', emoji: '💍', desc: '闪耀的戒指', hasControl: false },
{ id: 'necklace', name: '项链', emoji: '📿', desc: '精致的项链', hasControl: false },
{ id: 'perfume', name: '香水', emoji: '🧴', desc: '迷人的香水', hasControl: false },
{ id: 'teddy', name: '玩偶', emoji: '🧸', desc: '可爱的毛绒玩偶', hasControl: false },
{ id: 'cake', name: '蛋糕', emoji: '🎂', desc: '美味的蛋糕', hasControl: false },
{ id: 'wine', name: '红酒', emoji: '🍷', desc: '醇香的红酒', hasControl: false }
]
},
toy: {
name: '情趣玩具',
icon: ``,
items: [
{ id: 'vibrator', name: '跳蛋', emoji: '🥚', desc: '遥控跳蛋', hasControl: true, hasShock: false },
{ id: 'massager', name: '按摩棒', emoji: '🌡️', desc: '震动按摩棒', hasControl: true, hasShock: false },
{ id: 'breastChain', name: '微电流乳链', emoji: '⚡', desc: '微电流乳链', hasControl: true, hasShock: true },
{ id: 'analPlug', name: '肛塞', emoji: '🔌', desc: '震动肛塞', hasControl: true, hasShock: false },
{ id: 'cockRing', name: '锁精环', emoji: '💍', desc: '震动锁精环', hasControl: true, hasShock: false },
{ id: 'breastPump', name: '吸奶器', emoji: '🍼', desc: '电动吸奶器', hasControl: true, hasShock: false },
{ id: 'clitSucker', name: '阴蒂吮吸器', emoji: '💋', desc: '吮吸震动二合一', hasControl: true, hasShock: false },
{ id: 'butterfly', name: '穿戴式小蝴蝶', emoji: '🦋', desc: '隐蔽穿戴震动', hasControl: true, hasShock: false },
{ id: 'collar', name: '项圈', emoji: '⭕', desc: '精致的项圈', hasControl: false },
{ id: 'candle', name: '低温蜡烛', emoji: '🕯️', desc: '安全的低温蜡烛', hasControl: false },
{ id: 'lingerie', name: '情趣内衣', emoji: '👙', desc: '性感的情趣内衣', hasControl: false },
{ id: 'fuckingMachine', name: '炮机', emoji: '🔧', desc: '电动炮机', hasControl: true, hasShock: false },
{ id: 'masturbatorCup', name: '飞机杯', emoji: '🥤', desc: '电动飞机杯', hasControl: true, hasShock: false }
]
}
};
// 当前选中的分类、礼物和目标
let currentCategory = 'normal';
let selectedGift = null;
let selectedTarget = 'character'; // 'character' 送角色 | 'user' 送用户
// 多选模式状态
let multiSelectMode = false;
let selectedGifts = []; // 多选时存储多个礼物
// 显示礼物页面
export function showGiftPage() {
currentCategory = 'normal';
selectedGift = null;
selectedTarget = 'character';
multiSelectMode = false;
selectedGifts = [];
const page = document.getElementById('wechat-gift-page');
if (page) {
page.classList.remove('hidden');
renderGiftContent();
}
}
// 隐藏礼物页面
export function hideGiftPage() {
const page = document.getElementById('wechat-gift-page');
if (page) {
page.classList.add('hidden');
}
}
// 渲染礼物内容
function renderGiftContent() {
const tabsContainer = document.getElementById('wechat-gift-tabs');
const gridContainer = document.getElementById('wechat-gift-grid');
const sendBtn = document.getElementById('wechat-gift-send');
const targetContainer = document.getElementById('wechat-gift-target');
const headerEl = document.querySelector('.wechat-gift-navbar');
if (!tabsContainer || !gridContainer) return;
// 渲染多选按钮(仅情趣玩具分类显示)
let multiSelectBtn = document.getElementById('wechat-gift-multi-select-btn');
if (currentCategory === 'toy') {
if (!multiSelectBtn && headerEl) {
multiSelectBtn = document.createElement('button');
multiSelectBtn.id = 'wechat-gift-multi-select-btn';
multiSelectBtn.className = 'wechat-gift-multi-select-btn';
headerEl.appendChild(multiSelectBtn);
}
if (multiSelectBtn) {
if (multiSelectMode) {
multiSelectBtn.textContent = selectedGifts.length > 0 ? `完成(${selectedGifts.length})` : '取消';
multiSelectBtn.classList.add('active');
} else {
multiSelectBtn.textContent = '多选';
multiSelectBtn.classList.remove('active');
}
multiSelectBtn.onclick = toggleMultiSelectMode;
}
} else {
// 非情趣玩具分类,移除多选按钮并重置状态
if (multiSelectBtn) {
multiSelectBtn.remove();
}
multiSelectMode = false;
selectedGifts = [];
}
// 渲染送礼目标选择(仅情趣玩具显示)
if (targetContainer) {
if (currentCategory === 'toy') {
targetContainer.classList.remove('hidden');
targetContainer.innerHTML = `
送给谁?
`;
// 绑定目标选择事件
targetContainer.querySelectorAll('.wechat-gift-target-btn').forEach(btn => {
btn.addEventListener('click', () => {
selectedTarget = btn.dataset.target;
renderGiftContent();
});
});
} else {
targetContainer.classList.add('hidden');
targetContainer.innerHTML = '';
}
}
// 渲染分类标签
let tabsHtml = '';
for (const [key, category] of Object.entries(GIFT_CATEGORIES)) {
const activeClass = key === currentCategory ? 'active' : '';
tabsHtml += ``;
}
tabsContainer.innerHTML = tabsHtml;
// 绑定标签点击事件
tabsContainer.querySelectorAll('.wechat-gift-tab').forEach(tab => {
tab.addEventListener('click', () => {
currentCategory = tab.dataset.category;
selectedGift = null;
// 切换分类时不重置多选,只在非toy分类时重置
if (tab.dataset.category !== 'toy') {
multiSelectMode = false;
selectedGifts = [];
}
renderGiftContent();
});
});
// 渲染礼物网格
const category = GIFT_CATEGORIES[currentCategory];
let gridHtml = '';
category.items.forEach(item => {
// 多选模式下检查是否在selectedGifts中
const isSelectedInMulti = multiSelectMode && selectedGifts.some(g => g.id === item.id);
// 单选模式下检查是否是selectedGift
const isSelectedSingle = !multiSelectMode && selectedGift?.id === item.id;
const selectedClass = (isSelectedInMulti || isSelectedSingle) ? 'selected' : '';
const controlBadge = item.hasControl ? '可控' : '';
// 多选模式下显示勾选标记
const checkMark = isSelectedInMulti ? '✓' : '';
gridHtml += `
${item.emoji}
${item.name}
${controlBadge}
${checkMark}
`;
});
gridContainer.innerHTML = gridHtml;
// 绑定礼物点击事件
gridContainer.querySelectorAll('.wechat-gift-item').forEach(item => {
item.addEventListener('click', () => {
const giftId = item.dataset.giftId;
const gift = category.items.find(g => g.id === giftId);
if (multiSelectMode && currentCategory === 'toy') {
// 多选模式:只能选择有控制功能的玩具
if (!gift.hasControl) {
showToast('该玩具不支持多选控制');
return;
}
// 切换选中状态
const existingIndex = selectedGifts.findIndex(g => g.id === giftId);
if (existingIndex >= 0) {
selectedGifts.splice(existingIndex, 1);
} else {
if (selectedGifts.length >= 5) {
showToast('最多选择5个玩具');
return;
}
selectedGifts.push(gift);
}
} else {
// 单选模式
selectedGift = gift;
}
renderGiftContent();
});
});
// 更新发送按钮状态
if (sendBtn) {
if (multiSelectMode && selectedGifts.length > 0) {
sendBtn.disabled = false;
sendBtn.textContent = `送出 ${selectedGifts.length} 件玩具`;
} else if (!multiSelectMode && selectedGift) {
sendBtn.disabled = false;
sendBtn.textContent = `送出 ${selectedGift.name}`;
} else {
sendBtn.disabled = true;
sendBtn.textContent = '请选择礼物';
}
}
}
// 切换多选模式
function toggleMultiSelectMode() {
if (multiSelectMode && selectedGifts.length > 0) {
// 如果已有选择,点击"完成"按钮触发发送
sendGift();
} else {
// 切换模式
multiSelectMode = !multiSelectMode;
if (!multiSelectMode) {
selectedGifts = [];
}
selectedGift = null;
renderGiftContent();
}
}
// 发送礼物
export async function sendGift() {
// 检查是否有选择
const isMulti = multiSelectMode && selectedGifts.length > 0;
if (!isMulti && !selectedGift) {
showToast('请选择礼物');
return;
}
if (currentChatIndex < 0) {
showToast('请先打开聊天');
return;
}
const settings = getSettings();
const contact = settings.contacts[currentChatIndex];
if (!contact) return;
const isToy = currentCategory === 'toy';
const target = isToy ? selectedTarget : null;
// 关闭礼物页面
hideGiftPage();
// 获取描述(如果有输入的话)
const descInput = document.getElementById('wechat-gift-desc');
const customDesc = descInput?.value?.trim() || '';
if (descInput) descInput.value = '';
// 保存到聊天历史
const now = new Date();
const timeStr = `${now.getFullYear()}-${(now.getMonth()+1).toString().padStart(2,'0')}-${now.getDate().toString().padStart(2,'0')} ${now.getHours().toString().padStart(2,'0')}:${now.getMinutes().toString().padStart(2,'0')}`;
if (!contact.chatHistory) {
contact.chatHistory = [];
}
// 多选模式处理
if (isMulti) {
const giftsToSend = [...selectedGifts];
const giftNames = giftsToSend.map(g => g.name).join('、');
const giftEmojis = giftsToSend.map(g => g.emoji).join(' ');
const targetText = target === 'character' ? '送TA' : target === 'user' ? '送自己' : '同时送';
const giftMessage = `[情趣礼物套装] ${giftEmojis} ${giftNames}(${targetText})${customDesc ? ` - ${customDesc}` : ''}`;
const giftRecord = {
role: 'user',
content: giftMessage,
time: timeStr,
timestamp: Date.now(),
isGift: true,
isMultiGift: true,
giftInfo: {
gifts: giftsToSend.map(g => ({
id: g.id,
name: g.name,
emoji: g.emoji,
desc: g.desc,
hasControl: g.hasControl,
hasShock: g.hasShock
})),
isToy: true,
target: target,
customDesc: customDesc
}
};
contact.chatHistory.push(giftRecord);
// 显示礼物消息(多选版本)
appendMultiGiftMessage('user', giftsToSend, customDesc, contact, target);
contact.lastMessage = giftMessage;
// 添加到待配送列表(作为一个多玩具组合)
if (!contact.pendingGifts) {
contact.pendingGifts = [];
}
const multiPendingGift = {
isMulti: true,
toys: giftsToSend.map(g => ({
giftId: g.id,
giftName: g.name,
giftEmoji: g.emoji,
giftDesc: g.desc,
hasControl: g.hasControl,
hasShock: g.hasShock || false
})),
target: target,
startMessageCount: contact.chatHistory.length,
deliveredAt: null,
isDelivered: false,
isUsing: false,
timestamp: Date.now()
};
contact.pendingGifts.push(multiPendingGift);
// 显示配送中弹窗
setTimeout(() => {
showNotificationBanner('快递', `您选择的${giftsToSend.length}件商品正在配送中~`, 4000);
}, 500);
// 2秒后弹出加急配送弹窗
setTimeout(() => {
showExpressDeliveryModal(multiPendingGift, contact);
}, 2000);
requestSave();
refreshChatList();
// 显示打字指示器
showTypingIndicator(contact);
// 构建给AI的提示
let targetTextAI;
if (target === 'character') {
targetTextAI = '角色(你)';
} else if (target === 'user') {
targetTextAI = '用户';
} else {
targetTextAI = '你和用户两人同时';
}
const aiPrompt = `[系统提示:用户刚刚购买了一套情趣玩具套装,包括:${giftNames},准备送给${targetTextAI}使用。商品正在配送中,预计很快就会送达。${customDesc ? `用户附言:${customDesc}` : ''}
请根据你的角色性格,对这套即将到来的礼物做出反应:
- 如果是送给你的:可以表现出期待、害羞、紧张、好奇等情绪,可以问用户打算怎么用这些
- 如果是送给用户的:可以表现出好奇、调侃、期待看到用户反应等
- 如果是同时送给两人的:可以表现出兴奋、期待、好奇等,想象两人一起使用的场景
- 根据你的人设和与用户的关系,反应可以是含蓄的、热情的、或者假装矜持的
- 回复不要太短,请展现角色的内心活动和情绪变化
【重要】只能输出纯文字消息,禁止输出任何特殊格式标签]`;
try {
const aiResponse = await callAI(contact, aiPrompt);
hideTypingIndicator();
if (aiResponse) {
const aiMessages = splitAIMessages(aiResponse);
for (const msg of aiMessages) {
let reply = msg.trim();
reply = reply.replace(/<\s*meme\s*>[\s\S]*?<\s*\/\s*meme\s*>/gi, '').trim();
reply = reply.replace(/\[.*?\]/g, '').trim();
reply = reply.replace(/([^)]*)/g, '').trim();
reply = reply.replace(/\([^)]*\)/g, '').trim();
if (reply) {
contact.chatHistory.push({
role: 'assistant',
content: reply,
time: timeStr,
timestamp: Date.now()
});
appendMessage('assistant', reply, contact);
}
}
const lastMsg = aiMessages[aiMessages.length - 1]?.trim()?.replace(/\[.*?\]/g, '').trim();
if (lastMsg) {
contact.lastMessage = lastMsg.length > 20 ? lastMsg.substring(0, 20) + '...' : lastMsg;
}
requestSave();
refreshChatList();
}
} catch (err) {
hideTypingIndicator();
console.error('[可乐] 礼物AI回复失败:', err);
}
// 重置多选状态
multiSelectMode = false;
selectedGifts = [];
return;
}
// 单选模式处理(原有逻辑)
const gift = selectedGift;
// 构建礼物消息
let giftMessage;
if (isToy) {
const targetText = target === 'character' ? '送TA' : target === 'user' ? '送自己' : '同时送';
giftMessage = `[情趣礼物] ${gift.emoji} ${gift.name}(${targetText})${customDesc ? ` - ${customDesc}` : ''}`;
} else {
giftMessage = `[礼物] ${gift.emoji} ${gift.name}${customDesc ? ` - ${customDesc}` : ''}`;
}
const giftRecord = {
role: 'user',
content: giftMessage,
time: timeStr,
timestamp: Date.now(),
isGift: true,
giftInfo: {
id: gift.id,
name: gift.name,
emoji: gift.emoji,
desc: gift.desc,
isToy: isToy,
hasControl: gift.hasControl,
hasShock: gift.hasShock,
target: target,
customDesc: customDesc
}
};
contact.chatHistory.push(giftRecord);
// 显示礼物消息
appendGiftMessage('user', gift, isToy, customDesc, contact, target);
contact.lastMessage = giftMessage;
// 如果是可控制的情趣玩具,添加到待配送列表
if (isToy && gift.hasControl) {
if (!contact.pendingGifts) {
contact.pendingGifts = [];
}
const pendingGift = {
giftId: gift.id,
giftName: gift.name,
giftEmoji: gift.emoji,
giftDesc: gift.desc,
target: target,
hasControl: gift.hasControl,
hasShock: gift.hasShock || false,
startMessageCount: contact.chatHistory.length,
deliveredAt: null,
isDelivered: false,
isUsing: false,
timestamp: Date.now()
};
contact.pendingGifts.push(pendingGift);
// 显示配送中弹窗
setTimeout(() => {
showNotificationBanner('快递', '您选择的商品正在配送中~', 4000);
}, 500);
// 2秒后弹出加急配送弹窗
setTimeout(() => {
showExpressDeliveryModal(pendingGift, contact);
}, 2000);
}
requestSave();
refreshChatList();
// 显示打字指示器
showTypingIndicator(contact);
// 构建给AI的提示
let aiPrompt;
if (isToy && gift.hasControl) {
// 可控制的情趣玩具 - 配送中提示词
let targetText;
if (target === 'character') {
targetText = '你';
} else if (target === 'user') {
targetText = '用户';
} else {
targetText = '你和用户两人同时';
}
aiPrompt = `[系统提示:用户刚刚购买了一个${gift.name}(${gift.desc}),准备送给${targetText}使用。商品正在配送中,预计很快就会送达。${customDesc ? `用户附言:${customDesc}` : ''}
请根据你的角色性格,对这个即将到来的礼物做出反应:
- 如果是送给你的:可以表现出期待、害羞、紧张、好奇等情绪
- 如果是送给用户的:可以表现出好奇、调侃、期待看到用户反应等
- 如果是同时送给两人的:可以表现出兴奋、期待、好奇等,想象两人一起使用的场景
- 根据你的人设和与用户的关系,反应可以是含蓄的、热情的、或者假装矜持的
- 可以询问用户打算怎么用、什么时候用等
- 回复不要太短,请展现角色的内心活动和情绪变化
【重要】只能输出纯文字消息,禁止输出任何特殊格式标签]`;
} else if (isToy) {
// 不可控制的情趣玩具
aiPrompt = `[用户送给你一个情趣礼物:${gift.name}(${gift.desc})${customDesc ? `,附言:${customDesc}` : ''}。请根据你的人设性格对这个礼物做出反应。【重要】只能输出纯文字消息,禁止输出任何特殊格式标签]`;
} else {
// 普通礼物
aiPrompt = `[用户送给你一个礼物:${gift.name}(${gift.desc})${customDesc ? `,附言:${customDesc}` : ''}。请对这个礼物做出自然的反应。【重要】只能输出纯文字消息,禁止输出任何特殊格式标签]`;
}
try {
const aiResponse = await callAI(contact, aiPrompt);
hideTypingIndicator();
if (aiResponse) {
const aiMessages = splitAIMessages(aiResponse);
for (const msg of aiMessages) {
let reply = msg.trim();
// 过滤掉特殊标签
reply = reply.replace(/<\s*meme\s*>[\s\S]*?<\s*\/\s*meme\s*>/gi, '').trim();
reply = reply.replace(/\[.*?\]/g, '').trim();
// 过滤括号动作描写
reply = reply.replace(/([^)]*)/g, '').trim();
reply = reply.replace(/\([^)]*\)/g, '').trim();
if (reply) {
contact.chatHistory.push({
role: 'assistant',
content: reply,
time: timeStr,
timestamp: Date.now()
});
appendMessage('assistant', reply, contact);
}
}
const lastMsg = aiMessages[aiMessages.length - 1]?.trim()?.replace(/\[.*?\]/g, '').trim();
if (lastMsg) {
contact.lastMessage = lastMsg.length > 20 ? lastMsg.substring(0, 20) + '...' : lastMsg;
}
requestSave();
refreshChatList();
}
} catch (err) {
hideTypingIndicator();
console.error('[可乐] 礼物AI回复失败:', err);
}
}
// 检查礼物是否送达(在chat.js的消息发送后调用)
export function checkGiftDelivery(contact) {
if (!contact || !contact.pendingGifts || contact.pendingGifts.length === 0) return;
const currentCount = contact.chatHistory?.length || 0;
for (const gift of contact.pendingGifts) {
// 如果正在使用中或已完成,跳过
if (gift.isUsing || gift.completed) continue;
// 首次送达检测
if (!gift.isDelivered && currentCount >= gift.startMessageCount + 25) {
// 标记送达
gift.isDelivered = true;
gift.deliveredAt = Date.now();
gift.lastAskMessageCount = currentCount; // 记录询问时的消息数
// 显示送达弹窗
showNotificationBanner('快递', '您的商品已送达~', 4000);
// 2秒后弹出询问框
setTimeout(() => {
showGiftArrivalModal(gift, contact);
}, 2000);
requestSave();
break; // 一次只处理一个
}
// 已送达但点了"稍后",每隔25条消息再次询问
if (gift.isDelivered && !gift.isUsing && gift.lastAskMessageCount) {
if (currentCount >= gift.lastAskMessageCount + 25) {
gift.lastAskMessageCount = currentCount; // 更新询问时的消息数
// 显示提醒弹窗
showNotificationBanner('快递', '您的商品还在等待使用~', 3000);
// 2秒后再次询问
setTimeout(() => {
showGiftArrivalModal(gift, contact);
}, 2000);
requestSave();
break; // 一次只处理一个
}
}
}
}
// 显示加急配送弹窗
export function showExpressDeliveryModal(gift, contact) {
const modal = document.getElementById('wechat-express-delivery-modal');
if (!modal) return;
modal.classList.remove('hidden');
const yesBtn = document.getElementById('wechat-express-yes');
const noBtn = document.getElementById('wechat-express-no');
const handleYes = () => {
modal.classList.add('hidden');
yesBtn.removeEventListener('click', handleYes);
noBtn.removeEventListener('click', handleNo);
// 标记为已送达
gift.isDelivered = true;
gift.deliveredAt = Date.now();
requestSave();
// 显示送达通知
showNotificationBanner('快递', '您的商品已送达~', 3000);
// 2秒后弹出"是否开始玩"弹窗
setTimeout(() => {
showGiftArrivalModal(gift, contact);
}, 2000);
};
const handleNo = () => {
modal.classList.add('hidden');
yesBtn.removeEventListener('click', handleYes);
noBtn.removeEventListener('click', handleNo);
// 什么都不做,走原有的25条消息检测逻辑
};
yesBtn.addEventListener('click', handleYes);
noBtn.addEventListener('click', handleNo);
}
// 显示礼物送达询问弹窗
export function showGiftArrivalModal(gift, contact) {
const modal = document.getElementById('wechat-gift-arrival-modal');
const bodyEl = document.getElementById('wechat-gift-arrival-body');
if (!modal || !bodyEl) return;
// 支持多选礼物
if (gift.isMulti) {
const toyNames = gift.toys.map(t => t.giftName).join('、');
bodyEl.innerHTML = `您的 ${toyNames} 已送达,您要现在开始玩吗?`;
} else {
bodyEl.innerHTML = `您的 ${gift.giftName} 已送达,您要现在开始玩吗?`;
}
// 存储当前礼物信息
modal.dataset.giftId = gift.giftId || (gift.isMulti ? 'multi' : '');
modal.dataset.giftTimestamp = gift.timestamp;
modal.classList.remove('hidden');
// 绑定按钮事件
const yesBtn = document.getElementById('wechat-gift-arrival-yes');
const noBtn = document.getElementById('wechat-gift-arrival-no');
const handleYes = async () => {
modal.classList.add('hidden');
yesBtn.removeEventListener('click', handleYes);
noBtn.removeEventListener('click', handleNo);
// 标记礼物为已完成,防止重复触发弹窗
gift.completed = true;
requestSave();
// 打开玩具控制界面
const { showToyControlPage } = await import('./toy-control.js');
showToyControlPage(gift, contact, currentChatIndex);
};
const handleNo = () => {
modal.classList.add('hidden');
yesBtn.removeEventListener('click', handleYes);
noBtn.removeEventListener('click', handleNo);
// 更新消息计数基准,25条后再次询问
const currentCount = contact.chatHistory?.length || 0;
gift.lastAskMessageCount = currentCount;
requestSave();
};
yesBtn.addEventListener('click', handleYes);
noBtn.addEventListener('click', handleNo);
}
// 手动打开已送达礼物的控制界面(从心动瞬间历史记录进入)
export async function openToyControl(gift, contact, contactIndex) {
const { showToyControlPage } = await import('./toy-control.js');
showToyControlPage(gift, contact, contactIndex);
}
// 添加礼物消息到界面
export function appendGiftMessage(role, gift, isToy, customDesc, contact, target = null) {
const messagesContainer = document.getElementById('wechat-chat-messages');
if (!messagesContainer) return;
const messageDiv = document.createElement('div');
messageDiv.className = `wechat-message ${role === 'user' ? 'self' : ''}`;
const firstChar = contact?.name ? contact.name.charAt(0) : '?';
// 获取用户头像
let avatarContent;
if (role === 'user') {
const settings = getSettings();
if (settings.userAvatar) {
avatarContent = `
`;
} else {
avatarContent = '我';
}
} else {
avatarContent = contact?.avatar
? `
`
: firstChar;
}
const giftTypeClass = isToy ? 'wechat-gift-bubble-toy' : '';
let giftTypeLabel = isToy ? '情趣礼物' : '礼物';
if (isToy && target) {
giftTypeLabel = target === 'character' ? '情趣礼物·送TA' : target === 'user' ? '情趣礼物·送自己' : '情趣礼物·同时送';
}
messageDiv.innerHTML = `
${avatarContent}
${gift.emoji}
${escapeHtml(gift.name)}
${customDesc ? `
${escapeHtml(customDesc)}
` : ''}
${giftTypeLabel}
`;
messagesContainer.appendChild(messageDiv);
messagesContainer.scrollTop = messagesContainer.scrollHeight;
}
// 添加多选礼物消息到界面
export function appendMultiGiftMessage(role, gifts, customDesc, contact, target = null) {
const messagesContainer = document.getElementById('wechat-chat-messages');
if (!messagesContainer) return;
const messageDiv = document.createElement('div');
messageDiv.className = `wechat-message ${role === 'user' ? 'self' : ''}`;
const firstChar = contact?.name ? contact.name.charAt(0) : '?';
// 获取用户头像
let avatarContent;
if (role === 'user') {
const settings = getSettings();
if (settings.userAvatar) {
avatarContent = `
`;
} else {
avatarContent = '我';
}
} else {
avatarContent = contact?.avatar
? `
`
: firstChar;
}
const giftTypeLabel = target === 'character' ? '送TA' : target === 'user' ? '送自己' : '同时送';
// 生成每个礼物的标签
const giftTagsHtml = gifts.map(g => `
${g.emoji}
${escapeHtml(g.name)}
`).join('');
messageDiv.innerHTML = `
${avatarContent}
${giftTagsHtml}
${customDesc ? `
${escapeHtml(customDesc)}
` : ''}
`;
messagesContainer.appendChild(messageDiv);
messagesContainer.scrollTop = messagesContainer.scrollHeight;
}
// 获取礼物分类数据(供其他模块使用)
export function getGiftCategories() {
return GIFT_CATEGORIES;
}
// 初始化礼物事件
export function initGiftEvents() {
// 返回按钮
document.getElementById('wechat-gift-back')?.addEventListener('click', hideGiftPage);
// 发送按钮
document.getElementById('wechat-gift-send')?.addEventListener('click', sendGift);
}