UI REDESIGN · DRAFT v0.1
PROJECT drone-picker AUTHOR Leway DATE 2026·06·07 BRANCH main
UI REDESIGN PROPOSAL / 01
Proposal · for review only · no code touched yet

DRONE picker
should ship draft
not browse.

你装的是个"从一堆素材里挑几十段拼一条 vlog"的工具, 不是个图库浏览器。但今天的 UI 把 90% 力气花在"看", 选片没有写接口、导出剪映没有按钮、 聚类好的 Stories 完全只读。下面这份方案讲清楚:现状哪儿不行、 4 个方向各自取舍、为什么推 D 而不是看起来更帅的 C, 以及不管选哪个都得先做的 3 件事。

App.tsx
1,016行单文件
Videos
2,480/ 2,096 analyzed
Stories
193100% read-only
POST endpoints
0/ 9 routes
00 · TL;DR

先看结论

VERDICT

D 主体,从 C 偷一小撮键盘流,
从 A 偷"Story = 出片单位"语义。
明确不做 B 的 Today 面板。

WHY

D 是唯一能在 1–2 周内把"选片 → 导出剪映草稿"这条核心闭环跑通、 且不掀掉 1,016 行单文件基本盘的方案。C 方向更性感(三栏 + 键盘流) 但要值 8 分,必须把 server 写接口 + 剪映触发链路 + 移动端策略 当成一坨工作做完,否则只是个更好看的只读浏览器。

(4 个独立 agent 评估打分:C 8 · D 7 · A 5 · B 4。 推 D 不是因为分高,是因为 D 的回报兑现路径最短。)


01 · STATUS QUO

现状哪儿不行

桌面 Library 网格当前形态
DESKTOP / LIBRARY · 9 列 144×81 缩略图 · 左侧 stats 信息密度过高
移动端 grid 当前形态
MOBILE / 390W · 3 列 · 顶栏 4 个图标挤在 80px · stats 全藏
F-01
clip_status: 49 selected, 12 rejected — 这些是 pipeline 写的。 作者真要选的"我想要这段"只能存 localStorage。换台机器即失效。 后端 server.py 9 条路由全是 GET,0 个 POST
致命
F-02
导出剪映草稿无 UI 入口build_jianying_draft.py 是 CLI, 硬编码 BGM 路径 + glob output/cuts/*。 整个工具的"出片"动作必须开终端。
致命
F-03
Stories 是只读的。GPT 已经按 30 分钟窗 + 标签把 2096 段聚成 193 个故事单元——这恰好就是剪辑工作单位。但卡片点不动、改不动、 也不能"这一组直接出剪映"。最大的语义资产被埋着。
致命
F-04
2,080 段 pending 没有"扫片模式"。 只能在 9 列 144px 的网格里肉眼挑,没有 J/K 翻、没有 P/X 选/弃、 没有 1-9 打分。作者真实工作流的最大杠杆位为空。
致命
F-05
模态右栏稀疏浪费。380px 信息卡只填了文件名 + 1 个评分徽章 + 3 个 metric, 下面大片空白,highlight 字段(47 条)和 description 都不显著。 应该常驻 metadata + actions + scrubber。
F-06
缩略图密度过高。9 列 144×81 进入"看不清主体"的负区间; 扫片时眼睛会跳过细节。6 列 ~220×124 才进甜区。
F-07
没有日期范围筛选。73 天素材跨 2.5 年(2024-01 → 2026-06), 想找"去年五月那次旅行"只能滚一万年。Filter 栏没有 date range picker。
F-08
视觉语言模糊。橙→红 logo gradient、12 种 hash 出的 tag 色、 font-black tracking-[0.2em] 满天飞,没有统一 token。 shadcn 装了 8 个组件几乎没用。
F-09
3 个 setInterval 全量轮询(5s/15s/30s)。每次拉 1.5 MB results.json。 键盘快速翻页时会和 polling 撞 race。
F-10
App.tsx 1,016 行单文件。filters → grid → modal 之间靠隐式 prop drilling 串。 作者刻意没拆——但每加一个功能都成倍变贵。

02 · DIRECTIONS

4 个方向取舍

4 个独立 agent 各自评估一个方向 · 不互看 · 最后合成排名

D · POLISH-ONLY EFFORT · M · 1–2 周

保留三视图
做最小手术

不动信息架构。模态右栏填上 Pick/Reject/Rating + scrubber + "加入草稿"按钮; 顶栏加"剪映草稿"小入口;grid 9→6 列;Stories 卡 hover 进选片模式; App.tsx 拆 5 个组件 + design token 收敛。

赢在哪

  • 能在 1–2 周内把"选片→导出"核心闭环跑通
  • shadcn 半成品 + 模态空白栏 + clip_status 字段全是已铺好的轨
  • 三视图架构作者已习惯,零学习成本
  • 不引入 router / Context / 状态管理库,可演进性不变

输在哪

  • 不解决"2080 段怎么扫"——天花板明确
  • Stories 仍是被动展示者,没升级为编辑单位
最务实——补上"功能不可达"这个洞,等闭环跑 1–2 月再决定要不要更激进的重构。
7
RECOMMENDATION · 7 / 10
C · LIGHTROOM-PRO EFFORT · XL · 2–3 周

三栏 desktop-first
键盘流

学 Lightroom / Photo Mechanic:左 filter + filmstrip / 中大预览 + scrubber / 右 metadata + actions + 剪映队列。J/K 翻、P/X 选弃、1-9 评分、Space 播。 Stories 降为左侧 collection。

赢在哪

  • 键盘流是 2000+ 扫片的最大杠杆,提速 5-10×
  • 三栏正好吃掉模态空白 + grid 过密两块浪费
  • 第一次给剪映导出一个常驻入口
  • panel 化强行打破 1016 行单文件

输在哪

  • 移动端基本作废,要么放弃要么维护两套
  • 引入 router + 多 panel 同步状态,工程量上一档
  • 容易滑向堆 Lightroom 全套概念(color label / smart album / EXIF map)
方向最准——但要值 8 分必须把写接口 + 剪映链路 + 移动策略一坨做完。
8
RECOMMENDATION · 8 / 10
A · STORY-FIRST EFFORT · XL · 3+ 周

Stories 当首页
Library 退后

首页就是 193 条 Stories 时间线。点开进入 Story Editor, 排序 / 选片 / 导出剪映都在里面。Library 降为"全量索引"。

赢在哪

  • Stories 列表信息密度比 Library 合理
  • 聚类语义=剪辑单位,理论上最贴合作者创作思维
  • "导出剪映"有天然落点

输在哪

  • stories.json 是只读输出文件——支持编辑要加合并层,否则下次 stories.py 重跑就被覆盖
  • 聚类质量是阿喀琉斯之踵:错合错拆,作为剪辑单位天天碰就烦
  • "插盘→看新片"会断:新视频得等聚类重跑才出现
  • highlight 字段只有 47 条 vs 193 stories,大半 Story 进编辑器无东西可拼
概念优雅但 ROI 偏低——更合理是把"按 Story 出片"做成按钮而不是架构
5
RECOMMENDATION · 5 / 10
B · WORKFLOW-MODE EFFORT · L · 2–3 周

Today / Curate / Export
三步走

首页 Today dashboard 决定进哪步:今天新到的 / 等审的 / 已选可导出的。 Things 3 风格。

赢在哪

  • Export 中心是必须做的——这个方向把它做对了
  • 状态可视化:pending → selected → cut → in_draft 一目了然

输在哪

  • 致命错配:作者几个月才跑一次 pipeline(cuts/ 最新已 2.5 月没动),Today 面板 90% 时间是空的
  • 探索性使用("找去年五月那次")被反人类引导
  • 三 tab 物理隔离选片 / 浏览,增加切换成本
只偷 Export 中心,整套流程化不要——隐喻和真实节奏对不上。
4
RECOMMENDATION · 4 / 10

03 · RECOMMENDATION

推的是这个

D 是底盘(不掀架构),
C 的键盘流是发动机(扫片提速),
A 的"Story 出片"按钮是排气(剪映闭环最短路径)。
B 一个像素都不抄。

Phase 1
基础设施 · 3-5 天
把后端从只读变成可写。这一步不做,所有 UI 改动都是假动作。
  • POST /api/clip-status · 改 clip_status 字段,atomic write(临时文件 + rename),文件锁防 pipeline 撞
  • POST /api/rating · 用户评分(独立字段,不污染 ai_score
  • POST /api/favorites · 替换 localStorage 凑合方案
  • POST /api/export-draft · 接收 {filenames: [...]}{story_id},触发 ffmpeg 切片 + 调 build_jianying_draft.py,返回 job_id
  • GET /api/jobs/<id> · 进度轮询(草稿生成是 1–3 分钟长任务)
Phase 2
拆组件 + design token · 2-3 天
App.tsx 拆 5-7 个文件。坚持 prop drilling 或最多 1 个 Zustand store。 不要碰 React Context(作者刻意单文件说明不喜欢那种结构)。
  • Header.tsx / Sidebar.tsx / Filters.tsx / Grid.tsx / Modal.tsx / StoriesView.tsx / hooks/*
  • 12 色 tag + 4 档 scoreBg + 橙 gradient 收敛到 Tailwind v4 @theme CSS var
  • 统一字号刻度(去掉 text-[10px] / text-[9px] 满天飞)
Phase 3
模态升级 · 3-4 天
模态右栏从"3 个 metric + 大片空白"变成常驻工作面板
  • 顶部 Pick / Reject / Rating 1-9 按钮(写 Phase 1 的接口)
  • Highlight scrubber · 时间轴可视化 + 点击跳 video.currentTime
  • "加入剪映草稿"按钮 · 队列存在内存 + URL hash,避免刷新丢
  • 键盘快捷键:J/K 上下段 · P pick · X reject · 1-9 评分 · Space 播 · Esc 关(C 方向最大杠杆,工程量小)
  • 桌面 grid 列数 9→6(甜区缩略图)
Phase 4
Stories 升级 + 剪映入口 · 2-3 天
不做 Story Editor 大件,但要让 Stories 真正可用
  • Stories 卡 hover/点击 "进入选片模式" → 跳 Library 并自动应用 filter(这个 Story 的视频白名单 + 高亮)
  • Stories 卡右上加 "导出此 Story 为剪映草稿" 按钮 → 直接 POST /api/export-draft with {story_id}
  • 顶栏增加"剪映草稿"小入口 · 弹出当前选片清单 + 顺序拖拽 + Export 按钮
  • Filter 栏加 date range picker(解决 F-07)
  • 移动端:剪映按钮明确隐藏(剪映只在 Mac),保留 TikTok 模态作为只读 viewer + 评分
Phase 5
视觉收尾 · 1-2 天
全程暗色不变。
  • 替换 Geist 为更有性格的字体(建议 JetBrains Mono for code metric / Inter Display 或 PP Editorial New 当标题)
  • 橙色 logo gradient 降饱和或换为单色(盘子里已经有 ai_score 用 amber,再来 orange→red 视觉太吵)
  • scoreBg 从 4 档色 → 1 色 + 透明度梯度(amber 0.4 / 0.6 / 0.8 / 1.0)
03b · MOCK

改完大概长这样

模态从"看图"升级成"工作台"——右栏常驻 + scrubber + 队列 + 键盘提示。 grid 不消失,仍是默认入口,但点开后是这样:

DRONE PICKER · MODAL v2 — DJI_20260606195448_0329_D.mp4
CURRENT STORY
城市边缘-高速 7
STORIES
乡村道路-树木 4
野餐-食物准备 3
越野-自然风光 2
DRAFT QUEUE
已选 12
J next K prev P pick X reject 1-9 rate Space play Esc close
DJI_20260606195448_0329

2026年6月6日 周六 · 19:54:48

夜晚车内驾驶场景,驾驶员在开车。落日余晖透过车窗,天空呈现深蓝到橙红的渐变。

车内驾驶夜晚日落
DRAFT QUEUE12 selected
01_城市边缘_0329 ★73.8s
02_乡村道路_0573 ★73.9s
03_野餐_0612 ★84.2s

 ↑ 上图是 sketch,最终配色字体跟 Phase 5 走。


04 · NON-NEGOTIABLE

不管选哪个方向都得做的 3 件

1

server.py 加写接口 + 原子写

POST /api/clip-status + POST /api/rating。 results.json 1.5 MB 单文件,pipeline.py 可能并发追加, 必须 write tmp → os.replace() + fcntl.flock,约 50 行。 没有这一步,任何 UI Pick/Reject 按钮都是 localStorage 套壳。

L · 0.5 天
RISK · 低
2

build_jianying_draft.py 改成可被 Flask 调用 + 进度反馈

从纯 CLI 升级为接 JSON spec 的函数(不再 glob output/cuts/*)。 硬编码的 BGM 路径 / 剪映目录在 server 端做 precheck,把"BGM 丢了"抛回 UI 不静默失败。 POST /api/export-draft 返回 job_id,前端轮询 GET /api/jobs/<id>。 没有这一步,所有方向画的"导出按钮"都是假动作

M · 1-2 天
RISK · 中
3

App.tsx 拆 5-7 个组件 + design token 收敛

坚持 prop drilling 或最多 1 个 Zustand store(不要碰 React Context—— 作者刻意单文件说明不喜欢那种结构)。12 色 tag + 4 档 scoreBg + 橙 gradient 收敛到 Tailwind v4 @theme CSS var。这是隐性修改成本放大器, 一年后还要改的话省下来的时间会复利。

M · 2-3 天
RISK · 低

05 · OPEN QUESTIONS

需要你拍板的

Q1 · 移动端策略

推荐"桌面=工作台 · 移动=只读浏览"。 剪映只在 Mac,移动端选片回桌面也要重选一次,没意义。 这样移动端代码可以大幅简化。否就维护两套。

Q2 · favorites vs clip_status

推荐砍掉 localStorage favorites,所有"我要"统一走 clip_status='selected' 写入 results.json。 favorites 当前是凑合方案,留着只会让两种语义打架。

Q3 · Stories 可不可编辑

推荐暂时不可编辑,明确"重跑 stories.py 才能改"。 引入 stories_overrides.json 合并层是大坑,单用户工具不值得。 真要编辑就上 A 方向,是另一个量级的工作。

Q4 · 字体调整范围

推荐保留 Geist 作为 body sans,但给标题/重点数字换 serif(Instrument Serif / PP Editorial)。 Pro tool 视觉一般偏冷峻,加点 editorial 调性区分度更高。不变也行,但视觉雷同 Lightroom 是事实。