feat: 图库双源接入(Pexels+Unsplash,统一 PhotoProvider)与几何预设扩充

- providers.ts: PHOTO_PROVIDERS 注册表,Pexels 在前(dev 速率高);providerById
- unsplash.ts: 改造成 PhotoProvider(parseUnsplashResponse/unsplashProvider/
  notifyDownload),共享 PhotoProviderError 定义在此叶模块避免注册表互引成环;
  legacy searchUnsplash/unsplashStatus/toAsset/trackDownload 保留(基座旧
  SourcePanel 还在用,删了这轮 typecheck 过不了)
- pexels.ts(新): parsePexelsResponse 纯函数 + pexelsProvider;Authorization 头;
  fullUrl 取 large2x(≈1880)不取原图;无下载统计端点,不实现 notifyDownload
- 没配 key 一律静默 missing,search 抛 PhotoProviderError,模块顶层不抛
- geometry.ts: 新增 GEOMETRY_PRESETS 16 条(固定图案+人工配色,新背景菜单卡片
  数据源)+ 4 个新图案家族(waves/dots/horizon/glow)渲染,复用线性亮度钳制
  保证白字对比度;公开 GeometryKind 不动(旧面板缩略图字典闭合),遗留种子机制
  原样;导出 contrastToWhite/relativeLuminance 供自验
- selfcheck: 手写官方形状样本断言两家解析、缺失态/错误类、预设数量与对比度
This commit is contained in:
2026-09-05 18:24:11 +08:00
parent 19c8c604cb
commit 83f27d9e90
6 changed files with 960 additions and 83 deletions
+11 -9
View File
@@ -1,20 +1,22 @@
import type { PhotoProvider, PhotoProviderId } from "@/types";
import { pexelsProvider } from "./pexels";
import { unsplashProvider } from "./unsplash";
/** 图库调用失败(没配 key、网络错误、被限流)。界面据此显示一句话,不让路径崩掉。 */
export class PhotoProviderError extends Error {
constructor(message: string) {
super(message);
this.name = "PhotoProviderError";
}
}
// 共享错误类定义在 unsplash.ts(依赖最少的叶子模块),这里 re-export 保持桩文件
// 原本的出口路径;pexels.ts 也直接 import 它,避免 providers ↔ 各家模块引成环。
export { PhotoProviderError } from "./unsplash";
/**
* 【T14 待实现】图库注册表。
* 图库注册表。
*
* 顺序即界面上标签页的顺序。**Pexels 在前**:Unsplash demo key 每小时只有 50 次
* 请求,开发期点几下就没了;Pexels 是每小时 200 次、每月 2 万次。
* 界面只认 `PhotoProvider` 接口遍历这里,不写 `if (provider === "pexels")`。
*/
export const PHOTO_PROVIDERS: PhotoProvider[] = [];
export const PHOTO_PROVIDERS: readonly PhotoProvider[] = [
pexelsProvider,
unsplashProvider,
];
export function providerById(id: PhotoProviderId): PhotoProvider | undefined {
return PHOTO_PROVIDERS.find((p) => p.id === id);