Skip to content

feat: 传递文本 v2 — 手机收文本到 Mac#26

Merged
rrbe merged 17 commits into
masterfrom
feat/text-transfer-v2
Jun 27, 2026
Merged

feat: 传递文本 v2 — 手机收文本到 Mac#26
rrbe merged 17 commits into
masterfrom
feat/text-transfer-v2

Conversation

@rrbe

@rrbe rrbe commented Jun 25, 2026

Copy link
Copy Markdown
Owner

实现 PLAN §7「传递文本 · v2」:手机 → Mac·收文本(与已落地的 v1 #25 对称的反向通道)。

计划(设计已锁定,见 PLAN):

  • 独立收件箱通道POST /ls/text 收文本,不落盘;Mac 端长出「收到的文本」列表(来源 IP/设备名 + 时间,单条复制/删/清空)。
  • 闸门:opt-in 默认关(参照 uploadEnabled),但不限分享形态——什么都没分享也能开,开了就把服务拉起、出一张指向发送页的 QR。
  • 提醒:仅应用内(复用 onUpload 卡片机制 + 未读角标),不发系统通知。
  • 防滥用:双上限——单条 ~64KB + 收件箱 ~100 条挤旧。
  • 手机端:「发文本给电脑」表单,与上传表单同处 / 独立发送页。
  • 设置「持久化收到的文本」默认关。

第一笔:PLAN 标记 v1 已落地、v2 实现中。后续提交逐步落地。WIP。

rrbe added 17 commits June 26, 2026 00:09
手机→Mac 的反向文本通道(与 v1 对称),独立于 share、不落盘。

- FileServer:POST /ls/text 收一段纯文本(请求体即原文),textInboxEnabled
  闸门 + 单条 64KB 上限(事后 413)+ onReceiveText 回调;GET /ls/send 出独立
  发送页;listing 页按 canReceiveText 内嵌发送表单。
- SendText:可复用的「发文本给电脑」表单片段 + 独立发送页骨架。
- 预览/文本壳页(PreviewPage 及 md/json/csv/文本查看器)开收件箱时也内嵌发送
  表单,使纯文本分享 /ls/text 成「读 + 回填」双向页。
- 权限提示:Permission.recvText 经 permSummary 在网页眉头追加「· 可收文本」+
  一枚 chip(不计入 writable,只读/可读写仍指内容本身)。
- 手机端体验:壳页加 touch-action:manipulation 禁双击放大;发送框手机 16px 防
  聚焦缩放;文本页复制按钮挪到正文下方、复制走 readonly+屏外 textarea 防页面跳动。
- Lang:新增中英文案(设置/收件箱/发送页/错误/JS 提示)。
- HeadlessServer:LS_RECV / LS_RECV_LOG 钩子,供端到端冒烟。
- AppState:receivedTexts(上限 100 挤旧)、textInboxEnabled、persistReceivedText、
  未读计数;isServing / isReceiveOnly 把闸门纳入 start/stop/clearShare/QR;
  onReceiveText hop 回主线程;复制/删/清空/持久化。
- ContentView:收件箱卡片(复用「新收到」样式 + 来源/时长 + 复制/删/清空 + 未读角标);
  只收模式 ticket(含 ✕ 一键退出 → 回初始);设置页「允许收文本」+「记住收到的文本」
  两开关;qrPass 指向 /ls/send;router 改按 isServing 分流。
- Components:InboxGlyph 收件箱图标。
- tools/smoke-text-receive.sh(16 项):只收模式 URL 直指 /ls/send、302 清洗、
  原文逐字回读(UTF-8 + < 不被破坏)、无 token 403 / 空白 400 / 超 64KB 413、
  闸门关时 404/403 且列表无表单、文件夹+收件箱列表内嵌表单。
- TextShareTests:ReceivedText 来源回退、Codable 往返、id 唯一。
- ci.yml:接入收文本冒烟。
§5 进度补 v2 落点说明;§7 标题与 v2 小节改「已落地」;持久化双开关均已落地。
- 主页「分享文本」旁并排「接收文本」开关,开启即就地长出收件二维码与收件箱,不跳独立页
- 屏幕路由按「是否有分享内容」(isEmpty) 判定,只收模式留在功能选择页、可随时关闭
- 手机发送页记录本地「已发送」历史(localStorage,点一条回填),失败按 403/413/网络细分提示
把「分享文本 / 接收文本」并进一个二级页 TextScreen(Screen.text):上半编辑器发文本、
中间一个二维码、下半「允许收文本」开关 + 收件箱。主页 EmptyScreen 收敛回纯功能选择(拖拽
分享 / 一个「传递文本」入口,带未读角标与在线指示),不再就地长接收卡。

网页侧 GET /ls/text 改为恒可渲染:有共享文本发预览壳页(开着接收即自带发送框,
PreviewPage.canReceiveText),无文本但开着接收则退化成纯发送页——一页一码、两端双向。
二维码(makeURL)与 headless URL 一律指 /ls/text;旧 /ls/send 保留为 302 跳 /ls/text 兼容。
删去 ReceiveHomeCard / ReceiveToggleButton / InboxGlyph 与随之失效的文案键。
smoke-text-receive.sh 改测 /ls/text 退化页 + /ls/send 302。
setSharedText 不再每次生成新 token。原先每次发送/更新文本都轮换 token,会作废旧链接——
手机浏览器一刷新就 403、得重扫码;文件+文本共存时还会连累文件分享的访客一起掉线。

改为与分享文件一致的「会话」维度:token 只在会话边界轮换(setShared 换分享、stop/clearShare
结束)。会话内编辑/更新文本不换钥匙,正在看的手机刷新仍有效。要作废旧链接就停止/清除。
PlainTextEditor.updateNSView 在 tv.hasMarkedText()(拼音组合中)时直接返回。文本页内联编辑器在
服务运行时会被 2s 在线人数轮询触发的周期性重渲染反复调用 updateNSView,若组合期间回写 string /
重设 typing 属性会打断 marked text、吞字。组合结束后下一拍自然补同步。
「已发送」历史项右侧缀一个克制的相对时间,规则控长度:24h 内显示 HH:MM、
一年内显示 MM/DD、更久显示 YYYY。历史项存储从纯字符串升级为 {t:文本, d:发送时刻ms},
带迁移(旧的纯字符串记录归一为无时间戳、时间留空,重发即带上)。.sh-item 改 flex 行:
左正文两行截断、右时间 nowrap 不挤正文。时间纯客户端按渲染时刻相对计算。
两处:
- recordReceivedText 仅在 screen != .text 时累加未读——人已在传递文本页(收件箱在眼前)
  收到的直接算已读,修掉「正在页面上却清不掉红点」的 bug;配合 onAppear 清零,逻辑闭合。
- TransferTextButton 不再用常驻红点表示「接收开着」:未读只走右上角红色数字角标;接收开着、
  无未读时缀一颗缓慢呼吸(淡入淡出)的红点,用动效表实时接收中,与静态未读角标天然区分。
扫码的对端可能是平板/另一台电脑,不一定是手机。把 Mac 端文案里的「手机」改成中性说法
(沿用既有的「设备」语气):发送给手机→发送文本、手机扫码后…→对方扫码后…、等待手机发来→
等待对方发来、…手机扫码即可→…扫码即可、CLI「手机可能无法访问」→「其它设备可能无法访问」。
英文侧同步。顺手把误名的枚举 sendToPhoneKicker 改名 sendTextKicker。手机端「发送文本到电脑」
本就中性,未动。
「已发送」历史标题行右侧加一个克制的「清空」按钮:点一下清掉本机这份 localStorage 发送记录
(手机自用、从不回传 Mac),整段随即隐藏。主要给「一台设备被多人先后扫码」时主动抹掉自己的
发送痕迹。单击即清、不弹二次确认(本地便利数据、低风险,主场景是递给别人前快速清空)。i18n 加
clearHistory(清空 / Clear)。
传递文本此前没有单一的「停止」——要彻底停得手动撤文本 + 关接收,且文本页 ← 是纯导航
(回选择页但服务照跑),于是会出现「服务在跑、主页却显待命」。

- AppState.stopTextTransfer():一步撤文本 + 关接收 + 停服务(轮换 token 作废旧链接)+ 回选择页。
- TextScreen:正在传递(发或收)时出红色「停止」按钮,对齐文件票据的停止动作。
- EmptyScreen:服务在后台续跑时表头改用 StatusPill 如实显运行态(亮点 + 实际 IP:端口),
  不再骗「待命」;「传递文本」入口的呼吸点改由 isRunning 驱动(此屏必无文件分享),
  分享文本时也亮,不只接收时。
@rrbe rrbe merged commit cb0e714 into master Jun 27, 2026
1 check passed
@rrbe rrbe deleted the feat/text-transfer-v2 branch June 27, 2026 04:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant