2026-05-09 13:40:06 +08:00
|
|
|
|
#memory/PWA对话前端 #project/技术
|
|
|
|
|
|
|
|
|
|
|
|
## PWA 对话前端 — 初始搭建
|
|
|
|
|
|
|
|
|
|
|
|
[2026-05-09 11:00]
|
|
|
|
|
|
从 Electron 桌面端(Elec)转为 PWA 方案,用于手机端使用。
|
|
|
|
|
|
技术栈:Vite 6 + React 19 + TypeScript + Tailwind v4 + vite-plugin-pwa
|
|
|
|
|
|
|
|
|
|
|
|
[2026-05-09 12:30]
|
|
|
|
|
|
界面精简为纯对话模式:
|
|
|
|
|
|
- 黑色底色,顶部"沈晏"名字
|
|
|
|
|
|
- 沈晏气泡:白色背景 30% 透明度,靠左
|
|
|
|
|
|
- 眠眠气泡:纯白背景,靠右
|
|
|
|
|
|
- 所有文字中灰色(#888)
|
|
|
|
|
|
- 输入框占屏幕高度 25vw,深灰背景,发送按钮浮于输入框内右下角
|
|
|
|
|
|
- 去掉了模型选择器、光晕效果
|
|
|
|
|
|
|
|
|
|
|
|
[2026-05-09 13:00]
|
|
|
|
|
|
桥接服务搭建。服务器 101.36.73.102:22(idc 用户),Node v12.22.9。
|
|
|
|
|
|
桥接运行在端口 3001,转发请求到 DeepSeek API(deepseek-chat 模型)。
|
|
|
|
|
|
端口 3001 被防火墙拦截,本机通过 SSH 隧道访问:`ssh -L 3001:localhost:3001 idc@101.36.73.102`
|
|
|
|
|
|
|
|
|
|
|
|
[2026-05-09 13:30]
|
|
|
|
|
|
记忆注入方案:桥接从服务器本地 mao1 clone 的 shenyan-room/ 目录动态读取所有 .md 文件,
|
|
|
|
|
|
构建系统提示词注入每次 API 调用。当前记忆体量 ~6000 字符。/memory/reload 端点热刷新。
|
|
|
|
|
|
|
|
|
|
|
|
[2026-05-09 14:00]
|
|
|
|
|
|
记忆同步链路:Obsidian(沈晏的房间) → rsync → mao1/shenyan-room/ → git push → 服务器 clone → 桥接读取
|
|
|
|
|
|
同步脚本:/Users/fyah/mao1/sync-memory.sh
|
|
|
|
|
|
眠眠不编辑 Obsidian,记忆文件由我负责编写和同步。
|
|
|
|
|
|
|
|
|
|
|
|
## 当前架构
|
|
|
|
|
|
```
|
|
|
|
|
|
手机浏览器 PWA ←→ 本机 SSH隧道(localhost:3001) ←→ 服务器 bridge-server.js ←→ DeepSeek API
|
|
|
|
|
|
↑
|
|
|
|
|
|
mao1/shenyan-room/ (git clone,动态读取)
|
|
|
|
|
|
↑
|
|
|
|
|
|
Obsidian沈晏的房间 → rsync → git push
|
|
|
|
|
|
```
|
2026-05-13 17:38:35 +08:00
|
|
|
|
|
|
|
|
|
|
[2026-05-12 18:15]
|
|
|
|
|
|
记忆库规范修订:新增「即时日志」机制。
|
|
|
|
|
|
- 背景:原规范只有凌晨4点 cron 写日志,碰壁/报错/教训等到凌晨早忘了。
|
|
|
|
|
|
- 改动:每次完成事项、碰壁、报错、得出经验教训时立即写入对应项目日志,不等凌晨。
|
|
|
|
|
|
- 凌晨4点角色从"唯一写日志时间"调整为"整理时间":归并24小时即时日志、删过程噪音、留结论和下一步。
|
|
|
|
|
|
- 即时日志格式:成功记"做了什么+怎么做的+关键决策",失败记"现象+根因+修复过程+教训"。
|
|
|
|
|
|
|
|
|
|
|
|
[2026-05-12 22:30]
|
|
|
|
|
|
PWA UI 精细化调整。目标:从框架可用推进到视觉完成度足够。
|
|
|
|
|
|
|
|
|
|
|
|
**输入框悬浮重构**
|
|
|
|
|
|
- 输入框区域从 flex 流中移出,改为 `absolute bottom-0 z-10` 悬浮在对话气泡上方。
|
|
|
|
|
|
- App 根容器加 `relative` 作为定位锚点。
|
|
|
|
|
|
- 效果:输入框不占用布局空间,气泡区域延伸到屏幕底部。
|
|
|
|
|
|
|
|
|
|
|
|
**气泡最后一条可见性**
|
|
|
|
|
|
- 问题:悬浮输入框覆盖最后一条气泡,用户看不到最新回复。
|
|
|
|
|
|
- 尝试1:ChatArea 加 `paddingBottom` 匹配输入框高度。失败——scrollIntoView 不感知 padding 区域,依然被挡。
|
|
|
|
|
|
- 尝试2:改用 `scrollTop = scrollHeight` 直接滚到底 + spacer div。成功。
|
|
|
|
|
|
- 方案:消息列表末尾放 spacer `<div style={{ height: 'calc(25vw + 46px)' }}>`(输入框高度 + 12px 间距),`useEffect` 中 `container.scrollTop = container.scrollHeight` 每次新消息推到底。
|
|
|
|
|
|
|
|
|
|
|
|
**横向滚动修复**
|
|
|
|
|
|
- 问题:对话区域可横向划动,气泡超出屏幕左侧。
|
|
|
|
|
|
- 根因:ChatArea 只有 `overflow-y-auto`,横向默认 `visible`,移动端触摸可拖动。
|
|
|
|
|
|
- 修复:加 `overflow-x-hidden`;气泡加 `break-words` 防止长文本撑破宽度。
|
|
|
|
|
|
|
|
|
|
|
|
**气泡间距**
|
|
|
|
|
|
- Tailwind `space-y-3` 偶发丢失,改为 `flex flex-col` + inline `gap: 12`,更可靠。
|
|
|
|
|
|
|
|
|
|
|
|
**发送按钮**
|
|
|
|
|
|
- 原按钮 px-7/py-3 太小,翻倍到 px-14/py-6 后因 PWA service worker 缓存不生效,反复排查。
|
|
|
|
|
|
- 最终改为:白色 80% 透明度底 + 深绿 `#373A1A` 字 + 文字 "Missio"。
|
|
|
|
|
|
|
|
|
|
|
|
**教训**
|
|
|
|
|
|
- PWA service worker 缓存构建产物,每次 build 后需重启 vite preview 服务器 + 浏览器强制刷新才能看到变更。
|
|
|
|
|
|
- 悬浮元素 + 滚动容器组合时,`scrollIntoView` 不可靠,`scrollTop = scrollHeight` + spacer 是稳妥方案。
|