mirror of
https://github.com/ourongxing/newsnow.git
synced 2025-01-31 10:58:04 +08:00
feat: refactor metadata structure
This commit is contained in:
parent
ecc678a2bb
commit
f66cee4333
@ -1,68 +1,54 @@
|
|||||||
import { sources } from "./sources"
|
import { sources } from "./sources"
|
||||||
import { typeSafeObjectEntries, typeSafeObjectFromEntries } from "./type.util"
|
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
|
export const columnIds = ["focus", "realtime", "hottest", "china", "world", "tech", "finance"] as const
|
||||||
|
|
||||||
const originMetadata: Metadata = {
|
const columnName: Record<ColumnID, { zh: string }> = {
|
||||||
china: {
|
china: {
|
||||||
name: "国内",
|
zh: "国内",
|
||||||
sources: ["zhihu", "thepaper", "douyin", "bilibili-hot-search", "weibo", "toutiao", "tieba"],
|
|
||||||
},
|
},
|
||||||
world: {
|
world: {
|
||||||
name: "国际",
|
zh: "国际",
|
||||||
sources: ["zaobao", "cankaoxiaoxi", "kaopu"],
|
|
||||||
},
|
},
|
||||||
tech: {
|
tech: {
|
||||||
name: "科技",
|
zh: "科技",
|
||||||
sources: ["hackernews", "producthunt", "github-trending-today", "v2ex", "ithome", "coolapk", "solidot"],
|
|
||||||
},
|
},
|
||||||
finance: {
|
finance: {
|
||||||
name: "财经",
|
zh: "财经",
|
||||||
sources: [
|
|
||||||
"cls-telegraph",
|
|
||||||
"cls-depth",
|
|
||||||
"wallstreetcn",
|
|
||||||
"wallstreetcn-hot",
|
|
||||||
"wallstreetcn-news",
|
|
||||||
"xueqiu-hotstock",
|
|
||||||
"gelonghui",
|
|
||||||
"fastbull-express",
|
|
||||||
"fastbull-news",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
focus: {
|
focus: {
|
||||||
name: "关注",
|
zh: "关注",
|
||||||
sources: [],
|
|
||||||
},
|
},
|
||||||
realtime: {
|
realtime: {
|
||||||
name: "实时",
|
zh: "实时",
|
||||||
sources: [],
|
|
||||||
},
|
},
|
||||||
hottest: {
|
hottest: {
|
||||||
name: "最热",
|
zh: "最热",
|
||||||
sources: [],
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const metadata = typeSafeObjectFromEntries(typeSafeObjectEntries(originMetadata).map(([k, v]) => {
|
export const metadata: Metadata = typeSafeObjectFromEntries(typeSafeObjectEntries(columnName).map(([k, v]) => {
|
||||||
switch (k) {
|
switch (k) {
|
||||||
case "focus":
|
case "focus":
|
||||||
return [k, v]
|
return [k, {
|
||||||
|
name: v.zh,
|
||||||
|
sources: [] as SourceID[],
|
||||||
|
}]
|
||||||
case "hottest":
|
case "hottest":
|
||||||
return [k, {
|
return [k, {
|
||||||
...v,
|
name: v.zh,
|
||||||
sources: typeSafeObjectEntries(sources).filter(([, v]) => v.type === "hottest" && !v.redirect).map(([k]) => k),
|
sources: typeSafeObjectEntries(sources).filter(([, v]) => v.type === "hottest" && !v.redirect).map(([k]) => k),
|
||||||
}]
|
}]
|
||||||
case "realtime":
|
case "realtime":
|
||||||
return [k, {
|
return [k, {
|
||||||
...v,
|
name: v.zh,
|
||||||
sources: ["weibo", ...typeSafeObjectEntries(sources).filter(([, v]) => v.type === "realtime" && !v.redirect).map(([k]) => k)],
|
sources: typeSafeObjectEntries(sources).filter(([, v]) => v.type === "realtime" && !v.redirect).map(([k]) => k),
|
||||||
}]
|
}]
|
||||||
default:
|
default:
|
||||||
return [k, {
|
return [k, {
|
||||||
...v,
|
name: v.zh,
|
||||||
sources: v.sources.filter(s => sources[s]),
|
sources: typeSafeObjectEntries(sources).filter(([, v]) => v.column === k && !v.redirect).map(([k]) => k),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
@ -19,12 +19,14 @@ export const originSources = {
|
|||||||
sub: {
|
sub: {
|
||||||
share: {
|
share: {
|
||||||
title: "最新分享",
|
title: "最新分享",
|
||||||
|
column: "tech",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"zhihu": {
|
"zhihu": {
|
||||||
name: "知乎",
|
name: "知乎",
|
||||||
type: "hottest",
|
type: "hottest",
|
||||||
|
column: "china",
|
||||||
color: "blue",
|
color: "blue",
|
||||||
home: "https://www.zhihu.com",
|
home: "https://www.zhihu.com",
|
||||||
},
|
},
|
||||||
@ -32,6 +34,7 @@ export const originSources = {
|
|||||||
name: "微博",
|
name: "微博",
|
||||||
title: "实时热搜",
|
title: "实时热搜",
|
||||||
type: "hottest",
|
type: "hottest",
|
||||||
|
column: "china",
|
||||||
color: "red",
|
color: "red",
|
||||||
interval: Time.Realtime,
|
interval: Time.Realtime,
|
||||||
home: "https://weibo.com",
|
home: "https://weibo.com",
|
||||||
@ -40,12 +43,14 @@ export const originSources = {
|
|||||||
name: "联合早报",
|
name: "联合早报",
|
||||||
interval: Time.Common,
|
interval: Time.Common,
|
||||||
type: "realtime",
|
type: "realtime",
|
||||||
|
column: "world",
|
||||||
color: "red",
|
color: "red",
|
||||||
home: "https://www.zaobao.com",
|
home: "https://www.zaobao.com",
|
||||||
},
|
},
|
||||||
"coolapk": {
|
"coolapk": {
|
||||||
name: "酷安",
|
name: "酷安",
|
||||||
type: "hottest",
|
type: "hottest",
|
||||||
|
column: "tech",
|
||||||
color: "green",
|
color: "green",
|
||||||
title: "今日最热",
|
title: "今日最热",
|
||||||
home: "https://coolapk.com",
|
home: "https://coolapk.com",
|
||||||
@ -53,6 +58,7 @@ export const originSources = {
|
|||||||
"wallstreetcn": {
|
"wallstreetcn": {
|
||||||
name: "华尔街见闻",
|
name: "华尔街见闻",
|
||||||
color: "blue",
|
color: "blue",
|
||||||
|
column: "finance",
|
||||||
home: "https://wallstreetcn.com/",
|
home: "https://wallstreetcn.com/",
|
||||||
sub: {
|
sub: {
|
||||||
quick: {
|
quick: {
|
||||||
@ -86,6 +92,7 @@ export const originSources = {
|
|||||||
"douyin": {
|
"douyin": {
|
||||||
name: "抖音",
|
name: "抖音",
|
||||||
type: "hottest",
|
type: "hottest",
|
||||||
|
column: "china",
|
||||||
color: "gray",
|
color: "gray",
|
||||||
home: "https://www.douyin.com",
|
home: "https://www.douyin.com",
|
||||||
},
|
},
|
||||||
@ -97,6 +104,7 @@ export const originSources = {
|
|||||||
"tieba": {
|
"tieba": {
|
||||||
name: "百度贴吧",
|
name: "百度贴吧",
|
||||||
title: "热议",
|
title: "热议",
|
||||||
|
column: "china",
|
||||||
type: "hottest",
|
type: "hottest",
|
||||||
color: "blue",
|
color: "blue",
|
||||||
home: "https://tieba.baidu.com",
|
home: "https://tieba.baidu.com",
|
||||||
@ -104,12 +112,14 @@ export const originSources = {
|
|||||||
"toutiao": {
|
"toutiao": {
|
||||||
name: "今日头条",
|
name: "今日头条",
|
||||||
type: "hottest",
|
type: "hottest",
|
||||||
|
column: "china",
|
||||||
color: "red",
|
color: "red",
|
||||||
home: "https://www.toutiao.com",
|
home: "https://www.toutiao.com",
|
||||||
},
|
},
|
||||||
"ithome": {
|
"ithome": {
|
||||||
name: "IT之家",
|
name: "IT之家",
|
||||||
color: "red",
|
color: "red",
|
||||||
|
column: "tech",
|
||||||
type: "realtime",
|
type: "realtime",
|
||||||
home: "https://www.ithome.com",
|
home: "https://www.ithome.com",
|
||||||
},
|
},
|
||||||
@ -117,6 +127,7 @@ export const originSources = {
|
|||||||
name: "澎湃新闻",
|
name: "澎湃新闻",
|
||||||
interval: Time.Common,
|
interval: Time.Common,
|
||||||
type: "hottest",
|
type: "hottest",
|
||||||
|
column: "china",
|
||||||
title: "热榜",
|
title: "热榜",
|
||||||
color: "gray",
|
color: "gray",
|
||||||
home: "https://www.thepaper.cn",
|
home: "https://www.thepaper.cn",
|
||||||
@ -130,12 +141,14 @@ export const originSources = {
|
|||||||
"cankaoxiaoxi": {
|
"cankaoxiaoxi": {
|
||||||
name: "参考消息",
|
name: "参考消息",
|
||||||
color: "red",
|
color: "red",
|
||||||
|
column: "world",
|
||||||
interval: Time.Common,
|
interval: Time.Common,
|
||||||
home: "https://china.cankaoxiaoxi.com",
|
home: "https://china.cankaoxiaoxi.com",
|
||||||
},
|
},
|
||||||
"cls": {
|
"cls": {
|
||||||
name: "财联社",
|
name: "财联社",
|
||||||
color: "red",
|
color: "red",
|
||||||
|
column: "finance",
|
||||||
home: "https://www.cls.cn",
|
home: "https://www.cls.cn",
|
||||||
sub: {
|
sub: {
|
||||||
telegraph: {
|
telegraph: {
|
||||||
@ -153,6 +166,7 @@ export const originSources = {
|
|||||||
name: "雪球",
|
name: "雪球",
|
||||||
color: "blue",
|
color: "blue",
|
||||||
home: "https://xueqiu.com",
|
home: "https://xueqiu.com",
|
||||||
|
column: "finance",
|
||||||
sub: {
|
sub: {
|
||||||
hotstock: {
|
hotstock: {
|
||||||
title: "热门股票",
|
title: "热门股票",
|
||||||
@ -165,6 +179,7 @@ export const originSources = {
|
|||||||
name: "格隆汇",
|
name: "格隆汇",
|
||||||
color: "blue",
|
color: "blue",
|
||||||
title: "事件",
|
title: "事件",
|
||||||
|
column: "finance",
|
||||||
type: "realtime",
|
type: "realtime",
|
||||||
interval: Time.Realtime,
|
interval: Time.Realtime,
|
||||||
home: "https://www.gelonghui.com",
|
home: "https://www.gelonghui.com",
|
||||||
@ -173,6 +188,7 @@ export const originSources = {
|
|||||||
name: "法布财经",
|
name: "法布财经",
|
||||||
color: "emerald",
|
color: "emerald",
|
||||||
home: "https://www.fastbull.cn",
|
home: "https://www.fastbull.cn",
|
||||||
|
column: "finance",
|
||||||
sub: {
|
sub: {
|
||||||
express: {
|
express: {
|
||||||
title: "快讯",
|
title: "快讯",
|
||||||
@ -188,18 +204,21 @@ export const originSources = {
|
|||||||
"solidot": {
|
"solidot": {
|
||||||
name: "Solidot",
|
name: "Solidot",
|
||||||
color: "teal",
|
color: "teal",
|
||||||
|
column: "tech",
|
||||||
home: "https://solidot.org",
|
home: "https://solidot.org",
|
||||||
interval: Time.Slow,
|
interval: Time.Slow,
|
||||||
},
|
},
|
||||||
"hackernews": {
|
"hackernews": {
|
||||||
name: "Hacker News",
|
name: "Hacker News",
|
||||||
color: "orange",
|
color: "orange",
|
||||||
|
column: "tech",
|
||||||
type: "hottest",
|
type: "hottest",
|
||||||
home: "https://news.ycombinator.com/",
|
home: "https://news.ycombinator.com/",
|
||||||
},
|
},
|
||||||
"producthunt": {
|
"producthunt": {
|
||||||
name: "Product Hunt",
|
name: "Product Hunt",
|
||||||
color: "red",
|
color: "red",
|
||||||
|
column: "tech",
|
||||||
type: "hottest",
|
type: "hottest",
|
||||||
home: "https://www.producthunt.com/",
|
home: "https://www.producthunt.com/",
|
||||||
},
|
},
|
||||||
@ -207,6 +226,7 @@ export const originSources = {
|
|||||||
name: "Github",
|
name: "Github",
|
||||||
color: "gray",
|
color: "gray",
|
||||||
home: "https://github.com/",
|
home: "https://github.com/",
|
||||||
|
column: "tech",
|
||||||
sub: {
|
sub: {
|
||||||
"trending-today": {
|
"trending-today": {
|
||||||
title: "Today",
|
title: "Today",
|
||||||
@ -221,12 +241,14 @@ export const originSources = {
|
|||||||
sub: {
|
sub: {
|
||||||
"hot-search": {
|
"hot-search": {
|
||||||
title: "热搜",
|
title: "热搜",
|
||||||
|
column: "china",
|
||||||
type: "hottest",
|
type: "hottest",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"kaopu": {
|
"kaopu": {
|
||||||
name: "靠谱新闻",
|
name: "靠谱新闻",
|
||||||
|
column: "world",
|
||||||
color: "gray",
|
color: "gray",
|
||||||
desc: "不一定靠谱,多看多思考",
|
desc: "不一定靠谱,多看多思考",
|
||||||
home: "https://kaopu.news/",
|
home: "https://kaopu.news/",
|
||||||
@ -243,6 +265,7 @@ function genSources() {
|
|||||||
type: source.type,
|
type: source.type,
|
||||||
disable: source.disable,
|
disable: source.disable,
|
||||||
desc: source.desc,
|
desc: source.desc,
|
||||||
|
column: source.column,
|
||||||
home: source.home,
|
home: source.home,
|
||||||
color: source.color ?? "primary",
|
color: source.color ?? "primary",
|
||||||
interval: source.interval ?? Time.Default,
|
interval: source.interval ?? Time.Default,
|
||||||
|
@ -33,40 +33,48 @@ export interface PrimitiveMetadata {
|
|||||||
action: "init" | "manual" | "sync"
|
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
|
name: string
|
||||||
title?: string
|
|
||||||
desc?: string
|
|
||||||
/**
|
|
||||||
* 刷新的间隔时间,复用缓存
|
|
||||||
*/
|
|
||||||
interval?: number
|
|
||||||
type?: "hottest" | "realtime"
|
|
||||||
/**
|
|
||||||
* @default false
|
|
||||||
*/
|
|
||||||
disable?: boolean
|
|
||||||
home?: string
|
|
||||||
color?: Color
|
|
||||||
sub?: Record<string, {
|
sub?: Record<string, {
|
||||||
|
/**
|
||||||
|
* Subtitle 小标题
|
||||||
|
*/
|
||||||
title: string
|
title: string
|
||||||
type?: "hottest" | "realtime"
|
// type?: "hottest" | "realtime"
|
||||||
desc?: string
|
// desc?: string
|
||||||
home?: string
|
// column?: ManualColumnID
|
||||||
disable?: boolean
|
// color?: Color
|
||||||
interval?: number
|
// home?: string
|
||||||
}>
|
// disable?: boolean
|
||||||
|
// interval?: number
|
||||||
|
} & Partial<Omit<Source, "title" | "name" | "redirect">>>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Source {
|
export interface Source {
|
||||||
name: string
|
name: string
|
||||||
title?: string
|
/**
|
||||||
type?: "hottest" | "realtime"
|
* 刷新的间隔时间
|
||||||
color: Color
|
*/
|
||||||
desc?: string
|
|
||||||
home?: string
|
|
||||||
disable?: boolean
|
|
||||||
interval: number
|
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
|
redirect?: SourceID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,8 +46,8 @@ export function preprocessMetadata(target: PrimitiveMetadata) {
|
|||||||
typeSafeObjectEntries(target.data)
|
typeSafeObjectEntries(target.data)
|
||||||
.filter(([id]) => initialMetadata[id])
|
.filter(([id]) => initialMetadata[id])
|
||||||
.map(([id, s]) => {
|
.map(([id, s]) => {
|
||||||
if (id === "focus") return [id, s.filter(k => sources[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))
|
const oldS = s.filter(k => initialMetadata[id].includes(k)).map(k => sources[k].redirect ?? k)
|
||||||
const newS = initialMetadata[id].filter(k => !oldS.includes(k))
|
const newS = initialMetadata[id].filter(k => !oldS.includes(k))
|
||||||
return [id, [...oldS, ...newS]]
|
return [id, [...oldS, ...newS]]
|
||||||
}),
|
}),
|
||||||
|
@ -9,5 +9,5 @@ export const Route = createFileRoute("/")({
|
|||||||
|
|
||||||
function IndexComponent() {
|
function IndexComponent() {
|
||||||
const focusSources = useAtomValue(focusSourcesAtom)
|
const focusSources = useAtomValue(focusSourcesAtom)
|
||||||
return <Column id={focusSources.length ? "focus" : "realtime"} />
|
return <Column id={focusSources.length ? "focus" : "hottest"} />
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user