+
equalizer
+
@@ -62,6 +63,19 @@
(+{{ selectedHeaders.length - 1 }} others)
+
+
+
+
+
+ +{{ selectedTags.length }}
+
+
+
+
+
+
@@ -70,7 +84,7 @@
enterkeyhint="search">
-
@@ -441,19 +455,22 @@ import Vue from "vue";
import Extension from "@/service/extension";
import {
EAction,
- Site,
- LogItem,
EModule,
+ EOpenType,
+ ETagType,
EUserDataRequestStatus,
+ EViewKey,
+ LevelRequirement,
+ LogItem,
Options,
+ Site,
UserInfo,
- EViewKey,
- LevelRequirement, UserQuickLink,
+ UserQuickLink,
} from "@/interface/common";
import dayjs from "dayjs";
import AutoSignWarning from "./AutoSignWarning.vue";
-import { PPF } from "@/service/public";
+import {PPF} from "@/service/public";
interface UserInfoEx extends UserInfo {
joinDateTime?: string;
@@ -469,6 +486,7 @@ export default Vue.extend({
loading: false,
items: [] as any[],
selectedHeaders: [] as any[],
+ selectedTags: [] as any[],
headers: [
{
text: this.$t("home.headers.site"),
@@ -564,6 +582,14 @@ export default Vue.extend({
created() {
this.init();
},
+ // DEBUG
+ // watch: {
+ // selectedTags: {
+ // handler(v) {
+ // console.log("selectedTags changed", v);
+ // },
+ // },
+ // },
computed: {
//Done to get the ordered headers
showHeaders(): any[] {
@@ -576,11 +602,98 @@ export default Vue.extend({
*/
allOpenTypes() {
return [
- {type: 'openAllSites', icon: 'moving', color: 'secondary'},
- {type: 'openAllUnReadMsg', icon: 'forward_to_inbox', color: 'primary'},
- {type: 'openAllStatusErr', icon: 'sync_problem', color: 'error'},
+ {type: EOpenType.openAllSites, icon: 'moving', color: 'secondary'},
+ {type: EOpenType.openAllUnReadMsg, icon: 'forward_to_inbox', color: 'primary'},
+ {type: EOpenType.openAllStatusErr, icon: 'sync_problem', color: 'error'},
]
},
+ isSortByPriority() {
+ // @ts-ignore
+ return this.sites.filter(_ => _.priority).length > 0
+ },
+ /**
+ * 按优先级从小到大排序
+ */
+ allSitesSorted() {
+ // @ts-ignore
+ // return this.isSortByPriority ? this.sortByPriority(this.sites) : this.sites
+ return this.sortByPriority(this.sites)
+ },
+ allStatusErrSites() {
+ // @ts-ignore
+ return this.allSitesSorted
+ // 第一个一般是未登录
+ .filter((site: Site) => site.user?.lastErrorMsg || (site.user?.lastUpdateStatus !== EUserDataRequestStatus.success))
+ },
+ allUnReadMsgSites() {
+ // @ts-ignore
+ return this.allSitesSorted.filter((site: Site) => (site.user?.messageCount || 0) > 0)
+ },
+ allTaggedSites() {
+ // @ts-ignore
+ return this.allSitesSorted.filter(s => Array.isArray(s.tags) && s.tags.length > 0)
+ },
+ allUnTaggedSites() {
+ // @ts-ignore
+ return this.allSitesSorted.filter(s => !s.tags || s.tags.length === 0)
+ },
+ selectedTagValues() {
+ // @ts-ignore
+ return this.selectedTags.map((_: any) => _.value)
+ },
+ allSortedTags() {
+ // let res = [ETagType.all]
+ // if (this.allUnTaggedSites.length > 0) res.push(ETagType.unTagged)
+ // if (this.allUnReadMsgSites.length > 0) res.push(ETagType.unReadMsg)
+ // if (this.allStatusErrSites.length > 0) res.push(ETagType.statusError)
+ // 避免添加站点后, 刷新失败后, 标签反复横跳
+ let res = [ETagType.all, ETagType.unTagged, ETagType.unReadMsg, ETagType.statusError]
+ for (let site of this.allTaggedSites) {
+ res = res.concat(site.tags)
+ }
+ res = [...new Set(res)]
+ return res.map(tag => {
+ let text, value = tag
+ switch (tag) {
+ case ETagType.all:
+ case ETagType.unTagged:
+ case ETagType.unReadMsg:
+ case ETagType.statusError:
+ text = this.$t(`home.tags.${tag}`).toString()
+ break
+ default:
+ text = tag
+ }
+ return {text, value}
+ })
+ },
+ filteredSitesByTags() {
+ // @ts-ignore
+ if (this.selectedTagValues.length === 0) return this.sites
+ // @ts-ignore
+ if (this.selectedTagValues.includes(ETagType.all)) return this.sites
+ let tags = this.clone(this.selectedTagValues)
+ let res: any[] = []
+ if (tags.includes(ETagType.unTagged)) {
+ res = res.concat(this.allUnTaggedSites)
+ }
+ if (tags.includes(ETagType.unReadMsg)) {
+ res = res.concat(this.allUnReadMsgSites)
+ }
+ if (tags.includes(ETagType.statusError)) {
+ res = res.concat(this.allStatusErrSites)
+ }
+ for (let site of this.allTaggedSites) {
+ if (site.tags?.some((s: any) => tags.includes(s))) {
+ res.push(site)
+ }
+ }
+ // console.log(`filteredSitesByTags: ${tags}`, res)
+ res = this.uniqBy(res, 'name')
+ console.log(`filteredSitesByTags uniq: ${tags}`, res)
+ res = this.sortByPriority(res)
+ return res
+ },
},
/**
@@ -627,6 +740,8 @@ export default Vue.extend({
this.sites.push(_site);
}
});
+ // 按优先级排序
+ this.sites = this.sortByPriority(this.sites)
},
init() {
@@ -665,7 +780,7 @@ export default Vue.extend({
msg: this.$t("home.startGetting").toString(),
});
- this.sites.forEach((site: Site, index: number) => {
+ this.filteredSitesByTags.forEach((site: Site, index: number) => {
this.writeLog({
event: `Home.getUserInfo.Processing`,
msg: this.$t("home.gettingForSite", {
@@ -1124,6 +1239,32 @@ export default Vue.extend({
clone(source: any) {
return JSON.parse(JSON.stringify(source));
},
+ uniqBy(arr: any[], predicate: any) {
+ const cb = typeof predicate === 'function' ? predicate : (o: any) => o[predicate];
+
+ return [...arr.reduce((map, item) => {
+ const key = (item === null || item === undefined) ?
+ item : cb(item);
+
+ map.has(key) || map.set(key, item);
+
+ return map;
+ }, new Map()).values()];
+ },
+ filterOnlineSites(arr: any[]) {
+ return arr.filter(s => s.offline !== true)
+ },
+ // 按优先级排序
+ sortByPriority(arr: any[]) {
+ if (this.isSortByPriority) {
+ return arr.sort((a, b) => {
+ // 兼容部分未设置优先级的站点
+ return (a.priority || Number.MAX_SAFE_INTEGER) - (b.priority || Number.MAX_SAFE_INTEGER)
+ })
+ } else {
+ return arr
+ }
+ },
updateViewOptions() {
this.$store.dispatch("updateViewOptions", {
@@ -1139,6 +1280,7 @@ export default Vue.extend({
showLastUpdateTimeAsRelativeTime: this.showLastUpdateTimeAsRelativeTime,
showWeek: this.showWeek,
selectedHeaders: this.selectedHeaders,
+ selectedTags: this.selectedTags,
},
});
},
@@ -1165,23 +1307,19 @@ export default Vue.extend({
}
},
getAllUrlsByType: function (type: String) {
- // 这里应该过滤有效站点的, 但是个人数据这个页面的数据好像已经过滤过了?...
switch (type) {
- case "openAllSites":
- // case this.allOpenTypes[0].type:
- return this.sites.filter(s => s.offline !== true).map((site: Site) => site.activeURL)
- case "openAllStatusErr":
- // case this.allOpenTypes[1].type:
- return this.sites.filter(s => s.offline !== true)
- .filter((site: Site) => site.user?.lastUpdateStatus !== EUserDataRequestStatus.success)
+ case EOpenType.openAllSites:
+ return this.filterOnlineSites(this.filteredSitesByTags)
+ .map((site: Site) => site.activeURL)
+ case EOpenType.openAllStatusErr:
+ // 只打开有效站点
+ return this.filterOnlineSites(this.allStatusErrSites)
.map((site: Site) => this.defaultQuickLinks(site)[0] || site.activeURL)
- .map(s => s.href || s)
- case "openAllUnReadMsg":
- // case this.allOpenTypes[2].type:
- return this.sites.filter(s => s.offline !== true)
- .filter((site: Site) => (site.user?.messageCount || 0) > 0)
+ .map((s: any) => s.href || s)
+ case EOpenType.openAllUnReadMsg:
+ return this.filterOnlineSites(this.allUnReadMsgSites)
.map((site: Site) => this.defaultQuickLinks(site)[1] || site.activeURL)
- .map(s => s.href || s)
+ .map((s: any) => s.href || s)
default:
throw new Error(`getAllUrlsByType: 未知的类型:${type}`)
}
@@ -1324,7 +1462,12 @@ export default Vue.extend({
}
.select {
- max-width: 180px;
+ max-width: 160px;
+ }
+ .select-tags {
+ max-width: 70px;
+ max-height: 70%;
+ margin-left: 5px;
}
.lastUpdateTime {
@@ -1332,8 +1475,8 @@ export default Vue.extend({
}
.batchBtn {
- min-width: 0;
- margin: 1px 1px;
+ min-width: 60px;
+ margin: 3px 3px;
}
}
diff --git a/src/options/views/settings/Sites/Editor.vue b/src/options/views/settings/Sites/Editor.vue
index fb9ead9c3..ee365e3bf 100644
--- a/src/options/views/settings/Sites/Editor.vue
+++ b/src/options/views/settings/Sites/Editor.vue
@@ -12,6 +12,17 @@
:rules="rules.require"
>
+
+
+
+
+
+
+
+
+
+
+