将FeedList升级到Vue3

master
落雨楓 2 years ago
parent b1bb307212
commit 1b23c70ecd

@ -82,12 +82,14 @@
]
},
"ext.isekai.feedList": {
"scripts": [
"feedList/ext.isekai.feedList.js"
],
"styles": [
"feedList/ext.isekai.feedList.less"
],
"packageFiles": [
{ "name": "isekaiFeedList", "file": "feedList/ext.isekai.feedList.js", "main": true },
{ "name": "FeedList.vue", "file": "feedList/FeedList.vue" }
],
"es6": true,
"dependencies": [
"oojs",
"oojs-ui-core",

@ -0,0 +1,161 @@
<script>
module.exports = {
compatConfig: {
MODE: 3
},
compilerOptions: {
whitespace: 'condense'
},
setup() {
const mounted = Vue.ref(false);
const loading = Vue.ref(true);
const feedList = Vue.ref([]);
const api = new mw.Api();
let recentData = {
recentNew: null,
recentEdit: null,
};
const onLoaded = () => {
if (Array.isArray(recentData.recentNew) && Array.isArray(recentData.recentEdit)) {
//
let recentList = [
...recentData.recentNew,
...recentData.recentEdit
];
recentList.sort((a, b) => b.orderWeight - a.orderWeight);
// pageid
let pageIdList = [];
recentList = recentList.filter((item) => {
if (pageIdList.includes(item.pageid)) {
return false;
} else {
pageIdList.push(item.pageid);
return true;
}
});
//
api.get({
"action": "query",
"prop": "extracts|info",
"pageids": pageIdList.join('|'),
"redirects": 1,
"converttitles": 1,
"exchars": 100,
"exintro": 1,
"explaintext": 1,
"inprop": "url"
}).done((data) => {
if (data.query && data.query.pages) {
const pageInfoList = data.query.pages;
recentList = recentList.map((info) => {
if (info.pageid in pageInfoList) {
const pageInfo = pageInfoList[info.pageid];
return {
pageid: info.pageid,
title: pageInfo.title,
description: pageInfo.extract,
url: pageInfo.fullurl
}
} else {
return {
pageid: info.pageid,
title: info.title,
description: '',
url: mw.util.getUrl(info.title)
}
}
});
// data
feedList.value = recentList;
loading.value = false;
console.log('feedList', feedList);
}
});
}
};
Vue.onMounted(() => {
mounted.value = true;
api.get({
action: 'query',
list: 'recentchanges',
rctype: 'edit',
rcnamespace: 0,
rclimit: 20,
}).done((data) => {
recentData.recentEdit = [];
if (data.query && Array.isArray(data.query.recentchanges)) { //
data.query.recentchanges.forEach((one) => {
if (one.timestamp) {
one.timestamp = new Date(one.timestamp).getTime();
one.orderWeight = one.timestamp;
} else {
one.orderWeight = 0;
}
recentData.recentEdit.push(one);
});
onLoaded();
}
});
api.get({
action: 'query',
list: 'recentchanges',
rctype: 'new',
rcnamespace: 0,
rclimit: 20,
}).done((data) => {
recentData.recentNew = [];
if (data.query && Array.isArray(data.query.recentchanges)) { //
data.query.recentchanges.forEach((one) => {
if (one.timestamp) {
one.timestamp = new Date(one.timestamp).getTime();
one.orderWeight = one.timestamp + (86400 * 1000); // 7
} else {
one.orderWeight = 0;
}
recentData.recentNew.push(one);
});
onLoaded();
}
});
});
return {
mounted,
loading,
feedList
}
}
}
</script>
<template>
<div class="isekai-feed-list" :class="{ mounted: mounted }">
<div v-if="loading" class="loading">
<div class="spinner">
<div class="oo-ui-widget oo-ui-widget-enabled oo-ui-progressBarWidget-indeterminate oo-ui-progressBarWidget"
aria-disabled="false" role="progressbar" aria-valuemin="0" aria-valuemax="100">
<div class="oo-ui-progressBarWidget-bar"></div>
</div>
</div>
</div>
<ul v-else class="isekai-list">
<a class="isekai-list-item" v-for="(feedItem, index) in feedList" :key="index" :href="feedItem.url"
target="_blank">
<div class="isekai-list-item-content">
<div class="isekai-list-item-title">{{ feedItem.title }}</div>
<div class="isekai-list-item-text">{{ feedItem.description }}</div>
</div>
<div class="isekai-list-item-icon">
<span
class="oo-ui-widget oo-ui-widget-enabled oo-ui-iconElement oo-ui-iconElement-icon oo-ui-image-progressive oo-ui-icon-next oo-ui-labelElement-invisible oo-ui-iconWidget"
aria-disabled="false"></span>
</div>
</a>
</ul>
</div>
</template>

@ -1,122 +1,6 @@
const Vue = require("vue");
if (document.querySelector('#isekai-feed-list')) {
new Vue({
el: '#isekai-feed-list',
data: {
mounted: false,
loading: true,
feedList: []
},
mounted() {
this.$data.mounted = true;
const api = new mw.Api();
let recentData = {
recentNew: null,
recentEdit: null,
};
const onLoaded = () => {
if (Array.isArray(recentData.recentNew) && Array.isArray(recentData.recentEdit)) {
// 混合两个列表
let recentList = [
...recentData.recentNew,
...recentData.recentEdit
];
recentList.sort((a, b) => b.orderWeight - a.orderWeight);
// 去除重复获取pageid列表
let pageIdList = [];
recentList = recentList.filter((item) => {
if (pageIdList.includes(item.pageid)) {
return false;
} else {
pageIdList.push(item.pageid);
return true;
}
});
// 获取页面详细信息
api.get({
"action": "query",
"prop": "extracts|info",
"pageids": pageIdList.join('|'),
"redirects": 1,
"converttitles": 1,
"exchars": 100,
"exintro": 1,
"explaintext": 1,
"inprop": "url"
}).done((data) => {
if (data.query && data.query.pages) {
const pageInfoList = data.query.pages;
recentList = recentList.map((info) => {
if (info.pageid in pageInfoList) {
const pageInfo = pageInfoList[info.pageid];
return {
pageid: info.pageid,
title: pageInfo.title,
description: pageInfo.extract,
url: pageInfo.fullurl
}
} else {
return {
pageid: info.pageid,
title: info.title,
description: '',
url: mw.util.getUrl(info.title)
}
}
});
// 设置data
this.$data.feedList = recentList;
this.$data.loading = false;
}
});
}
};
api.get({
action: 'query',
list: 'recentchanges',
rctype: 'edit',
rcnamespace: 0,
rclimit: 20,
}).done((data) => {
recentData.recentEdit = [];
if (data.query && Array.isArray(data.query.recentchanges)) { //有成功取到数据
data.query.recentchanges.forEach((one) => {
if (one.timestamp) {
one.timestamp = new Date(one.timestamp).getTime();
one.orderWeight = one.timestamp;
} else {
one.orderWeight = 0;
}
recentData.recentEdit.push(one);
});
onLoaded();
}
});
api.get({
action: 'query',
list: 'recentchanges',
rctype: 'new',
rcnamespace: 0,
rclimit: 20,
}).done((data) => {
recentData.recentNew = [];
if (data.query && Array.isArray(data.query.recentchanges)) { // 成功取到数据
data.query.recentchanges.forEach((one) => {
if (one.timestamp) {
one.timestamp = new Date(one.timestamp).getTime();
one.orderWeight = one.timestamp + (86400 * 1000); // 新页面保护权重比页面更新高7天
} else {
one.orderWeight = 0;
}
recentData.recentNew.push(one);
});
onLoaded();
}
});
}
});
const App = require("./FeedList.vue");
Vue.createMwApp(App).mount("#isekai-feed-list");
}

@ -5,7 +5,7 @@
height: 2.25rem;
}
#isekai-feed-list {
.isekai-feed-list {
margin: 0;
height: @feed-list-height;
overflow-y: auto;

@ -3,25 +3,6 @@
<span class="card-header-text"><?=wfMessage('isekai-feed-list-title')->parse()?></span>
</div>
<div class="card-body-fluid">
<div id="isekai-feed-list" :class="{ mounted: 'mounted' }">
<div v-if="loading" class="loading">
<div class="spinner">
<div class="oo-ui-widget oo-ui-widget-enabled oo-ui-progressBarWidget-indeterminate oo-ui-progressBarWidget" aria-disabled="false" role="progressbar" aria-valuemin="0" aria-valuemax="100">
<div class="oo-ui-progressBarWidget-bar"></div>
</div>
</div>
</div>
<ul v-else class="isekai-list">
<a class="isekai-list-item" v-for="(feedItem, index) in feedList" :key="index" :href="feedItem.url" target="_blank">
<div class="isekai-list-item-content">
<div class="isekai-list-item-title">{{ feedItem.title }}</div>
<div class="isekai-list-item-text">{{ feedItem.description }}</div>
</div>
<div class="isekai-list-item-icon">
<span class="oo-ui-widget oo-ui-widget-enabled oo-ui-iconElement oo-ui-iconElement-icon oo-ui-image-progressive oo-ui-icon-next oo-ui-labelElement-invisible oo-ui-iconWidget" aria-disabled="false"></span>
</div>
</a>
</ul>
</div>
<div id="isekai-feed-list"></div>
</div>
</div>

@ -6,6 +6,10 @@ a {
&.tile-app {
color: #fff;
&:visited {
color: #fff;
}
&:visited:hover {
color: #fff;
}

Loading…
Cancel
Save