mumu小手机
Last updated
Last updated
<Phone>
<UserInput>汇总用户在本次对话中发送的所有消息,使用|||分隔每条独立消息</UserInput>
<AiInput>汇总角色在本次对话中回复的所有消息,使用|||分隔每条独立回复</AiInput>
</Phone>```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>暗色金属质感手机界面</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
/* 自定义滚动条隐藏 */
.no-scrollbar::-webkit-scrollbar { display: none; }
.no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
/* 金属拉丝渐变 */
.metal-finish {
background: linear-gradient(180deg, #334155 0%, #1e293b 40%, #020617 100%);
}
/* 气泡动画 */
@keyframes popIn {
from { opacity: 0; transform: scale(0.95) translateY(10px); }
to { opacity: 1; transform: scale(1) translateY(0); }
}
.message-anim { animation: popIn 0.3s ease-out forwards; }
/* 规则面板动画 */
.rules-anim {
transform-origin: top right;
animation: growIn 0.2s ease-out forwards;
}
@keyframes growIn {
from { opacity: 0; transform: scale(0.9) translateY(-10px); }
to { opacity: 1; transform: scale(1) translateY(0); }
}
/* 禁用状态按钮样式 */
#submit-btn:disabled {
background-color: #1e293b;
border-color: #334155;
color: #64748b;
cursor: not-allowed;
opacity: 0.6;
box-shadow: none;
transform: none;
}
</style>
</head>
<body class="min-h-screen flex items-center justify-center p-4 font-sans antialiased text-slate-300">
<div class="relative w-[320px] h-[650px] metal-finish rounded-[44px] shadow-[0_50px_100px_-20px_rgba(0,0,0,1)] p-[8px] flex flex-col border border-white/10">
<div class="absolute inset-0 rounded-[44px] border-[0.5px] border-white/20 pointer-events-none"></div>
<div class="flex-1 bg-[#0a0a0b] rounded-[36px] overflow-hidden flex flex-col relative border border-black shadow-[inset_0_0_10px_rgba(0,0,0,0.8)]">
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-24 h-6 bg-black rounded-b-2xl z-20"></div>
<div class="h-10 px-6 pt-1 flex justify-between items-center text-[11px] font-bold text-zinc-400 z-10">
<span>14:25</span>
<div class="flex gap-1.5 items-center">
<i class="fas fa-signal"></i><i class="fas fa-wifi"></i>
<div class="w-5 h-2.5 border border-zinc-700 rounded-[2px] relative flex items-center px-[1px]">
<div class="h-[80%] bg-zinc-300 w-[60%] rounded-[1px]"></div>
</div>
</div>
</div>
<div class="h-12 bg-[#0a0a0b]/80 backdrop-blur-md border-b border-white/5 flex items-center justify-between px-4 mt-1 shrink-0 relative">
<div class="w-8"></div>
<h1 class="font-semibold text-[14px] text-zinc-100">MUMU🐱</h1>
<button onclick="toggleRules()" class="w-8 h-8 flex items-center justify-center text-zinc-400 hover:text-white transition-colors">
<i class="fas fa-ellipsis-h text-sm"></i>
</button>
<div id="rules-panel" class="absolute top-11 right-4 w-48 bg-zinc-900/95 backdrop-blur-xl border border-white/10 rounded-xl shadow-2xl p-4 z-50 hidden rules-anim">
<h4 class="text-[11px] font-bold text-emerald-500 uppercase tracking-wider mb-2">使用规则</h4>
<ul class="text-[10px] text-zinc-400 space-y-2 leading-tight">
<li class="flex gap-1.5"><span class="text-emerald-500">•</span><span>输入内容按回车预览</span></li>
<li class="flex gap-1.5"><span class="text-emerald-500">•</span><span><strong>清空输入框</strong>后方可结束发送</span></li>
</ul>
</div>
</div>
<div id="chat-container" onclick="closeRules()" class="flex-1 overflow-y-auto px-4 py-4 space-y-5 no-scrollbar bg-gradient-to-b from-[#0a0a0b] to-[#111113]"></div>
<div class="px-3 pt-2 pb-8 bg-[#0a0a0b] border-t border-white/5 flex items-center gap-3 shrink-0">
<div class="flex-1 relative">
<input
id="chat-input"
type="text"
placeholder="输入内容并回车..."
class="w-full h-10 bg-zinc-900/50 text-zinc-200 rounded-xl px-4 text-sm border border-zinc-800/50 outline-none focus:border-emerald-600/50 transition-all placeholder:text-zinc-500"
>
</div>
<button id="submit-btn" onclick="submitToParent()" class="whitespace-nowrap h-10 bg-emerald-600 hover:bg-emerald-500 text-white px-4 rounded-xl shadow-lg transition-all active:scale-95 text-[12px] font-bold border border-emerald-400/20">
结束发送
</button>
</div>
<div class="absolute bottom-1.5 left-1/2 -translate-x-1/2 w-28 h-[4px] bg-zinc-800 rounded-full"></div>
</div>
</div>
<script>
const chatContainer = document.getElementById('chat-container');
const chatInput = document.getElementById('chat-input');
const submitBtn = document.getElementById('submit-btn');
const rulesPanel = document.getElementById('rules-panel');
const FRIEND_AVATAR = "https://cdn.mufy.ai/images/9b350667-10e5-43ea-efd8-aac249556d00/public";
const MY_AVATAR = "https://cdn.mufy.ai/images/b41c873a-449d-4539-56ee-15abbd5bc700/public";
const userInput = `$1`;
const aiInput = `$2`;
let newUserMessages = [];
function scrollToBottom() { chatContainer.scrollTop = chatContainer.scrollHeight; }
function toggleRules() { rulesPanel.classList.toggle('hidden'); }
function closeRules() { rulesPanel.classList.add('hidden'); }
// --- 新增:检查输入框内容以控制按钮状态 ---
function checkInputStatus() {
const hasValue = chatInput.value.trim().length > 0;
submitBtn.disabled = hasValue;
// 改变按钮视觉反馈(如果是禁用状态,Tailwind 的 hover 会由于 disabled 属性失效)
if (hasValue) {
submitBtn.classList.add('opacity-50');
submitBtn.title = "请先按回车确认当前输入的内容";
} else {
submitBtn.classList.remove('opacity-50');
submitBtn.title = "";
}
}
function createMessageElement(text, isMe, isAnim = true) {
const wrapper = document.createElement('div');
wrapper.className = `flex ${isMe ? 'flex-row-reverse' : 'flex-row'} items-start gap-2.5 ${isAnim ? 'message-anim' : ''}`;
wrapper.innerHTML = `
<div class="w-9 h-9 rounded-[10px] bg-zinc-800 border border-white/10 shadow-md overflow-hidden shrink-0">
<img src="${isMe ? MY_AVATAR : FRIEND_AVATAR}" class="w-full h-full object-cover">
</div>
<div class="flex flex-col space-y-1 max-w-[75%]">
<div class="relative px-3.5 py-2.5 rounded-2xl text-[13px] leading-[1.4] tracking-wide
${isMe ? 'bg-[#07c160] text-white rounded-tr-[4px]' : 'bg-zinc-800/80 text-zinc-100 rounded-tl-[4px] border border-white/5'}">
${text}
</div>
</div>
`;
return wrapper;
}
function initChat() {
if (userInput && typeof userInput === 'string') {
userInput.split('|||').forEach(text => {
if (text.trim()) chatContainer.appendChild(createMessageElement(text.trim(), true, false));
});
}
if (aiInput && typeof aiInput === 'string') {
aiInput.split('|||').forEach(text => {
if (text.trim()) chatContainer.appendChild(createMessageElement(text.trim(), false, false));
});
}
scrollToBottom();
checkInputStatus(); // 初始化按钮状态
}
function smartFill(text, autoSend) {
const parentDoc = window.parent.document;
const textarea = parentDoc.querySelector('textarea.text-blackAlpha-700') ||
parentDoc.querySelector('textarea[placeholder*="Enter"]');
if (!textarea) {
console.error("未找到输入框");
return;
}
const nativeValueSetter = Object.getOwnPropertyDescriptor(
window.parent.HTMLTextAreaElement.prototype,
"value"
).set;
nativeValueSetter.call(textarea, text);
const inputEvent = new Event('input', { bubbles: true });
textarea.dispatchEvent(inputEvent);
const changeEvent = new Event('change', { bubbles: true });
textarea.dispatchEvent(changeEvent);
if (autoSend) {
setTimeout(() => {
textarea.focus();
const sendBtn = textarea.closest('.relative')?.querySelector('button:not([disabled])');
if (sendBtn && !sendBtn.disabled) {
sendBtn.click();
} else {
const enterEvent = new KeyboardEvent('keydown', {
key: 'Enter',
code: 'Enter',
keyCode: 13,
which: 13,
bubbles: true,
cancelable: true
});
textarea.dispatchEvent(enterEvent);
}
}, 100);
}
}
function addLocalMessage() {
const text = chatInput.value.trim();
if (!text) return;
chatContainer.appendChild(createMessageElement(text, true));
newUserMessages.push(text);
chatInput.value = '';
checkInputStatus(); // 清空后恢复按钮
scrollToBottom();
}
function submitToParent() {
if (newUserMessages.length === 0) return;
const finalPayload = newUserMessages.join('|||');
// 此处调用您的智能填充逻辑...
console.log("发送到父组件:", finalPayload);
smartFill(finalPayload, true);
}
// 监听输入事件
chatInput.addEventListener('input', checkInputStatus);
chatInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
addLocalMessage();
e.preventDefault();
}
});
window.onload = initChat;
</script>
</body>
</html>
```严格按照以下XML结构输出手机聊天组件,不要输出任何其他内容:
<Phone>
<UserInput>汇总用户在本次对话中发送的所有消息,使用|||分隔每条独立消息</UserInput>
<AiInput>汇总角色在本次对话中回复的所有消息,使用|||分隔每条独立回复</AiInput>
</Phone>
【字段说明】
- <UserInput>:完整记录上一条用户发送的全部对话内容,每条消息末尾添加|||符号,最后一条消息无需添加
- <AiInput>:完整记录角色回复的全部对话内容,每条回复末尾添加|||符号,最后一条回复无需添加
【重要约束】
- 仅输出XML结构,禁止添加开场白、解释性文字或多余内容
- 严格保留标签名称<Phone><UserInput><AiInput>,不得修改
- 确保消息内容准确还原对话原文,不进行删减或润色