feat: refactor metadata structure

This commit is contained in:
Ou 2024-10-26 00:00:33 +08:00
parent ecc678a2bb
commit f66cee4333
5 changed files with 79 additions and 62 deletions

View File

@ -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<ColumnID, { zh: string }> = {
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),
}]
}
}))

View File

@ -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,

View File

@ -33,40 +33,48 @@ export interface PrimitiveMetadata {
action: "init" | "manual" | "sync"
}
export interface OriginSource {
type ManualColumnID = Exclude<ColumnID, "focus" | "realtime" | "hottest">
export interface OriginSource extends Partial<Omit<Source, "name" | "redirect">> {
name: string
title?: string
desc?: string
/**
*
*/
interval?: number
type?: "hottest" | "realtime"
/**
* @default false
*/
disable?: boolean
home?: string
color?: Color
sub?: Record<string, {
/**
* Subtitle
*/
title: string
type?: "hottest" | "realtime"
desc?: string
home?: string
disable?: boolean
interval?: number
}>
// type?: "hottest" | "realtime"
// desc?: string
// column?: ManualColumnID
// color?: Color
// home?: string
// disable?: boolean
// interval?: number
} & Partial<Omit<Source, "title" | "name" | "redirect">>>
}
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
}

View File

@ -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]]
}),

View File

@ -9,5 +9,5 @@ export const Route = createFileRoute("/")({
function IndexComponent() {
const focusSources = useAtomValue(focusSourcesAtom)
return <Column id={focusSources.length ? "focus" : "realtime"} />
return <Column id={focusSources.length ? "focus" : "hottest"} />
}