Releases: kingsxiao/mac-file-drawer
Releases · kingsxiao/mac-file-drawer
Release list
FileDrawer v1.8.0
- 拖入补齐「万物」——图像数据与文件承诺:此前拖入只认 文件 URL / 链接 / 纯文本,三大高频来源全部失守——照片 App 拖图(文件承诺形态)直接收不到、邮件附件大概率同样失败、浏览器拖图退化成
.webloc链接(要的是那张图,存下的却是个网址)。本次在InboxStore.url(fromProvider:)的解析链上补齐两条通道:① 图像载荷优先于随行 URL——浏览器拖图同时携带图像数据与 URL,现在先落图本身(浏览器 TIFF / PNG / GIF、SVG 等凡 conforms topublic.image的注册类型都命中),suggestedName作命名提示、去重与消毒沿用收件箱既有规则;② 文件承诺 / 文件表示接收——loadFileRepresentation把照片(HEIC)、照片视频(movie)、音频、PDF 附件等承诺文件按原始文件名收进收件箱(交付的临时 URL 回调内立即移动,跨卷退化为拷贝;系统不 coerce 数据表示的 provider 走原始数据自写文件兜底,扩展名取注册类型惯用扩展)。接收类型表DropFileLoader.typeIdentifiers扩为 原四类 +image/movie/audio/pdf白名单(显式白名单而非笼统public.data,任意数据型拖拽不会把抽屉误当落点;展开态与收起芯片共用同一 onDrop,芯片同样能接);解析优先级定为 真实文件 URL 引用 > 图像载荷 > 其余媒体承诺 > 链接 webloc > 纯文本(真实文件始终原地引用不搬家)。⌘V 同步支持图像:剪贴板是「拷贝图像」(TIFF / PNG)时直接物化成收件箱图片文件,且优先于随行的图片地址字符串(用户意图是图不是链接)。收件箱物化文件沿用既有生命周期(移除 + 撤销窗口关闭后sweep回收)。验证:新增 8 个单测——图像+URL 并存落图不落 webloc、纯图像数据物化、文件承诺(JPEG/PDF 文件表示)按原始名收进收件箱、文件 URL 优先于图像数据、白名单 conformance 判定(HEIC/MPEG-4/MP3 命中、URL/文本/未知类型不命中)、粘贴 TIFF 物化、粘贴图像优先于随行文本、未识别自定义类型返回 nil(原「未识别载荷」用例以 PNG 充当,语义已变,改为真正的未声明类型);220 测试全绿 + release 零警告。实机行为(照片 App / Safari 真拖拽)待人工验证
FileDrawer v1.7.0
- 收起态重做「悬浮芯片」(方案定稿:三选一中的 A)(用户反馈:悬停效果与展开按钮奇怪、胶囊握把版仍不好看)——两轮迭代定稿为「小物件」路线:收起态不再是一条 46×196 高条(预览 / 计数 / 把手三组职能挤在窄条里怎么摆都显挤),而是屏幕边上一枚 44×100 的玻璃悬浮芯片(Dropover / Yoink 流派),与停靠边留 3pt 悬浮缝,像贴在屏幕边的便签夹;窗口总尺寸相应改为 54×104(芯片 + 缝 + 悬停外探行程,布局测试同步)。内容自上而下:最新一张缩略瓷片 32×32(里面是什么)、等宽粗体计数(14pt rounded)、品牌紫 5pt 状态灯(唯一彩色元素);空态换托盘图形。整枚芯片就是按钮:芯片不带任何描边与投影(静息发丝线、空态虚线槽、贴边投影均按用户反馈「收起状态去掉边框」三轮迭代移除——静息时 radius 6 的深色投影紧贴圆角边缘本身就会被看成一圈 border,hover 时加深外扩(radius 6→10、透明度 0.14→0.24)正是「border 变大」的观感来源),边界感由材质与屏幕内容的对比承担,悬停 = 整枚向屏幕中线滑出 6pt——纯物理动作;按压 = 向停靠边推回 3pt 合上悬浮缝 + 轻缩 0.96(像把小物件按回墙上);真 Button 本体让 System Events / VoiceOver 可 AXPress(旧 onTapGesture 手势控件无 AXPress,辅助功能按不了)。悬停描边历经三轮用户反馈定稿为「零描边零投影」:先是光环方案因「hover 不要外框」移除(光环本体曾以两层结构恒定描边 + 只动透明度修复过闪跳——
StrokeStyle不可动画会整层闪跳、品牌紫 NSColor 动态 provider 与灰互插会闪帧),再是静息发丝线与空态虚线槽移除,最后投影也移除(hover 反馈只剩滑出动作);拖放接收描边是功能反馈,保留。中间形态「胶囊握把」(28×46 握把 + 纸叠内容组,a7e355d)经实机验证后按用户反馈废弃。验证:明暗两态静息 / 悬停实机截图像素级核对(结构 / 滑出 / 点亮确认,此轮在物理屏完成)、空态与左缘停靠镜像、AXPress 实测展开、212 测试全绿;边框修复的 hover 过渡帧复核因远控虚拟显示器不合成透明窗口(实测最小透明面板同样不渲染,环境问题非代码问题)无法截屏,依结构性论证(无可动画属性跨样式切换)+ 测试保障 - 排序把手重做「沟槽让位」(用户反馈:悬停时左缘拖动把手太大、盖在缩略图上很突兀)——废弃 3fbab29 的「毛玻璃芯片浮层」方案(16×38 胶囊芯片叠在瓷片上),改为悬停时行内容右移 16pt(紧凑 14pt)让出左缘沟槽,9.5pt 纤细三横线裸图标把手在沟槽里亮起:落在行卡片自身安静的底色上天然有对比度,无芯片 / 无描边 / 无投影,不再覆盖缩略图;「让位」动作本身就是可拖拽的暗示,与拖入悬停「列表退后」同一动效语言;命中区靠纵向 padding 扩至全行高(视觉体积不增),行体 onDrag 保持不变,抓把手 / 抓行体都能开排序会话(设计稿 §九.3;验证:临时常显补丁截图核对把手居沟槽不压瓷片)
- 用户反馈修订「去紫 + 头部收敛」:① 图标与搜索 UI 去紫——头部图标定稿中性灰底 + primary 符号(试行品牌渐变底后按用户反馈「图标不要用紫色」回退);搜索胶囊聚焦态从品牌紫描边 + 紫色外发光改为中性石墨描边(primary 0.30)+ 底色微升、外发光删除,聚焦放大镜与头部放大镜激活态均改 primary——搜索 UI 全程无彩色,品牌紫此后只保留在拖放反馈 / 置顶图钉角标 / 收起边条把手与计数徽章 / 搜索命中高亮等瞬态或角标场景;② 移除头部右上角「收起成边条」按钮(与左缘拉手重复),收起路径收敛为左缘拉手 / 菜单栏 / 全局热键,头部按钮组只剩 排序 · 搜索 · 设置(设计稿 §九同步修订)
- UI / 交互全面打磨「设计先行」(设计稿:
docs/ui-optimization-design-2026-09.md,审计 → 设计 → 实施 → 验证四步走):对展开态明暗两态、搜索态、收起边条做视觉审计 + 代码走读,归纳十项问题后按设计稿逐项实施——① 头部信息整合:分组计数从孤立灰色胶囊改为紧随组名的三级灰等宽注脚(少一个描边元素;头部图标保持中性灰底,见上条反馈修订);② 搜索匹配计数:搜索激活时计数注脚切换为青瓷色N/M(匹配数/分组总数,沿用选中色系表达「当前视图状态」),0 命中也显示;③ 排序按钮状态外显:图标从恒定双箭头改为当前排序模式专属符号(时钟环 / 沙漏 / abc / 网格 / 排序把手),切换带 symbol replace 动效,菜单项同步加图标提升可扫读性;SortMode.symbol顺势换掉休眠的textformat.abc(中文环境渲染成汉字的已知陷阱);④ 搜索胶囊消歧:删掉输入框外右侧的「关闭搜索」X(与框内「清空文本」X 比邻、语义易混),关闭路径收敛为 Esc 与再次点击头部放大镜(放大镜升级 toggle:已展开且无文本时点击收起,有文本时聚焦不清空);⑤ 置顶分区线:置顶区与非置顶区之间加 hairline 分隔(两区都非空才出现,透明度 0.16——实测 0.10 在浅色玻璃上低于可感知阈值);置顶图钉角标 7→8.5pt 从「隐约可见」到「一眼可辨」;⑥ 拖入退后感:拖入悬停时列表轻退后(opacity 0.55 + scale 0.985),描边与「松开」徽章上前,符合「内容让位给新文件」的心智;⑦ Toast 让位:撤销 / 轻提示出现期间列表底部 padding 12→64 随弹簧动画让位,最后一行不再被盖住;⑧ 预览卡 footer:键盘提示 chips 居左成组、元信息居右、之间加发丝竖线分隔,不再挤作一团;⑨ 行内悬停操作钮间距 1→4pt;⑩ 新增文案入英文表。验证:a11y 树核对(搜索态无双 X、匹配计数 1/10、toggle 收起)、像素级核对(浅色分隔线 / 深色品牌瓷片与角标 / 青瓷计数色)、.app 形态走filedrawer://remove实测 toast 让位与回落、明暗两态整体目检(212 测试全绿) - 拖拽排序链路加固「会话记录替代落点解码」:拖动把手排序在真实拖拽会话里可能整条失灵的根因——行级落点代理(validateDrop / dropEntered / performDrop)依赖从拖拽 provider 同步解码拖动条目 id(主线程信号量阻塞
loadDataRepresentation最多 1s),而真实会话里落点端 provider 由拖拽 pasteboard 重建,.ownProcess注册的自定义标记与数据并不保证存活:标记一丢,行级代理恒拒收 = 拖到行上无指示条、松手无反应,拖拽排序整个失效(此前所有单测都用进程内现构 provider,覆盖不到这段;同步解码即使成功也在拖动悬停期间反复阻塞主线程)。修复:onDrag 开始(主线程同步)即在 InteractionModel 开「排序会话」记录拖动条目 id 与会话号,落点代理一律读会话记录、完全不解码 provider;会话号防连续快速拖拽时上一次迟到的清理误清新会话;拖拽取消时 SwiftUI 不保证回调 dropExited / 不调 performDrop(指示条残留、脏记录会让下一次外部拖入被误判成排序拖拽),统一由 DragSessionObserver 会话结束轮询清理。顺带两处体验收敛:① 行体拖拽与把手拖拽开同一种排序会话(SwiftUI 嵌套 onDrag 的命中归属不可靠,无论哪处闭包被触发都能排序;拖到抽屉外仍是拷贝文件),排序入口从「仅悬停后的小把手」扩为整行;② 排序落点松手置「落在行上」标记,开启「拖出后自动收起」时排序不再被误当拖出而把抽屉收起(208 测试全绿,含会话生命周期、迟到清理防误清、会话记录驱动落点回归) - 缩略图方形裁切修复:行内图片缩略图「宽度不一」的根因是布局修饰符顺序——
scaledToFill的溢出绘制会把外层 ZStack 的边界撑大成「原始宽高比矩形」,clipShape裁的是这个被撑大的边界,而之后的frame(42×42)只负责摆放不裁剪;结果缩略图从不裁方、直接按图片原始比例显示(竖图窄条左右留空、横图宽条溢出瓷片、超宽图整条压到文件名),不同比例的图片左列参差不齐。修复:把方形frame移进瓷片内部、置于scaledToFill之后clipShape之前,溢出被裁进圆角方形(预览弹层 20pt 头部瓷片与收起态纸叠瓷片共用 FileTile,一并修复)。验证:离屏 ImageRenderer 探针证实旧代码 16:9 图渲染成 74.5×41.5pt、24:5 图溢满整个画布,修复后四种比例(16:9 / 9:16 / 1:1 / 24:5)全部精确 42×42;实机注入测试数据截图像素测量,图片内容边到边铺满瓷片(206 测试全绿) - 性能与包体积专项:app 包 3.7MB → 1.6MB(-57%)、DMG 约 1.9MB → 1.2MB——① 二进制
strip -S -x剥调试/本地符号(实测符号表占未剥离体积 ~65%,3.4MB→1.2MB;strip 后签名,universal 双架构 2.8MB);② AppIcon.icns 全部 PNG 载荷无损再压缩(471KB→278KB,逐条目像素级校验一致,原始 ARGB 小尺寸条目原样保留);③ 缩略图缓存从 ShelfStore 的 @published 拆成独立 ThumbCache ObservableObject(FileTile 直接观察)——此前每个后台解码完成都会触发 ContentView 连带全列表重渲染(含过滤+排序管线与全部行视图),首屏批量补图时逐张触发是滚动卡顿源;④ 「启动丢弃失效条目」从 init 同步 fileExists × n 改为首次后台存在性扫描落地后静默移除(条目指向网络卷时不再卡首帧;无失效条目时行为不变);⑤ 键盘路由的展示管线改惰性计算(多数按键不再每次 keyDown 跑过滤+排序);⑥ 聚焦屏 1s 兜底轮询定时器按需启停(仅聚焦屏模式创建,设置切换重估,鼠标跟随模式不再常驻空转)。实测否决项:-Osize(strip 后零差异)、-dead_strip(零差异)、DMG 换 ULMO/ULFO(反而更大,UDZO 已最优)保持不动 - 手动排序落点修复:两个叠加的落点错误一并修掉——其一,非「手动顺序」排序下(默认「最新在前」)调序以条目存储顺序(添加顺序)为基准计算,而屏幕显示的是排序管线输出,两者整表倒置,表现为拖完条目没落在松手位置、整表跳序;现在调序前先把当前分组条目的存储顺序冻结为屏幕所见顺序(其他分组不动)再切「手动顺序」。其二,落点固定「插到目标行前」,向下拖一格会把条目插回原位 = 完全无操作(向下拖的落点总比预期高一行);改为方向感知:向下拖插到目标行后、向上拖插到目标行前,插入指示条随方向画在行上缘/下缘即所见落点。四个入口统一:拖拽把手、右键菜单「上移/下移/移到最前/移到最后」、⌘↑⌘↓、
filedrawer:// send-to-front(206 测试全绿,含落点冻结、方向判定、下移一格、多选整批、跨分组冻结等回归) - 开源发布基建:补齐 LICENSE(MIT)、CONTRIBUTING、CODE_OF_CONDUCT、SECURITY 与 Issue/PR 模板;新增 tag 触发的自动发版流水线(
release.yml:测试→零警告→universal 构建→校验 tag 与版本一致→DMG/zip/SHA256SUMS→GitHub Release,Notes 自动取自 CHANGELOG 对应段);新增发版助手scripts/cut_release.sh(改版本号、定稿 CHANGELOG、提交、打 tag 一条命令);make_app.sh落实 README 承诺的SIGN_IDENTITY环境变量(缺省仍 ad-hoc) - 收起态边条重新设计:从「图标 + 把手 + 数字」改为「纸叠预览」——上段透出最近 3 条的缩略瓷片(与展开后顺序一致,收起态也会补齐缩略图解码),中段品牌色胶囊 + 指向屏幕中线的 chevron 把手(指示拉开方向),下段品牌渐变计数徽章(白字,与撤销 toast 同视觉语言);空态换成虚线纸槽 + 托盘图标;边条加宽至 46pt(42→46,高度 190→196);外部文件拖到边条上时(关闭自动展开时)现在有品牌色描边接收高亮;悬停重做为「从玻璃上揭起」——外探 5pt + 朝开口侧的接触投影(去掉整体缩放)、品牌描边浮现、纸叠被捏开(层间距撑大、深层变实)、把手亮起胶囊底板,弹簧参数加欠阻尼回弹
- 多显示器适配修复:滑出停帧不再落到相邻显示器上(停靠边外侧紧邻另一块屏时,滑出矩形会出现在邻屏可见区域——表现为抽屉「从隔壁屏幕里飞出来」,现退化为收起边条姿态作为出发/停放帧);跨屏定位改为瞬移(跟随鼠标换屏 / key 窗口换屏时,弹簧动画原本会拖着窗口横穿中间屏幕「飞过桌面」);无屏(headless 启动 / 显示器全部断开)不再中断初始化——菜单栏图标、热键、屏幕监听先就位,显示器接入后立即自动重新定位
- 聚焦屏跟随:多显示器下聚焦屏变化时抽屉自动迁到聚焦屏的停靠边(展开态 / 收起边条同理,跨屏瞬移不飞桌面)——触发源覆盖点击另一块屏、把窗口拖到另一块屏(全局鼠标按下 / 抬起监听)、⌘Tab 切应用、切换空间(Workspace 通知),以及纯键盘焦点漂移(⌘W 关窗后焦点回落等)的 1s 兜底轮询;「展开时停靠到鼠标所在屏幕」关闭时目标屏从「主屏幕」明确为聚焦屏(key 窗口所在屏),开启模式下轮询不生效——鼠标划过邻屏不算聚焦变化,只在离散事件时重评估,避免抽屉追着光标来回跳;屏幕外停放态不跟随,且从异侧停放滑入展开前先把出发点重新停放到聚焦屏外缘(否则滑入动画会拖着窗口横穿中间屏)