本次提交包含多项核心更新: 1. 全量替换项目内所有xianyan.app域名变更为s2ss.com,包含配置文件、路由、隐私政策等 2. 重构图表库从fl_chart迁移至syncfusion_flutter_charts,优化图表渲染效果 3. 新增宽屏分屏布局支持,包含右侧面板注册表与可拖拽分割线 4. 完善触觉反馈服务与认证感知Mixin,修复多处内存泄漏问题 5. 合并勋章墙与金币记录入口至成就中心,简化个人中心导航 6. 新增收藏与时间线数据合并导入功能 7. 修复多处UI样式问题,统一主题颜色使用规范 8. 新增日历同步与跨平台触觉反馈依赖库 9. 修复BotToast初始化流程,避免路由切换时的弹窗崩溃
896 lines
27 KiB
HTML
896 lines
27 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=1440">
|
||
<title>闲言 - 发现页宽屏布局</title>
|
||
<style>
|
||
:root {
|
||
--primary: #007AFF;
|
||
--primary-light: rgba(0,122,255,0.12);
|
||
--secondary: #5856D6;
|
||
--background: #FAFAFA;
|
||
--surface: #FFFFFF;
|
||
--surface-secondary: #F2F2F7;
|
||
--text: #1C1C1E;
|
||
--text-secondary: #8E8E93;
|
||
--text-tertiary: #AEAEB2;
|
||
--separator: rgba(60,60,67,0.12);
|
||
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
|
||
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
|
||
--radius-sm: 4px;
|
||
--radius-md: 8px;
|
||
--radius-lg: 12px;
|
||
--radius-xl: 16px;
|
||
--space-1: 4px;
|
||
--space-2: 8px;
|
||
--space-3: 16px;
|
||
--space-4: 24px;
|
||
--space-5: 32px;
|
||
--font-family: -apple-system, system-ui, 'SF Pro Display', 'Segoe UI', sans-serif;
|
||
--nav-width: 72px;
|
||
--glass-bg: rgba(255,255,255,0.72);
|
||
--glass-border: rgba(255,255,255,0.36);
|
||
--glass-blur: 20px;
|
||
--card-bg: rgba(255,255,255,0.8);
|
||
--red: #FF3B30;
|
||
--orange: #FF9500;
|
||
--green: #34C759;
|
||
--teal: #5AC8FA;
|
||
--bubble-self: #007AFF;
|
||
--bubble-other: #E9E9EB;
|
||
}
|
||
|
||
[data-theme="dark"] {
|
||
--background: #1A1A2E;
|
||
--surface: #16213E;
|
||
--surface-secondary: #0F3460;
|
||
--text: #F5F5F7;
|
||
--text-secondary: #98989D;
|
||
--text-tertiary: #636366;
|
||
--separator: rgba(84,84,88,0.65);
|
||
--glass-bg: rgba(30,30,50,0.72);
|
||
--glass-border: rgba(60,60,80,0.36);
|
||
--card-bg: rgba(30,30,50,0.8);
|
||
--bubble-other: #2C2C3E;
|
||
}
|
||
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
|
||
body {
|
||
font-family: var(--font-family);
|
||
background: var(--background);
|
||
color: var(--text);
|
||
height: 100vh;
|
||
overflow: hidden;
|
||
transition: background 0.3s, color 0.3s;
|
||
}
|
||
|
||
.app-shell {
|
||
display: flex;
|
||
height: 100vh;
|
||
width: 100%;
|
||
}
|
||
|
||
.nav-sidebar {
|
||
width: var(--nav-width);
|
||
min-width: var(--nav-width);
|
||
background: var(--glass-bg);
|
||
backdrop-filter: blur(var(--glass-blur));
|
||
-webkit-backdrop-filter: blur(var(--glass-blur));
|
||
border-right: 1px solid var(--separator);
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: var(--space-4) 0;
|
||
gap: var(--space-2);
|
||
z-index: 10;
|
||
}
|
||
|
||
.nav-logo {
|
||
width: 40px;
|
||
height: 40px;
|
||
border-radius: var(--radius-lg);
|
||
background: linear-gradient(135deg, var(--primary), var(--secondary));
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 20px;
|
||
color: #fff;
|
||
margin-bottom: var(--space-4);
|
||
box-shadow: var(--shadow-md);
|
||
}
|
||
|
||
.nav-item {
|
||
width: 48px;
|
||
height: 48px;
|
||
border-radius: var(--radius-lg);
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
cursor: pointer;
|
||
transition: all 0.2s ease;
|
||
font-size: 10px;
|
||
color: var(--text-secondary);
|
||
gap: 2px;
|
||
text-decoration: none;
|
||
position: relative;
|
||
}
|
||
.nav-item .nav-icon { font-size: 22px; line-height: 1; }
|
||
.nav-item .nav-label { font-size: 9px; font-weight: 500; }
|
||
.nav-item:hover { background: var(--primary-light); color: var(--primary); }
|
||
.nav-item.active { background: var(--primary-light); color: var(--primary); }
|
||
.nav-item.active::before {
|
||
content: '';
|
||
position: absolute;
|
||
left: -12px;
|
||
width: 3px;
|
||
height: 20px;
|
||
background: var(--primary);
|
||
border-radius: 0 2px 2px 0;
|
||
}
|
||
|
||
.nav-spacer { flex: 1; }
|
||
|
||
.nav-theme-btn {
|
||
width: 40px;
|
||
height: 40px;
|
||
border-radius: 50%;
|
||
border: none;
|
||
background: var(--surface-secondary);
|
||
color: var(--text);
|
||
font-size: 18px;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: all 0.2s;
|
||
}
|
||
.nav-theme-btn:hover { background: var(--primary-light); }
|
||
|
||
.content-area {
|
||
flex: 1;
|
||
display: flex;
|
||
overflow: hidden;
|
||
position: relative;
|
||
}
|
||
|
||
.master-panel {
|
||
width: 40%;
|
||
min-width: 320px;
|
||
max-width: 600px;
|
||
background: var(--background);
|
||
border-right: 1px solid var(--separator);
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: hidden;
|
||
transition: width 0.3s ease;
|
||
}
|
||
|
||
.master-header {
|
||
padding: var(--space-3) var(--space-4);
|
||
background: var(--glass-bg);
|
||
backdrop-filter: blur(var(--glass-blur));
|
||
-webkit-backdrop-filter: blur(var(--glass-blur));
|
||
border-bottom: 1px solid var(--separator);
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 5;
|
||
}
|
||
|
||
.master-title {
|
||
font-size: 28px;
|
||
font-weight: 700;
|
||
letter-spacing: -0.5px;
|
||
}
|
||
|
||
.master-subtitle {
|
||
font-size: 13px;
|
||
color: var(--text-secondary);
|
||
margin-top: var(--space-1);
|
||
}
|
||
|
||
.master-search {
|
||
margin-top: var(--space-3);
|
||
display: flex;
|
||
gap: var(--space-2);
|
||
}
|
||
|
||
.search-input {
|
||
flex: 1;
|
||
height: 36px;
|
||
border-radius: var(--radius-lg);
|
||
border: 1px solid var(--separator);
|
||
background: var(--surface-secondary);
|
||
color: var(--text);
|
||
padding: 0 var(--space-3);
|
||
font-size: 14px;
|
||
font-family: var(--font-family);
|
||
outline: none;
|
||
transition: border-color 0.2s;
|
||
}
|
||
.search-input:focus { border-color: var(--primary); }
|
||
.search-input::placeholder { color: var(--text-tertiary); }
|
||
|
||
.flow-list {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
padding: var(--space-2) var(--space-3);
|
||
}
|
||
|
||
.flow-card {
|
||
background: var(--card-bg);
|
||
backdrop-filter: blur(10px);
|
||
border-radius: var(--radius-xl);
|
||
padding: var(--space-3) var(--space-4);
|
||
margin-bottom: var(--space-2);
|
||
cursor: pointer;
|
||
transition: all 0.2s ease;
|
||
border: 1px solid var(--separator);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-3);
|
||
}
|
||
.flow-card:hover {
|
||
transform: translateY(-1px);
|
||
box-shadow: var(--shadow-md);
|
||
}
|
||
.flow-card.selected {
|
||
border-color: var(--primary);
|
||
background: var(--primary-light);
|
||
}
|
||
|
||
.flow-avatar {
|
||
width: 44px;
|
||
height: 44px;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 22px;
|
||
flex-shrink: 0;
|
||
color: #fff;
|
||
}
|
||
|
||
.flow-info { flex: 1; min-width: 0; }
|
||
.flow-name {
|
||
font-size: 15px;
|
||
font-weight: 600;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
.flow-preview {
|
||
font-size: 13px;
|
||
color: var(--text-secondary);
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
margin-top: 2px;
|
||
}
|
||
.flow-meta {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-end;
|
||
gap: var(--space-1);
|
||
flex-shrink: 0;
|
||
}
|
||
.flow-time { font-size: 11px; color: var(--text-tertiary); }
|
||
.flow-badge {
|
||
width: 20px;
|
||
height: 20px;
|
||
border-radius: 50%;
|
||
background: var(--primary);
|
||
color: #fff;
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.divider-handle {
|
||
width: 6px;
|
||
cursor: col-resize;
|
||
background: var(--separator);
|
||
position: relative;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: background 0.2s;
|
||
flex-shrink: 0;
|
||
}
|
||
.divider-handle:hover { background: var(--primary); }
|
||
.divider-handle::after {
|
||
content: '···';
|
||
color: var(--text-tertiary);
|
||
font-size: 10px;
|
||
writing-mode: vertical-lr;
|
||
letter-spacing: 2px;
|
||
}
|
||
|
||
.detail-panel {
|
||
flex: 1;
|
||
min-width: 400px;
|
||
background: var(--background);
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.chat-header {
|
||
padding: var(--space-3) var(--space-4);
|
||
background: var(--glass-bg);
|
||
backdrop-filter: blur(var(--glass-blur));
|
||
-webkit-backdrop-filter: blur(var(--glass-blur));
|
||
border-bottom: 1px solid var(--separator);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-3);
|
||
}
|
||
|
||
.chat-header-avatar {
|
||
width: 36px;
|
||
height: 36px;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 18px;
|
||
color: #fff;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.chat-header-info { flex: 1; }
|
||
.chat-header-name { font-size: 16px; font-weight: 600; }
|
||
.chat-header-status { font-size: 11px; color: var(--green); }
|
||
|
||
.chat-header-actions {
|
||
display: flex;
|
||
gap: var(--space-2);
|
||
}
|
||
.chat-action-btn {
|
||
width: 32px;
|
||
height: 32px;
|
||
border-radius: 50%;
|
||
border: none;
|
||
background: var(--surface-secondary);
|
||
color: var(--text-secondary);
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: all 0.2s;
|
||
}
|
||
.chat-action-btn:hover { background: var(--primary-light); color: var(--primary); }
|
||
|
||
.chat-messages {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
padding: var(--space-4);
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-2);
|
||
}
|
||
|
||
.message-row {
|
||
display: flex;
|
||
gap: var(--space-2);
|
||
max-width: 75%;
|
||
animation: msgIn 0.3s ease;
|
||
}
|
||
.message-row.self {
|
||
align-self: flex-end;
|
||
flex-direction: row-reverse;
|
||
}
|
||
|
||
@keyframes msgIn {
|
||
from { opacity: 0; transform: translateY(8px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
.msg-avatar {
|
||
width: 28px;
|
||
height: 28px;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 14px;
|
||
flex-shrink: 0;
|
||
color: #fff;
|
||
}
|
||
|
||
.msg-bubble {
|
||
padding: var(--space-2) var(--space-3);
|
||
border-radius: var(--radius-xl);
|
||
font-size: 14px;
|
||
line-height: 1.5;
|
||
position: relative;
|
||
}
|
||
|
||
.message-row:not(.self) .msg-bubble {
|
||
background: var(--bubble-other);
|
||
color: var(--text);
|
||
border-top-left-radius: var(--radius-sm);
|
||
}
|
||
|
||
.message-row.self .msg-bubble {
|
||
background: var(--bubble-self);
|
||
color: #fff;
|
||
border-top-right-radius: var(--radius-sm);
|
||
}
|
||
|
||
.msg-time {
|
||
font-size: 10px;
|
||
color: var(--text-tertiary);
|
||
margin-top: var(--space-1);
|
||
text-align: center;
|
||
}
|
||
|
||
.message-row.self .msg-time { text-align: right; }
|
||
|
||
.chat-date-divider {
|
||
text-align: center;
|
||
padding: var(--space-2) 0;
|
||
font-size: 11px;
|
||
color: var(--text-tertiary);
|
||
}
|
||
|
||
.chat-input-area {
|
||
padding: var(--space-3);
|
||
background: var(--glass-bg);
|
||
backdrop-filter: blur(var(--glass-blur));
|
||
border-top: 1px solid var(--separator);
|
||
display: flex;
|
||
gap: var(--space-2);
|
||
align-items: flex-end;
|
||
}
|
||
|
||
.chat-input-wrapper {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: flex-end;
|
||
gap: var(--space-2);
|
||
background: var(--surface-secondary);
|
||
border-radius: 20px;
|
||
padding: var(--space-1) var(--space-2);
|
||
border: 1px solid var(--separator);
|
||
transition: border-color 0.2s;
|
||
}
|
||
.chat-input-wrapper:focus-within { border-color: var(--primary); }
|
||
|
||
.chat-input {
|
||
flex: 1;
|
||
border: none;
|
||
background: transparent;
|
||
color: var(--text);
|
||
padding: var(--space-1) var(--space-2);
|
||
font-size: 14px;
|
||
font-family: var(--font-family);
|
||
outline: none;
|
||
resize: none;
|
||
max-height: 80px;
|
||
min-height: 24px;
|
||
line-height: 1.4;
|
||
}
|
||
.chat-input::placeholder { color: var(--text-tertiary); }
|
||
|
||
.chat-attach-btn {
|
||
width: 28px;
|
||
height: 28px;
|
||
border-radius: 50%;
|
||
border: none;
|
||
background: transparent;
|
||
color: var(--text-secondary);
|
||
font-size: 16px;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: all 0.2s;
|
||
}
|
||
.chat-attach-btn:hover { color: var(--primary); }
|
||
|
||
.chat-send-btn {
|
||
width: 36px;
|
||
height: 36px;
|
||
border-radius: 50%;
|
||
border: none;
|
||
background: var(--primary);
|
||
color: #fff;
|
||
font-size: 16px;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: all 0.2s;
|
||
flex-shrink: 0;
|
||
}
|
||
.chat-send-btn:hover { opacity: 0.85; }
|
||
|
||
::-webkit-scrollbar { width: 6px; }
|
||
::-webkit-scrollbar-track { background: transparent; }
|
||
::-webkit-scrollbar-thumb { background: var(--text-tertiary); border-radius: 3px; }
|
||
::-webkit-scrollbar-thumb:hover { background: var(--text-secondary); }
|
||
</style>
|
||
</head>
|
||
<body data-theme="light">
|
||
|
||
<div class="app-shell">
|
||
<nav class="nav-sidebar">
|
||
<div class="nav-logo">💬</div>
|
||
<a class="nav-item" href="widescreen-home.html" title="闲言">
|
||
<span class="nav-icon">💬</span>
|
||
<span class="nav-label">闲言</span>
|
||
</a>
|
||
<a class="nav-item active" href="widescreen-discover.html" title="发现">
|
||
<span class="nav-icon">🧭</span>
|
||
<span class="nav-label">发现</span>
|
||
</a>
|
||
<a class="nav-item" href="widescreen-profile.html" title="我的">
|
||
<span class="nav-icon">👤</span>
|
||
<span class="nav-label">我的</span>
|
||
</a>
|
||
<div class="nav-spacer"></div>
|
||
<button class="nav-theme-btn" onclick="toggleTheme()" title="切换主题">🌙</button>
|
||
</nav>
|
||
|
||
<div class="content-area">
|
||
<div class="master-panel" id="masterPanel">
|
||
<div class="master-header">
|
||
<div class="master-title">发现</div>
|
||
<div class="master-subtitle">探索有趣的会话流</div>
|
||
<div class="master-search">
|
||
<input class="search-input" type="text" placeholder="🔍 搜索会话流...">
|
||
</div>
|
||
</div>
|
||
<div class="flow-list" id="flowList">
|
||
<div class="flow-card selected" onclick="selectFlow(this, 0)">
|
||
<div class="flow-avatar" style="background:linear-gradient(135deg,#007AFF,#5856D6)">🤖</div>
|
||
<div class="flow-info">
|
||
<div class="flow-name">AI 诗词助手</div>
|
||
<div class="flow-preview">为您推荐一首适合今天的诗…</div>
|
||
</div>
|
||
<div class="flow-meta">
|
||
<span class="flow-time">刚刚</span>
|
||
<span class="flow-badge">3</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flow-card" onclick="selectFlow(this, 1)">
|
||
<div class="flow-avatar" style="background:linear-gradient(135deg,#FF9500,#FF3B30)">📚</div>
|
||
<div class="flow-info">
|
||
<div class="flow-name">每日一句</div>
|
||
<div class="flow-preview">今天的句子来自泰戈尔…</div>
|
||
</div>
|
||
<div class="flow-meta">
|
||
<span class="flow-time">10:30</span>
|
||
<span class="flow-badge">1</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flow-card" onclick="selectFlow(this, 2)">
|
||
<div class="flow-avatar" style="background:linear-gradient(135deg,#34C759,#007AFF)">🎭</div>
|
||
<div class="flow-info">
|
||
<div class="flow-name">古风意境</div>
|
||
<div class="flow-preview">春江潮水连海平,海上明…</div>
|
||
</div>
|
||
<div class="flow-meta">
|
||
<span class="flow-time">昨天</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flow-card" onclick="selectFlow(this, 3)">
|
||
<div class="flow-avatar" style="background:linear-gradient(135deg,#5856D6,#FF2D55)">✍️</div>
|
||
<div class="flow-info">
|
||
<div class="flow-name">写作灵感</div>
|
||
<div class="flow-preview">试试用这个开头写一段…</div>
|
||
</div>
|
||
<div class="flow-meta">
|
||
<span class="flow-time">昨天</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flow-card" onclick="selectFlow(this, 4)">
|
||
<div class="flow-avatar" style="background:linear-gradient(135deg,#5AC8FA,#34C759)">🎵</div>
|
||
<div class="flow-info">
|
||
<div class="flow-name">诗词配乐</div>
|
||
<div class="flow-preview">为这首诗配上合适的音乐…</div>
|
||
</div>
|
||
<div class="flow-meta">
|
||
<span class="flow-time">2天前</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flow-card" onclick="selectFlow(this, 5)">
|
||
<div class="flow-avatar" style="background:linear-gradient(135deg,#FF2D55,#FF9500)">🌍</div>
|
||
<div class="flow-info">
|
||
<div class="flow-name">世界名句</div>
|
||
<div class="flow-preview">To be or not to be…</div>
|
||
</div>
|
||
<div class="flow-meta">
|
||
<span class="flow-time">3天前</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flow-card" onclick="selectFlow(this, 6)">
|
||
<div class="flow-avatar" style="background:linear-gradient(135deg,#FFCC00,#FF9500)">☀️</div>
|
||
<div class="flow-info">
|
||
<div class="flow-name">早安寄语</div>
|
||
<div class="flow-preview">新的一天,新的开始…</div>
|
||
</div>
|
||
<div class="flow-meta">
|
||
<span class="flow-time">3天前</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="divider-handle" id="divider"></div>
|
||
|
||
<div class="detail-panel" id="detailPanel">
|
||
<div class="chat-header" id="chatHeader">
|
||
<div class="chat-header-avatar" style="background:linear-gradient(135deg,#007AFF,#5856D6)" id="chatAvatar">🤖</div>
|
||
<div class="chat-header-info">
|
||
<div class="chat-header-name" id="chatName">AI 诗词助手</div>
|
||
<div class="chat-header-status" id="chatStatus">● 在线</div>
|
||
</div>
|
||
<div class="chat-header-actions">
|
||
<button class="chat-action-btn" title="搜索">🔍</button>
|
||
<button class="chat-action-btn" title="更多">⋯</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="chat-messages" id="chatMessages">
|
||
<div class="chat-date-divider">今天 10:24</div>
|
||
|
||
<div class="message-row">
|
||
<div class="msg-avatar" style="background:linear-gradient(135deg,#007AFF,#5856D6)">🤖</div>
|
||
<div>
|
||
<div class="msg-bubble">你好!我是 AI 诗词助手 🎋 今天想聊些什么呢?我可以为你推荐诗词、解析名句、或者陪你品诗论词。</div>
|
||
<div class="msg-time">10:24</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="message-row self">
|
||
<div>
|
||
<div class="msg-bubble">帮我推荐一首适合今天的诗吧,今天心情有点低落 😔</div>
|
||
<div class="msg-time">10:25</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="message-row">
|
||
<div class="msg-avatar" style="background:linear-gradient(135deg,#007AFF,#5856D6)">🤖</div>
|
||
<div>
|
||
<div class="msg-bubble">心情低落的时候,苏轼的词最能抚慰人心。推荐你这首 📜</div>
|
||
<div class="msg-time">10:25</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="message-row">
|
||
<div class="msg-avatar" style="background:linear-gradient(135deg,#007AFF,#5856D6)">🤖</div>
|
||
<div>
|
||
<div class="msg-bubble" style="background:var(--surface-secondary);border:1px solid var(--separator);border-radius:var(--radius-xl);border-top-left-radius:var(--radius-sm)">
|
||
<div style="font-weight:600;margin-bottom:8px">🎋 《定风波·莫听穿林打叶声》</div>
|
||
<div style="font-style:italic;line-height:1.8;margin-bottom:8px">
|
||
莫听穿林打叶声,何妨吟啸且徐行。<br>
|
||
竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生。<br><br>
|
||
料峭春风吹酒醒,微冷,山头斜照却相迎。<br>
|
||
回首向来萧瑟处,归去,也无风雨也无晴。
|
||
</div>
|
||
<div style="font-size:12px;color:var(--text-secondary)">—— 苏轼</div>
|
||
</div>
|
||
<div class="msg-time">10:25</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="message-row self">
|
||
<div>
|
||
<div class="msg-bubble">"也无风雨也无晴" 这句真的很有力量</div>
|
||
<div class="msg-time">10:26</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="message-row">
|
||
<div class="msg-avatar" style="background:linear-gradient(135deg,#007AFF,#5856D6)">🤖</div>
|
||
<div>
|
||
<div class="msg-bubble">是的!这句词的境界非常高 🌟 苏轼经历了乌台诗案,被贬黄州,却依然能写出这样豁达的词句。他告诉我们:无论是风雨还是晴天,内心都可以保持平静。这才是真正的"不以物喜,不以己悲" 💪</div>
|
||
<div class="msg-time">10:26</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="message-row self">
|
||
<div>
|
||
<div class="msg-bubble">还有类似的推荐吗?</div>
|
||
<div class="msg-time">10:27</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="message-row">
|
||
<div class="msg-avatar" style="background:linear-gradient(135deg,#007AFF,#5856D6)">🤖</div>
|
||
<div>
|
||
<div class="msg-bubble">当然!再推荐一首李白的《行路难》✨</div>
|
||
<div class="msg-time">10:28</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="chat-input-area">
|
||
<div class="chat-input-wrapper">
|
||
<button class="chat-attach-btn">📎</button>
|
||
<textarea class="chat-input" rows="1" placeholder="输入消息..."></textarea>
|
||
<button class="chat-attach-btn">😊</button>
|
||
</div>
|
||
<button class="chat-send-btn">↑</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
const flows = [
|
||
{
|
||
avatar: '🤖', name: 'AI 诗词助手', status: '● 在线', gradient: 'linear-gradient(135deg,#007AFF,#5856D6)',
|
||
messages: [
|
||
{ type: 'date', text: '今天 10:24' },
|
||
{ from: 'other', text: '你好!我是 AI 诗词助手 🎋 今天想聊些什么呢?我可以为你推荐诗词、解析名句、或者陪你品诗论词。', time: '10:24' },
|
||
{ from: 'self', text: '帮我推荐一首适合今天的诗吧,今天心情有点低落 😔', time: '10:25' },
|
||
{ from: 'other', text: '心情低落的时候,苏轼的词最能抚慰人心。推荐你这首 📜', time: '10:25' },
|
||
{ from: 'other', text: '🎋 《定风波》\n莫听穿林打叶声,何妨吟啸且徐行。\n竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生。', time: '10:25', isPoem: true },
|
||
{ from: 'self', text: '"也无风雨也无晴" 这句真的很有力量', time: '10:26' },
|
||
{ from: 'other', text: '是的!这句词的境界非常高 🌟 苏轼经历了乌台诗案,被贬黄州,却依然能写出这样豁达的词句。', time: '10:26' },
|
||
]
|
||
},
|
||
{
|
||
avatar: '📚', name: '每日一句', status: '● 在线', gradient: 'linear-gradient(135deg,#FF9500,#FF3B30)',
|
||
messages: [
|
||
{ type: 'date', text: '今天 08:00' },
|
||
{ from: 'other', text: '🌅 早安!今天的句子来自泰戈尔:', time: '08:00' },
|
||
{ from: 'other', text: '"如果你因失去了太阳而流泪,那么你也失去了群星。"\n—— 泰戈尔《飞鸟集》', time: '08:00', isPoem: true },
|
||
{ from: 'self', text: '好美!每天一句真的很治愈', time: '08:15' },
|
||
{ from: 'other', text: '谢谢!明天同一时间再见 😊', time: '08:16' },
|
||
]
|
||
},
|
||
{
|
||
avatar: '🎭', name: '古风意境', status: '● 在线', gradient: 'linear-gradient(135deg,#34C759,#007AFF)',
|
||
messages: [
|
||
{ type: 'date', text: '昨天 20:30' },
|
||
{ from: 'other', text: '🌙 夜读张若虚《春江花月夜》', time: '20:30' },
|
||
{ from: 'other', text: '春江潮水连海平,海上明月共潮生。\n滟滟随波千万里,何处春江无月明!', time: '20:30', isPoem: true },
|
||
{ from: 'self', text: '这首诗被誉为"孤篇压全唐"!', time: '20:35' },
|
||
]
|
||
},
|
||
{
|
||
avatar: '✍️', name: '写作灵感', status: '上次在线:昨天', gradient: 'linear-gradient(135deg,#5856D6,#FF2D55)',
|
||
messages: [
|
||
{ type: 'date', text: '昨天 15:00' },
|
||
{ from: 'other', text: '✍️ 今天的写作提示:\n"那天下午,我在旧书店的角落里发现了一封没有署名的信…"', time: '15:00' },
|
||
{ from: 'self', text: '这个开头很有悬念感!', time: '15:10' },
|
||
]
|
||
},
|
||
{
|
||
avatar: '🎵', name: '诗词配乐', status: '上次在线:2天前', gradient: 'linear-gradient(135deg,#5AC8FA,#34C759)',
|
||
messages: [
|
||
{ type: 'date', text: '2天前' },
|
||
{ from: 'other', text: '🎵 为《水调歌头》配上一首古琴曲', time: '14:00' },
|
||
{ from: 'other', text: '明月几时有?把酒问青天。不知天上宫阙,今夕是何年。', time: '14:00', isPoem: true },
|
||
]
|
||
},
|
||
{
|
||
avatar: '🌍', name: '世界名句', status: '上次在线:3天前', gradient: 'linear-gradient(135deg,#FF2D55,#FF9500)',
|
||
messages: [
|
||
{ type: 'date', text: '3天前' },
|
||
{ from: 'other', text: '🌍 Today\'s quote:\n"To be, or not to be, that is the question."\n— Shakespeare', time: '09:00' },
|
||
]
|
||
},
|
||
{
|
||
avatar: '☀️', name: '早安寄语', status: '上次在线:3天前', gradient: 'linear-gradient(135deg,#FFCC00,#FF9500)',
|
||
messages: [
|
||
{ type: 'date', text: '3天前' },
|
||
{ from: 'other', text: '☀️ 早安!新的一天,新的开始。愿你今天一切顺利!', time: '07:00' },
|
||
]
|
||
}
|
||
];
|
||
|
||
function selectFlow(el, idx) {
|
||
document.querySelectorAll('.flow-card').forEach(c => c.classList.remove('selected'));
|
||
el.classList.add('selected');
|
||
const f = flows[idx];
|
||
document.getElementById('chatAvatar').textContent = f.avatar;
|
||
document.getElementById('chatAvatar').style.background = f.gradient;
|
||
document.getElementById('chatName').textContent = f.name;
|
||
document.getElementById('chatStatus').textContent = f.status;
|
||
|
||
const container = document.getElementById('chatMessages');
|
||
container.innerHTML = '';
|
||
f.messages.forEach(m => {
|
||
if (m.type === 'date') {
|
||
container.innerHTML += `<div class="chat-date-divider">${m.text}</div>`;
|
||
return;
|
||
}
|
||
const isSelf = m.from === 'self';
|
||
const avatarHtml = isSelf ? '' : `<div class="msg-avatar" style="background:${f.gradient}">${f.avatar}</div>`;
|
||
const bubbleStyle = m.isPoem
|
||
? `style="background:var(--surface-secondary);border:1px solid var(--separator);white-space:pre-line"`
|
||
: '';
|
||
const bubbleClass = m.isPoem && !isSelf ? 'msg-bubble' : 'msg-bubble';
|
||
container.innerHTML += `
|
||
<div class="message-row ${isSelf ? 'self' : ''}">
|
||
${avatarHtml}
|
||
<div>
|
||
<div class="${bubbleClass}" ${bubbleStyle}>${m.text}</div>
|
||
<div class="msg-time">${m.time}</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
});
|
||
container.scrollTop = container.scrollHeight;
|
||
}
|
||
|
||
function toggleTheme() {
|
||
const body = document.body;
|
||
const btn = document.querySelector('.nav-theme-btn');
|
||
if (body.dataset.theme === 'light') {
|
||
body.dataset.theme = 'dark';
|
||
btn.textContent = '☀️';
|
||
} else {
|
||
body.dataset.theme = 'light';
|
||
btn.textContent = '🌙';
|
||
}
|
||
}
|
||
|
||
const divider = document.getElementById('divider');
|
||
const masterPanel = document.getElementById('masterPanel');
|
||
let isDragging = false;
|
||
|
||
divider.addEventListener('mousedown', () => {
|
||
isDragging = true;
|
||
document.body.style.cursor = 'col-resize';
|
||
document.body.style.userSelect = 'none';
|
||
});
|
||
|
||
document.addEventListener('mousemove', (e) => {
|
||
if (!isDragging) return;
|
||
const navWidth = 72;
|
||
const newWidth = e.clientX - navWidth;
|
||
if (newWidth >= 320 && newWidth <= 600) {
|
||
masterPanel.style.width = newWidth + 'px';
|
||
}
|
||
});
|
||
|
||
document.addEventListener('mouseup', () => {
|
||
isDragging = false;
|
||
document.body.style.cursor = '';
|
||
document.body.style.userSelect = '';
|
||
});
|
||
|
||
const chatInput = document.querySelector('.chat-input');
|
||
chatInput.addEventListener('input', function() {
|
||
this.style.height = 'auto';
|
||
this.style.height = Math.min(this.scrollHeight, 80) + 'px';
|
||
});
|
||
|
||
document.querySelector('.chat-send-btn').addEventListener('click', () => {
|
||
const text = chatInput.value.trim();
|
||
if (!text) return;
|
||
const container = document.getElementById('chatMessages');
|
||
container.innerHTML += `
|
||
<div class="message-row self">
|
||
<div>
|
||
<div class="msg-bubble">${text}</div>
|
||
<div class="msg-time">刚刚</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
chatInput.value = '';
|
||
chatInput.style.height = 'auto';
|
||
container.scrollTop = container.scrollHeight;
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|