Skip to content

Commit

Permalink
1.优化ui显示
Browse files Browse the repository at this point in the history
2.统一组件为通用结构化组件
3.B站热点新增图片展示
  • Loading branch information
Nier committed Mar 12, 2023
1 parent 1b01f71 commit 0a8466d
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 176 deletions.
44 changes: 10 additions & 34 deletions public/preload.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
const https = require("https");
const http = require("http");
const crypto = require("crypto");
const fs = require("fs");
const urlParser = require('url');

/**
* 全局函数(preload种可以调用electron/node函数)
Expand All @@ -24,21 +28,6 @@ window.fetchJsonHttps = (host, path, config = {}) => new Promise((resolve) => {
}
)


const fetchHost = (url) => {
// 默认组装Referer header头
let domainType = ".cn"
if (url.indexOf(".com") > -1) {
domainType = ".com"
}

const [host, path] = url.split(domainType)
return {
host: `${host}${domainType}`
, path
}
}

function fetchSuffix(url) {
const urlSegments = url.split(".")
let fileSuffix = urlSegments[urlSegments.length - 1]
Expand All @@ -50,15 +39,11 @@ function fetchSuffix(url) {
}

const fetchFile = (url, filePath, config) => {
const {host, path} = fetchHost(url)
const {host, path} = urlParser.parse(url)
const request = url.startsWith('https') ? https : http

return new Promise(resolve => request.get({
host:

`${host.replace('https://', '').replace('http://', '')}`

,
host: `${host.replace('https://', '').replace('http://', '')}`,
path: path,
method: 'get',
headers: config['headers'] || {}
Expand Down Expand Up @@ -86,23 +71,16 @@ const getFileSize = (filePath) => {

window.composeFilePath = (url) => {
// 文件名采用随机方式,避免文件冲突
let fileName =

`${crypto.createHash('md5').update(url).digest('hex')}`

let fileName = `${crypto.createHash('md5').update(url).digest('hex')}`

let fileSuffix = fetchSuffix(url)
// 组装文件路径,需要将文件后缀拼接上
return

`${utools.getPath("temp")}/${fileName}.${fileSuffix}`


return `${utools.getPath("temp")}/${fileName}.${fileSuffix}`
}

window.downloadImage = async (url, config = {}) => {
// 默认组装Referer header头
const {host} = fetchHost(url)
const {host} = urlParser.parse(url)
config = Object.assign({'headers': {'Referer': host}, ...config})

// 组装文件路径,需要将文件后缀拼接上
Expand All @@ -124,8 +102,6 @@ window.downloadImage = async (url, config = {}) => {

return {
imgSrc: url,
fileSrc:

`file://${filePath}`,
fileSrc: `file://${filePath}`,
}
}
27 changes: 14 additions & 13 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,12 @@ export default {
updateConfig(config.value)
}
const triggerUpdate = () => emitter.emit(REFRESH_EVENT)
return {
loading,
config,
sources,
switchSource,
triggerUpdate,
triggerUpdate: () => emitter.emit(REFRESH_EVENT),
RefreshSharp, InfoOutlined,
theme: computed(() => osThemeRef.value === "dark" ? darkTheme : null),
}
Expand All @@ -48,14 +45,17 @@ export default {
<n-config-provider :theme="theme">
<n-message-provider placement="top" container-style="margin-top:50px" :duration="1500" closable>
<n-layout position="absolute">
<n-layout-header style="height: 50px;" bordered>
<n-space justify="space-between" align="center" style="height: 50px;padding:0 10px">
<n-space>
<n-tag :key="source['name']" v-for="source in sources" checkable @click='()=>switchSource(source)'
:checked="source['name']===config.source?.name">{{ source['title'] }}
</n-tag>
<n-layout-header bordered>
<n-space justify="space-between" align="center" style="padding:10px 10px">
<n-space align="center">
<template :key="source['name']" v-for="(source,index) in sources">
<n-tag round checkable @click='()=>switchSource(source)'
:checked="source['name']===config.source?.name">{{ source['title'] }}
</n-tag>
<n-divider v-if="index<sources.length-1" vertical/>
</template>
</n-space>
<n-space>
<n-space style="width: 55px" align="center">
<n-button title="刷新" :disabled="loading" :focusable="false" text @click="triggerUpdate">
<n-icon size="20px" :component="RefreshSharp"/>
</n-button>
Expand All @@ -67,14 +67,15 @@ export default {
</n-space>
</n-space>
</n-layout-header>
<n-layout has-sider position="absolute" style="top: 60px">
<n-layout has-sider position="absolute" style="top: 50px">
<n-layout content-style="padding: 5px 10px;" :native-scrollbar="false">
<About ref="about"/>
<n-spin :show="loading" description="努力加载中~" style="min-height: 300px">
<BiliBiliHot v-if="config.source?.name==='bilibiliHot'" v-model:loading="loading"/>
<ReadHub v-if="config.source?.name==='readhub'" v-model:loading="loading"/>
<OpenSourceNews v-if="config.source?.name==='opensourceNews'" v-model:loading="loading"/>
<OpenSourceSoftwareUpdateNews v-if="config.source?.name==='opensourceSoftwareUpdateNews'" v-model:loading="loading"/>
<OpenSourceSoftwareUpdateNews v-if="config.source?.name==='opensourceSoftwareUpdateNews'"
v-model:loading="loading"/>
<WeiboHot v-if="config.source?.name==='weibohot'" v-model:loading="loading"/>
</n-spin>
</n-layout>
Expand Down
25 changes: 20 additions & 5 deletions src/components/BiliBiliHot.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
<template>
<CommonNews :news-api="fetchNews" :news-extractor="newsExtractor"/>
<CommonNews :news-api="fetchNews" :news-extractor="newsExtractor">
<template #content_extra="news">
<n-space justify="start">
<n-tag size="small" type="info" round>硬币: {{ news['item']['origin']['stat']['coin'] }}</n-tag>
<n-tag size="small" type="info" round>观看: {{ news['item']['origin']['stat']['view'] }}</n-tag>
<n-tag size="small" type="info" round>分享: {{ news['item']['origin']['stat']['share'] }}</n-tag>
<n-tag size="small" type="info" round>喜欢: {{ news['item']['origin']['stat']['like'] }}</n-tag>
</n-space>
</template>
</CommonNews>
</template>

<script>
Expand All @@ -18,10 +27,16 @@ export default {
)
const newsExtractor = (body) => {
const lists = body.data?.list || []
return lists.map(news => ({
title: news['title'],
link: news['short_link']
}))
return lists.map(news => {
return {
title: news['title'],
link: news['short_link'],
imgSrc: news['pic'],
origin: news,
}
})
}
return {
fetchNews,
Expand Down
43 changes: 25 additions & 18 deletions src/components/CommonNews.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,24 @@
<n-list-item :key="item.title" v-for="(item,index) in news" align="left"
@click.stop="()=>openOriginLink(item['link'])">
<template #prefix>
<n-space justify="center" align="center">
<n-tag type="default" round size="small">
<slot name="prefix" :item="item" :index="index">
<n-text :type="index<=2?'error':'warning'" strong style="font-size: larger">
{{ index + 1 }}
</n-tag>
</n-space>
</n-text>
</slot>
</template>
<n-space vertical>
<n-space align="center">
<img v-if="item['imgSrc']" width="100" :src="imgMap[item['imgSrc']]">
<n-space justify="start" vertical>
<div>
<n-text class="cursor-pointer">{{ item['title'] }}</n-text>
</div>
<n-text strong style="font-size: 17px" class="cursor-pointer">{{ item['title'] }}</n-text>
<slot name="content_extra" :item="item"/>
</n-space>
</n-space>
<template #suffix>

<slot name="suffix" :item="item"/>
</template>
</n-list-item>
</n-list>
<DetailDrawer ref="detailDrawer"/>
</template>

<script>
Expand All @@ -46,6 +45,9 @@ export default {
const news = ref([])
const {newsApi, newsExtractor} = props
const {error} = useMessage()
const imgMap = ref({})
const reload = () => {
if (!newsApi) {
return error('未配置新闻源')
Expand All @@ -54,14 +56,21 @@ export default {
ctx.emit('update:loading', true)
news.value = []
newsApi().then(res => news.value = newsExtractor(res))
imgMap.value = {}
newsApi().then(res => {
news.value = newsExtractor(res)
for (let i = 0; i < news.value.length; i++) {
const imgSrc = news.value[i]['imgSrc']
if (!imgSrc) {
continue
}
downloadImage(imgSrc).then(result => imgMap.value[imgSrc] = result['fileSrc'])
}
})
.catch(e => alert(e))
.finally(() => ctx.emit('update:loading', false))
}
const detailDrawer = ref()
const showContent = (item) => {
detailDrawer.value.show({title: item['title'], content: item['summary']})
}
const openOriginLink = (link) => utools.shellOpenExternal(link)
Expand All @@ -72,12 +81,10 @@ export default {
return {
news,
toDateTimeStr,
detailDrawer,
showContent,
DetailDrawer,
openOriginLink,
OpenInBrowserRound,
imgMap,
}
}
}
Expand Down
11 changes: 10 additions & 1 deletion src/components/OpenSourceSoftwareUpdateNews.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,17 @@ export default {
extractNews: (res) => {
const $ = cheerio.load(res.data)
const newsLinks = $('.news-item-hover')
return newsLinks.map((_, news) => ({title: $(news).find('.title').text(), link: news.attribs['data-url']}))
return newsLinks.map((_, news) => {
const imgAttribs = $(news).find('img')[0]?.attribs || {}
return {
title: $(news).find('.title').text(),
imgSrc: imgAttribs['data-src'],
link: news.attribs['data-url']
}
}
)
}
}
}
Expand Down
76 changes: 29 additions & 47 deletions src/components/ReadHub.vue
Original file line number Diff line number Diff line change
@@ -1,79 +1,61 @@
<template>
<n-list hoverable clickable>
<n-list-item :key="item.uid" v-for="(item,index) in news" align="left" @click.stop="()=>showContent(item)">
<template #prefix>
<n-space justify="center" align="center">
<n-tag type="primary" round size="small">
{{ index + 1 }}
</n-tag>
</n-space>
</template>
<n-space vertical>
<n-space justify="start" vertical>
<n-tag type="info" size="small" class="cursor-pointer">{{ toDateTimeStr(item['createdAt']) }}</n-tag>
<n-text class="cursor-pointer">{{ item['title'] }}</n-text>
</n-space>
</n-space>
<template #suffix>
<n-space>
<n-button title="浏览器打开" :focusable="false" size="small" ghost
@click.stop="()=>openOriginLink(item['uid'])">
<n-icon :component="OpenInBrowserRound"/>
</n-button>
</n-space>
</template>
</n-list-item>
</n-list>
<CommonNews :news-api="fetchNews" :news-extractor="newsExtractor">
<template #content_extra="{item}">
<n-text>
{{ toDateTimeStr(item['createdAt']) }}
</n-text>
</template>
<template #suffix="{item}">
<n-button :focusable="false" round @click.stop="()=>showContent(item)" ghost size="large">
概要
</n-button>
</template>
</CommonNews>
<DetailDrawer ref="detailDrawer"/>
</template>

<script>
import {onMounted, ref} from "vue";
import {ref} from "vue";
import axios from "axios";
import {toDateTimeStr} from "../js/useDate.js";
import DetailDrawer from "/src/components/DetailDrawer.vue";
import CommonNews from "/src/components/CommonNews.vue";
import {OpenInBrowserRound} from "@vicons/material";
import {emitter, REFRESH_EVENT} from "../js/useEvent.js";
export default {
name: "ReadHub",
components: {DetailDrawer, OpenInBrowserRound},
components: {DetailDrawer, CommonNews, OpenInBrowserRound},
props: {
loading: {type: Boolean, default: false},
},
emits: ['update:loading'],
setup(props, ctx) {
// https://api.readhub.cn/topic/list?size=50
const news = ref([])
const reload = () => {
ctx.emit('update:loading', true)
news.value = []
axios.get('https://api.readhub.cn/topic/list?size=50')
.then(res => {
const {items} = res.data.data
news.value = items || []
})
.finally(() => ctx.emit('update:loading', false))
const fetchNews = () => axios.get('https://api.readhub.cn/topic/list?size=50')
const newsExtractor = (body) => {
const {items} = body.data.data
return (items || []).map(item => ({
uid: item['uid'],
title: item['title'],
summary: item['summary'],
createdAt: item['createdAt'],
link: `https://readhub.cn/topic/${item['uid']}`
}))
}
const detailDrawer = ref()
const showContent = (item) => {
detailDrawer.value.show({title: item['title'], content: item['summary']})
}
const openOriginLink = (uid) => utools.shellOpenExternal(`https://readhub.cn/topic/${uid}`)
onMounted(() => {
reload()
emitter.on(REFRESH_EVENT, reload)
})
return {
news,
fetchNews,
newsExtractor,
toDateTimeStr,
detailDrawer,
showContent,
DetailDrawer,
openOriginLink,
OpenInBrowserRound,
}
}
Expand Down
Loading

0 comments on commit 0a8466d

Please sign in to comment.