rss-reader/index.html
2023-09-02 23:45:35 +08:00

193 lines
6.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RSS Reader</title>
<meta name="description" content='RSS Reader一个将订阅信息聚合展示的开源web工具便于了解近期关注的信息同时页面数据数据也实现了自动刷新。'>
<meta name="keywords" content="<< .Keywords >>">
<meta name="anthor" content="srcrs">
<!-- <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> -->
<link rel="stylesheet" href="static/index.min.css">
<link rel="icon" href="static/favicon.svg" type="image/x-icon">
<style>
body {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 30px;
}
.card-header {
display: flex;
justify-content: center;
align-items: center;
font-size: 18px;
font-weight: bold;
}
.list-item {
display: flex;
align-items: center;
text-align: left;
width: 100%;
}
.list-item-title {
display: flex;
/* white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; */
flex-grow: 1;
text-align: left;
width: 100%;
margin-bottom: 10px;
}
a {
color: black;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.feed-col {
margin-bottom: 20px;
}
.time {
font-size: 12px;
color: #999;
}
</style>
</head>
<body>
<div id="app">
<el-container>
<el-header>
<h1>RSS Reader</h1>
</el-header>
<el-main v-loading.fullscreen.lock="fullscreenLoading" element-loading-text="拼命加载中">
<el-row :gutter="20">
<< range $index, $feed :=.RssDataList >>
<el-col v-if="showSEOFlag" :xs="24" :sm="12" :md="8" :lg="6" :key="index" class="feed-col">
<el-card class="box-card">
<div slot="header" class="card-header">
<span>
<< $feed.Title >>
</span>
</div>
<el-scrollbar style="height: 300px;">
<< range $i, $item :=$feed.Items >>
<el-list key="<< $i >>">
<el-list-item>
<div class="list-item-title">
<span>
<< inc $i >>.
</span>
<el-link href="<< $item.Link >>" target="_blank" title="<< $item.Title >>">
<< $item.Title >>
</el-link>
</div>
</el-list-item>
</el-list>
<< end >>
</el-scrollbar>
<div slot="footer" class="card-footer" style="height: 10px;">
<time class="time">
<< $feed.Custom.lastupdate >>
</time>
</div>
</el-card>
</el-col>
<< end>>
<el-col :xs="24" :sm="12" :md="8" :lg="6" v-for="(feed, index) in feeds" :key="index" class="feed-col">
<el-card class="box-card">
<div slot="header" class="card-header">
<span>{{ feed.title }}</span>
</div>
<el-scrollbar style="height: 300px;">
<el-list v-for="(item, i) in feed.items" :key="i">
<el-list-item>
<div class="list-item-title">
<span>{{ i+1 }}. </span>
<el-link :href="item.link" target="_blank" :title="item.title">{{ item.title }}</el-link>
</div>
</el-list-item>
</el-list>
</el-scrollbar>
<div slot="footer" class="card-footer" style="height: 10px;">
<time class="time">{{ feed.custom.lastupdate }}</time>
</div>
</el-card>
</el-col>
</el-row>
</el-main>
<el-footer>
<el-link href="https://github.com/srcrs/rss-reader" target="_blank">Rss-reader</el-link>
<span> | </span>
<el-link href="https://github.com/srcrs" target="_blank">By srcrs</el-link>
</el-footer>
</el-container>
</div>
<!-- <script src="https://unpkg.com/vue@next"></script> -->
<script src="static/vue.global.prod.js"></script>
<!-- <script src="https://cdn.bootcdn.net/ajax/libs/element-plus/2.3.3/index.full.js"></script> -->
<script src="static/index.full.min.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
feeds: [],
showSEOFlag: true,
fullscreenLoading: true,
};
},
async created() {
this.fullscreenLoading = false;
},
async mounted() {
const protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
const connect = () => {
const socket = new WebSocket(protocol + window.location.host + "/ws");
socket.onmessage = event => {
const feed = JSON.parse(event.data);
const existingFeed = this.feeds.find(f => f.link === feed.link);
if (existingFeed) {
Object.assign(existingFeed, feed);
} else {
this.feeds.push(feed);
}
this.showSEOFlag = false;
};
socket.onclose = event => {
console.log("WebSocket closed. Reconnecting...");
setTimeout(connect, 300000);
};
// Send heartbeat message every 120 seconds
const sendHeartbeat = () => {
if (socket.readyState === WebSocket.OPEN) {
socket.send("heartbeat");
}
};
setInterval(sendHeartbeat, 120000);
};
connect();
},
beforeDestroy() {
// 在组件销毁前手动关闭 WebSocket 连接
this.socket.close();
}
});
app.use(ElementPlus);
app.mount("#app");
</script>
</body>
</html>