From f66cee433330b613abd4030fc51d3c16f3c7d265 Mon Sep 17 00:00:00 2001 From: Ou Date: Sat, 26 Oct 2024 00:00:33 +0800 Subject: [PATCH] feat: refactor metadata structure --- shared/metadata.ts | 52 ++++++++++---------------- shared/sources.ts | 23 ++++++++++++ shared/types.ts | 60 +++++++++++++++++------------- src/atoms/primitiveMetadataAtom.ts | 4 +- src/routes/index.tsx | 2 +- 5 files changed, 79 insertions(+), 62 deletions(-) diff --git a/shared/metadata.ts b/shared/metadata.ts index 7b70226..678ad67 100644 --- a/shared/metadata.ts +++ b/shared/metadata.ts @@ -1,68 +1,54 @@ import { sources } from "./sources" import { typeSafeObjectEntries, typeSafeObjectFromEntries } from "./type.util" -import type { Metadata } from "./types" +import type { ColumnID, Metadata, SourceID } from "./types" export const columnIds = ["focus", "realtime", "hottest", "china", "world", "tech", "finance"] as const -const originMetadata: Metadata = { +const columnName: Record = { china: { - name: "国内", - sources: ["zhihu", "thepaper", "douyin", "bilibili-hot-search", "weibo", "toutiao", "tieba"], + zh: "国内", }, world: { - name: "国际", - sources: ["zaobao", "cankaoxiaoxi", "kaopu"], + zh: "国际", }, tech: { - name: "科技", - sources: ["hackernews", "producthunt", "github-trending-today", "v2ex", "ithome", "coolapk", "solidot"], + zh: "科技", }, finance: { - name: "财经", - sources: [ - "cls-telegraph", - "cls-depth", - "wallstreetcn", - "wallstreetcn-hot", - "wallstreetcn-news", - "xueqiu-hotstock", - "gelonghui", - "fastbull-express", - "fastbull-news", - ], + zh: "财经", }, focus: { - name: "关注", - sources: [], + zh: "关注", }, realtime: { - name: "实时", - sources: [], + zh: "实时", }, hottest: { - name: "最热", - sources: [], + zh: "最热", }, } -export const metadata = typeSafeObjectFromEntries(typeSafeObjectEntries(originMetadata).map(([k, v]) => { +export const metadata: Metadata = typeSafeObjectFromEntries(typeSafeObjectEntries(columnName).map(([k, v]) => { switch (k) { case "focus": - return [k, v] + return [k, { + name: v.zh, + sources: [] as SourceID[], + }] case "hottest": return [k, { - ...v, + name: v.zh, sources: typeSafeObjectEntries(sources).filter(([, v]) => v.type === "hottest" && !v.redirect).map(([k]) => k), }] case "realtime": return [k, { - ...v, - sources: ["weibo", ...typeSafeObjectEntries(sources).filter(([, v]) => v.type === "realtime" && !v.redirect).map(([k]) => k)], + name: v.zh, + sources: typeSafeObjectEntries(sources).filter(([, v]) => v.type === "realtime" && !v.redirect).map(([k]) => k), }] default: return [k, { - ...v, - sources: v.sources.filter(s => sources[s]), + name: v.zh, + sources: typeSafeObjectEntries(sources).filter(([, v]) => v.column === k && !v.redirect).map(([k]) => k), }] } })) diff --git a/shared/sources.ts b/shared/sources.ts index bbdd327..d782892 100644 --- a/shared/sources.ts +++ b/shared/sources.ts @@ -19,12 +19,14 @@ export const originSources = { sub: { share: { title: "最新分享", + column: "tech", }, }, }, "zhihu": { name: "知乎", type: "hottest", + column: "china", color: "blue", home: "https://www.zhihu.com", }, @@ -32,6 +34,7 @@ export const originSources = { name: "微博", title: "实时热搜", type: "hottest", + column: "china", color: "red", interval: Time.Realtime, home: "https://weibo.com", @@ -40,12 +43,14 @@ export const originSources = { name: "联合早报", interval: Time.Common, type: "realtime", + column: "world", color: "red", home: "https://www.zaobao.com", }, "coolapk": { name: "酷安", type: "hottest", + column: "tech", color: "green", title: "今日最热", home: "https://coolapk.com", @@ -53,6 +58,7 @@ export const originSources = { "wallstreetcn": { name: "华尔街见闻", color: "blue", + column: "finance", home: "https://wallstreetcn.com/", sub: { quick: { @@ -86,6 +92,7 @@ export const originSources = { "douyin": { name: "抖音", type: "hottest", + column: "china", color: "gray", home: "https://www.douyin.com", }, @@ -97,6 +104,7 @@ export const originSources = { "tieba": { name: "百度贴吧", title: "热议", + column: "china", type: "hottest", color: "blue", home: "https://tieba.baidu.com", @@ -104,12 +112,14 @@ export const originSources = { "toutiao": { name: "今日头条", type: "hottest", + column: "china", color: "red", home: "https://www.toutiao.com", }, "ithome": { name: "IT之家", color: "red", + column: "tech", type: "realtime", home: "https://www.ithome.com", }, @@ -117,6 +127,7 @@ export const originSources = { name: "澎湃新闻", interval: Time.Common, type: "hottest", + column: "china", title: "热榜", color: "gray", home: "https://www.thepaper.cn", @@ -130,12 +141,14 @@ export const originSources = { "cankaoxiaoxi": { name: "参考消息", color: "red", + column: "world", interval: Time.Common, home: "https://china.cankaoxiaoxi.com", }, "cls": { name: "财联社", color: "red", + column: "finance", home: "https://www.cls.cn", sub: { telegraph: { @@ -153,6 +166,7 @@ export const originSources = { name: "雪球", color: "blue", home: "https://xueqiu.com", + column: "finance", sub: { hotstock: { title: "热门股票", @@ -165,6 +179,7 @@ export const originSources = { name: "格隆汇", color: "blue", title: "事件", + column: "finance", type: "realtime", interval: Time.Realtime, home: "https://www.gelonghui.com", @@ -173,6 +188,7 @@ export const originSources = { name: "法布财经", color: "emerald", home: "https://www.fastbull.cn", + column: "finance", sub: { express: { title: "快讯", @@ -188,18 +204,21 @@ export const originSources = { "solidot": { name: "Solidot", color: "teal", + column: "tech", home: "https://solidot.org", interval: Time.Slow, }, "hackernews": { name: "Hacker News", color: "orange", + column: "tech", type: "hottest", home: "https://news.ycombinator.com/", }, "producthunt": { name: "Product Hunt", color: "red", + column: "tech", type: "hottest", home: "https://www.producthunt.com/", }, @@ -207,6 +226,7 @@ export const originSources = { name: "Github", color: "gray", home: "https://github.com/", + column: "tech", sub: { "trending-today": { title: "Today", @@ -221,12 +241,14 @@ export const originSources = { sub: { "hot-search": { title: "热搜", + column: "china", type: "hottest", }, }, }, "kaopu": { name: "靠谱新闻", + column: "world", color: "gray", desc: "不一定靠谱,多看多思考", home: "https://kaopu.news/", @@ -243,6 +265,7 @@ function genSources() { type: source.type, disable: source.disable, desc: source.desc, + column: source.column, home: source.home, color: source.color ?? "primary", interval: source.interval ?? Time.Default, diff --git a/shared/types.ts b/shared/types.ts index 3f26acb..d813b9b 100644 --- a/shared/types.ts +++ b/shared/types.ts @@ -33,40 +33,48 @@ export interface PrimitiveMetadata { action: "init" | "manual" | "sync" } -export interface OriginSource { +type ManualColumnID = Exclude + +export interface OriginSource extends Partial> { name: string - title?: string - desc?: string - /** - * 刷新的间隔时间,复用缓存 - */ - interval?: number - type?: "hottest" | "realtime" - /** - * @default false - */ - disable?: boolean - home?: string - color?: Color sub?: Record + // type?: "hottest" | "realtime" + // desc?: string + // column?: ManualColumnID + // color?: Color + // home?: string + // disable?: boolean + // interval?: number + } & Partial>> } export interface Source { name: string - title?: string - type?: "hottest" | "realtime" - color: Color - desc?: string - home?: string - disable?: boolean + /** + * 刷新的间隔时间 + */ interval: number + color: Color + + /** + * Subtitle 小标题 + */ + title?: string + desc?: string + /** + * Default normal timeline + */ + type?: "hottest" | "realtime" + column?: ManualColumnID + home?: string + /** + * @default false + */ + disable?: boolean redirect?: SourceID } diff --git a/src/atoms/primitiveMetadataAtom.ts b/src/atoms/primitiveMetadataAtom.ts index 6c33dce..61fc111 100644 --- a/src/atoms/primitiveMetadataAtom.ts +++ b/src/atoms/primitiveMetadataAtom.ts @@ -46,8 +46,8 @@ export function preprocessMetadata(target: PrimitiveMetadata) { typeSafeObjectEntries(target.data) .filter(([id]) => initialMetadata[id]) .map(([id, s]) => { - if (id === "focus") return [id, s.filter(k => sources[k])] - const oldS = s.filter(k => initialMetadata[id].includes(k)) + if (id === "focus") return [id, s.filter(k => sources[k]).map(k => sources[k].redirect ?? k)] + const oldS = s.filter(k => initialMetadata[id].includes(k)).map(k => sources[k].redirect ?? k) const newS = initialMetadata[id].filter(k => !oldS.includes(k)) return [id, [...oldS, ...newS]] }), diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 86f6eb4..be152c2 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -9,5 +9,5 @@ export const Route = createFileRoute("/")({ function IndexComponent() { const focusSources = useAtomValue(focusSourcesAtom) - return + return }