Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e68dc6c

Browse files
基本实现热榜展示
1 parent f1999fb commit e68dc6c

File tree

2 files changed

+275
-9
lines changed

2 files changed

+275
-9
lines changed

‎src/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
import './scripts/helloWorld.tsx'
1+
import './scripts/newsTop.tsx'

‎src/scripts/newsTop.tsx‎

Lines changed: 274 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,166 @@ import {Col} from '@app/lib/components'
1515
import {WstackProps} from '@app/types/widget'
1616
import {FC} from 'react'
1717

18+
/**榜单信息*/
19+
interface TopInfo {
20+
/**榜单名字*/
21+
title: string
22+
23+
/**榜单链接*/
24+
href: string
25+
}
26+
27+
/**文章信息*/
28+
interface ArticleInfo {
29+
/**文章标题*/
30+
title: string
31+
32+
/**原文地址*/
33+
href: string
34+
35+
/**文章热度*/
36+
hot: string
37+
}
38+
39+
/**页面信息*/
40+
interface PageInfo {
41+
/**页面标题*/
42+
title: string
43+
44+
/**该榜单的 logo */
45+
logo: string
46+
47+
/**文章列表*/
48+
articleList: ArticleInfo[]
49+
50+
/**js执行的错误信息*/
51+
err: Error
52+
}
53+
54+
/**内置榜单别名,可在桌面小部件编辑传入别名*/
55+
const topList: TopInfo[] = [
56+
{
57+
title: '知乎',
58+
href: 'https://tophub.today/n/mproPpoq6O',
59+
},
60+
{
61+
title: '微博',
62+
href: 'https://tophub.today/n/KqndgxeLl9',
63+
},
64+
{
65+
title: '微信',
66+
href: 'https://tophub.today/n/WnBe01o371',
67+
},
68+
{
69+
title: '澎湃',
70+
href: 'https://tophub.today/n/wWmoO5Rd4E',
71+
},
72+
{
73+
title: '百度',
74+
href: 'https://tophub.today/n/Jb0vmloB1G',
75+
},
76+
{
77+
title: '知乎日报',
78+
href: 'https://tophub.today/n/KMZd7VOvrO',
79+
},
80+
{
81+
title: '历史上的今天',
82+
href: 'https://tophub.today/n/KMZd7X3erO',
83+
},
84+
{
85+
title: '神马搜索',
86+
href: 'https://tophub.today/n/n6YoVqDeZa',
87+
},
88+
{
89+
title: '搜狗',
90+
href: 'https://tophub.today/n/NaEdZndrOM',
91+
},
92+
{
93+
title: '今日头条',
94+
href: 'https://tophub.today/n/x9ozB4KoXb',
95+
},
96+
{
97+
title: '360搜索',
98+
href: 'https://tophub.today/n/KMZd7x6erO',
99+
},
100+
{
101+
title: '36氪',
102+
href: 'https://tophub.today/n/Q1Vd5Ko85R',
103+
},
104+
{
105+
title: '好奇心日报',
106+
href: 'https://tophub.today/n/Y3QeLGAd7k',
107+
},
108+
{
109+
title: '少数派',
110+
href: 'https://tophub.today/n/Y2KeDGQdNP',
111+
},
112+
{
113+
title: '果壳',
114+
href: 'https://tophub.today/n/20MdK2vw1q',
115+
},
116+
{
117+
title: '虎嗅网',
118+
href: 'https://tophub.today/n/5VaobgvAj1',
119+
},
120+
{
121+
title: 'IT之家',
122+
href: 'https://tophub.today/n/74Kvx59dkx',
123+
},
124+
{
125+
title: '爱范儿',
126+
href: 'https://tophub.today/n/74KvxK7okx',
127+
},
128+
{
129+
title: 'GitHub',
130+
href: 'https://tophub.today/n/rYqoXQ8vOD',
131+
},
132+
{
133+
title: '威锋网',
134+
href: 'https://tophub.today/n/n4qv90roaK',
135+
},
136+
{
137+
title: 'CSDN',
138+
href: 'https://tophub.today/n/n3moBVoN5O',
139+
},
140+
{
141+
title: '掘金',
142+
href: 'https://tophub.today/n/QaqeEaVe9R',
143+
},
144+
{
145+
title: '哔哩哔哩',
146+
href: 'https://tophub.today/n/74KvxwokxM',
147+
},
148+
{
149+
title: '抖音',
150+
href: 'https://tophub.today/n/DpQvNABoNE',
151+
},
152+
{
153+
title: '吾爱破解',
154+
href: 'https://tophub.today/n/NKGoRAzel6',
155+
},
156+
{
157+
title: '百度贴吧',
158+
href: 'https://tophub.today/n/Om4ejxvxEN',
159+
},
160+
{
161+
title: '天涯',
162+
href: 'https://tophub.today/n/Jb0vmmlvB1',
163+
},
164+
{
165+
title: 'V2EX',
166+
href: 'https://tophub.today/n/wWmoORe4EO',
167+
},
168+
{
169+
title: '虎扑社区',
170+
href: 'https://tophub.today/n/G47o8weMmN',
171+
},
172+
{
173+
title: '汽车之家',
174+
href: 'https://tophub.today/n/YqoXQGXvOD',
175+
},
176+
]
177+
18178
const {setStorage, getStorage} = useStorage('newsTop-xiaoming')
19179

20180
/**文字颜色*/
@@ -43,6 +203,28 @@ const colors = {
43203
black: '#000000',
44204
}
45205

206+
/**
207+
* 文章组件
208+
* @param param.article 文章
209+
* @param param.sort 文章序号
210+
*/
211+
const Article: FC<{article: ArticleInfo; sort: number}> = ({article, sort}) => {
212+
return (
213+
<>
214+
<wspacer length={5}></wspacer>
215+
<wstack verticalAlign="center" href={article.href}>
216+
<wtext maxLine={1} font={Font.lightSystemFont(14)}>
217+
{sort}{article.title}
218+
</wtext>
219+
<wspacer></wspacer>
220+
<wtext maxLine={1} font={Font.lightSystemFont(12)} opacity={0.6}>
221+
{article.hot}
222+
</wtext>
223+
</wstack>
224+
</>
225+
)
226+
}
227+
46228
class NewsTop {
47229
async init() {
48230
if (isLaunchInsideApp()) {
@@ -58,6 +240,11 @@ class NewsTop {
58240
if (isLaunchInsideApp()) {
59241
await showNotification({title: '稍等片刻', body: '小部件渲染中...', sound: 'alert'})
60242
}
243+
// 获取榜单url
244+
const topUrl = this.getTopUrl()
245+
// 获取榜单数据
246+
const {title, logo, articleList} = await this.getNewsTop(topUrl)
247+
61248
// 多久(毫秒)更新一次小部件(默认1小时)
62249
const updateInterval = 1 * 60 * 60 * 1000
63250
// 渲染尺寸
@@ -68,26 +255,53 @@ class NewsTop {
68255
updateDate={new Date(Date.now() + updateInterval)}
69256
background={boxBg.match('透明背景') ? transparentBg : boxBg}
70257
>
71-
{size === 'small' && this.renderSmall()}
72-
{size === 'medium' && this.renderMedium()}
73-
{size === 'large' && this.renderLarge()}
258+
<wstack flexDirection="column" padding={[16, 16, 16, 16]}>
259+
{/* 标题和logo */}
260+
<wstack verticalAlign="center">
261+
<wimage src={logo} width={14} height={14} borderRadius={4}></wimage>
262+
<wspacer length={10}></wspacer>
263+
<wtext opacity={0.7} font={Font.boldSystemFont(12)}>
264+
{title}
265+
</wtext>
266+
</wstack>
267+
{/* 内容 */}
268+
{size === 'small' && this.renderSmall(articleList)}
269+
{size === 'medium' && this.renderMedium(articleList)}
270+
{size === 'large' && this.renderLarge(articleList)}
271+
</wstack>
74272
</wbox>
75273
)
76274
}
77275

78276
// 渲染小尺寸
79-
renderSmall() {
277+
renderSmall(articleList: ArticleInfo[]) {
80278
return <wstack flexDirection="column"></wstack>
81279
}
82280

83281
// 渲染中尺寸
84-
renderMedium() {
85-
return <wstack></wstack>
282+
renderMedium(articleList: ArticleInfo[]) {
283+
const _articleList = articleList.slice(0, 5)
284+
return (
285+
<wstack flexDirection="column">
286+
{_articleList.map((article, index) => (
287+
<Article article={article} sort={index + 1}></Article>
288+
))}
289+
<wspacer></wspacer>
290+
</wstack>
291+
)
86292
}
87293

88294
// 渲染大尺寸
89-
renderLarge() {
90-
return <wstack flexDirection="column"></wstack>
295+
renderLarge(articleList: ArticleInfo[]) {
296+
const _articleList = articleList.slice(0, 10)
297+
return (
298+
<wstack flexDirection="column">
299+
{_articleList.map((article, index) => (
300+
<Article article={article} sort={index + 1}></Article>
301+
))}
302+
<wspacer></wspacer>
303+
</wstack>
304+
)
91305
}
92306

93307
// 显示菜单
@@ -130,6 +344,58 @@ class NewsTop {
130344
break
131345
}
132346
}
347+
348+
// 获取热榜数据
349+
async getNewsTop(url: string): Promise<PageInfo> {
350+
const webview = new WebView()
351+
await webview.loadURL(url)
352+
await webview.waitForLoad()
353+
const {title = '今日热榜', logo = 'flame.fill', articleList = [], err} = (await webview.evaluateJavaScript(
354+
`
355+
let title = ''
356+
let logo = ''
357+
let articleList = []
358+
let err = ''
359+
try {
360+
title = document.title.split(' ')[0]
361+
logo = document.querySelector('.custom-info-content > img').src
362+
articleList = Array.from(document.querySelector('.divider > .weui-panel > .weui-panel__bd').querySelectorAll('a')).map(a => {
363+
return {
364+
title: a.querySelector('h4').innerText.replace(/\\d+?[、]\\s*/, ''),
365+
href: a.href,
366+
hot: a.querySelector('h4+p').innerText
367+
}
368+
})
369+
} catch(err) {
370+
err = err
371+
}
372+
Object.assign({}, {title, logo, articleList, err})
373+
`,
374+
)) as PageInfo
375+
err && console.warn(`热榜获取出错: ${err}`)
376+
return {title, logo, articleList, err}
377+
}
378+
379+
// 获取要显示的榜单 url
380+
getTopUrl(): string {
381+
// 默认为知乎榜单
382+
const defaultUrl = 'https://tophub.today/n/mproPpoq6O'
383+
// 从小部件编辑处获取关键词或链接
384+
const keyword = (args.widgetParameter as string) || defaultUrl
385+
if (this.isUrl(keyword)) return keyword
386+
const topInfo = topList.find(item => item.title.toLowerCase() === keyword.toLowerCase())
387+
if (topInfo) return topInfo.href
388+
return defaultUrl
389+
}
390+
391+
/**
392+
* 判断一个值是否为网络连接
393+
* @param value 值
394+
*/
395+
isUrl(value: string): boolean {
396+
const reg = /^(http|https)\:\/\/[\w\W]+/
397+
return reg.test(value)
398+
}
133399
}
134400

135401
EndAwait(() => new NewsTop().init())

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /