From 3f002e0c526b1babd74260510f03cff778025c4e Mon Sep 17 00:00:00 2001
From: Peng-YM <1048217874pengym@gmail.com>
Date: Fri, 11 Dec 2020 11:59:02 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A4=9C=E9=97=B4=E6=A8=A1=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
backend/sub-store.js | 23 +++++
web/public/index.html | 5 +-
web/src/App.vue | 37 ++++---
web/src/router/index.js | 8 +-
web/src/store/index.js | 23 ++++-
web/src/views/Cloud.vue | 17 ++--
web/src/views/SubEditor.vue | 6 +-
web/src/views/Subscription.vue | 55 +++++++++--
web/src/views/User.vue | 174 +++++++++++++++++++++++++--------
9 files changed, 268 insertions(+), 80 deletions(-)
diff --git a/backend/sub-store.js b/backend/sub-store.js
index 1a6d81a..a730482 100644
--- a/backend/sub-store.js
+++ b/backend/sub-store.js
@@ -76,6 +76,13 @@ function service() {
// rules API
$app.get("/download/rule/:name", downloadRule);
+ $app.route("/api/rules")
+ .post(createRule)
+ .get(getAllRules);
+ $app.route("/api/rule/:name")
+ .patch(updateRule)
+ .delete(deleteRule)
+ .get(getRule);
// Storage management
$app.route("/api/storage")
@@ -435,6 +442,22 @@ function service() {
}
}
+ function createRule(req, res) {
+
+ }
+ function deleteRule(req, res) {
+
+ }
+ function updateRule(req, res) {
+
+ }
+ function getAllRules(req, res) {
+
+ }
+ function getRule(req, res) {
+
+ }
+
// settings API
function getSettings(req, res) {
const settings = $.read(SETTINGS_KEY);
diff --git a/web/public/index.html b/web/public/index.html
index 7e83902..d115030 100644
--- a/web/public/index.html
+++ b/web/public/index.html
@@ -5,8 +5,11 @@
+
+
+
-
+
diff --git a/web/src/App.vue b/web/src/App.vue
index 4f88643..7122ac8 100644
--- a/web/src/App.vue
+++ b/web/src/App.vue
@@ -34,20 +34,20 @@ import BottomNav from "@/components/BottomNav";
import {showError} from "@/utils";
-function initStore(store) {
- store.dispatch('FETCH_SUBSCRIPTIONS').catch(() => {
+async function initStore(store) {
+ await store.dispatch('FETCH_SUBSCRIPTIONS').catch(() => {
showError(`无法拉取订阅列表!`);
});
- store.dispatch("FETCH_COLLECTIONS").catch(() => {
+ await store.dispatch("FETCH_COLLECTIONS").catch(() => {
showError(`无法拉取组合订阅列表!`);
});
- store.dispatch("FETCH_ARTIFACTS").catch(() => {
+ await store.dispatch("FETCH_ARTIFACTS").catch(() => {
showError(`无法拉取配置列表!`);
});
- store.dispatch("FETCH_SETTINGS").catch(() => {
+ await store.dispatch("FETCH_SETTINGS").catch(() => {
showError(`无法拉取配置列表!`);
});
- store.dispatch("FETCH_ENV").catch(() => {
+ await store.dispatch("FETCH_ENV").catch(() => {
showError(`无法获取当前运行环境!`);
});
}
@@ -60,7 +60,12 @@ export default {
created() {
initStore(this.$store);
- // this.$vuetify.theme.dark = !this.$vuetify.theme.dark;
+ this.$store.watch(
+ (state => state.settings.theme.darkMode),
+ (value => {
+ this.$vuetify.theme.dark = value
+ })
+ )
},
computed: {
@@ -74,15 +79,23 @@ export default {
watch: {
successMessage() {
- setTimeout(() => {
+ if (this.$store.state.snackbarTimer) {
+ clearTimeout(this.$store.state.snackbarTimer);
+ }
+ const timer = setTimeout(() => {
this.$store.commit("SET_SUCCESS_MESSAGE", "");
- }, 1000);
+ }, 3000);
+ this.$store.commit("SET_SNACK_BAR_TIMER", timer);
},
errorMessage() {
- setTimeout(() => {
+ if (this.$store.state.snackbarTimer) {
+ clearTimeout(this.$store.state.snackbarTimer);
+ }
+ const timer = setTimeout(() => {
this.$store.commit("SET_ERROR_MESSAGE", "");
- }, 1000);
- },
+ }, 3000);
+ this.$store.commit("SET_SNACK_BAR_TIMER", timer);
+ }
}
}
diff --git a/web/src/router/index.js b/web/src/router/index.js
index 01e1f78..400ead1 100644
--- a/web/src/router/index.js
+++ b/web/src/router/index.js
@@ -17,25 +17,25 @@ const router = new Router({
path: "/",
name: "subscriptions",
component: Subscription,
- meta: {title: "订阅"}
+ meta: {title: "订阅", keepAlive: true}
},
{
path: "/dashboard",
name: "dashboard",
component: Dashboard,
- meta: {title: "首页"}
+ meta: {title: "首页", keepAlive: true}
},
{
path: "/cloud",
name: "artifact",
component: Cloud,
- meta: {title: "同步"}
+ meta: {title: "同步", keepAlive: true}
},
{
path: "/user",
name: "user",
component: User,
- meta: {title: "我的"}
+ meta: {title: "我的", keepAlive: true}
},
{
path: "/sub-edit/:name",
diff --git a/web/src/store/index.js b/web/src/store/index.js
index 853c004..71307da 100644
--- a/web/src/store/index.js
+++ b/web/src/store/index.js
@@ -7,17 +7,21 @@ Vue.use(Vuex);
const store = new Vuex.Store({
state: {
title: "Sub-Store",
- isDarkMode: false,
clipboard: "",
successMessage: "",
errorMessage: "",
+ snackbarTimer: "",
subscriptions: {},
collections: {},
artifacts: {},
env: {},
- settings: {}
+ settings: {
+ theme: {
+ darkMode: false
+ }
+ }
},
mutations: {
@@ -28,8 +32,9 @@ const store = new Vuex.Store({
SET_NAV_TITLE(state, title) {
state.title = title;
},
- SET_DARK_MODE(state, isDarkMode) {
- state.isDarkMode = isDarkMode
+
+ SET_SNACK_BAR_TIMER(state, timer) {
+ state.snackbarTimer = timer;
},
SET_SUCCESS_MESSAGE(state, msg) {
@@ -40,6 +45,9 @@ const store = new Vuex.Store({
state.errorMessage = msg;
},
+ SET_DARK_MODE(state, on) {
+ state.settings.theme.darkMode = on;
+ }
},
actions: {
@@ -71,7 +79,12 @@ const store = new Vuex.Store({
},
async FETCH_SETTINGS({state}) {
return axios.get("/settings").then(resp => {
- state.settings = resp.data;
+ state.settings = {
+ theme: {
+ darkMode: false
+ },
+ ...resp.data
+ }
});
},
// update subscriptions
diff --git a/web/src/views/Cloud.vue b/web/src/views/Cloud.vue
index 26170de..10107af 100644
--- a/web/src/views/Cloud.vue
+++ b/web/src/views/Cloud.vue
@@ -2,14 +2,12 @@
+ mdi-cloud
同步配置
-
-
-
-
-
-
+
+ visibility
+
@@ -195,6 +193,9 @@ export default {
artifacts() {
const items = this.$store.state.artifacts;
return Object.keys(items).map(k => items[k]);
+ },
+ settings() {
+ return this.$store.state.settings;
}
},
methods: {
@@ -287,6 +288,10 @@ export default {
data = this.$store.state.collections;
}
return Object.keys(data);
+ },
+
+ openGist() {
+ window.open(`https://gist.github.com${ '/' + this.settings.githubUser || ''}`)
}
}
}
diff --git a/web/src/views/SubEditor.vue b/web/src/views/SubEditor.vue
index 5dd7968..85db72d 100644
--- a/web/src/views/SubEditor.vue
+++ b/web/src/views/SubEditor.vue
@@ -36,7 +36,7 @@
mdi-cloud
-
+
{{ sub.name }}
@@ -571,7 +571,7 @@ function uuidv4() {
\ No newline at end of file
diff --git a/web/src/views/Subscription.vue b/web/src/views/Subscription.vue
index 585ce29..6a51f74 100644
--- a/web/src/views/Subscription.vue
+++ b/web/src/views/Subscription.vue
@@ -2,6 +2,7 @@
+ local_airport
单个订阅
@@ -17,7 +18,7 @@
>
mdi-cloud
-
+
@@ -54,6 +55,7 @@
+ work_outline
组合订阅
@@ -70,7 +72,7 @@
>
mdi-cloud
-
+
@@ -166,6 +168,14 @@ export default {
title: "删除",
action: "DELETE"
},
+ // {
+ // title: "上移",
+ // action: "MOVE_UP"
+ // },
+ // {
+ // title: "下移",
+ // action: "MOVE_DOWN"
+ // }
]
}
},
@@ -174,9 +184,14 @@ export default {
subscriptionBaseURL() {
return BACKEND_BASE;
},
- subscriptions() {
- const subs = this.$store.state.subscriptions;
- return Object.keys(subs).map(k => subs[k]);
+ subscriptions: {
+ get(){
+ const subs = this.$store.state.subscriptions;
+ return Object.keys(subs).map(k => subs[k]);
+ },
+ set(){
+
+ }
},
collections() {
const cols = this.$store.state.collections;
@@ -197,6 +212,12 @@ export default {
break
case 'DELETE':
this.$store.dispatch("DELETE_SUBSCRIPTION", sub.name);
+ break
+ case 'MOVE_UP':
+ this.moveUpSubscription(sub.name);
+ break
+ case 'MOVE_DOWN':
+
break
}
},
@@ -232,15 +253,29 @@ export default {
},
refreshProxyList() {
this.$refs.proxyList.refresh();
- }
+ },
+ moveUpSubscription(name) {
+ let index = 0;
+ for (; index < this.subscriptions.length; index++) {
+ if (this.subscriptions[index].name === name) {
+ break;
+ }
+ }
+ if (index === 0) return;
+ // otherwise swap with previous one
+ const prev = this.subscriptions[index - 1];
+ const cur = this.subscriptions[index];
+ this.subscriptions.splice(index - 1, 2, cur, prev);
+ },
+ // moveDownSubscription(name) {
+ //
+ // }
}
}
\ No newline at end of file
diff --git a/web/src/views/User.vue b/web/src/views/User.vue
index 9abf180..5375719 100644
--- a/web/src/views/User.vue
+++ b/web/src/views/User.vue
@@ -2,25 +2,86 @@
- GitHub 配置
+ mdi-cloud
+ 数据同步
- settings
+
+ visibility
+
-
+ 最近同步于:{{ syncTime }}
+
+
+
+
+
+ 上传
+
+ mdi-cloud-upload
+
+
+
+ 恢复
+
+ mdi-cloud-download
+
+
+
+
-
-
+
+
+ settings
+ 设置
+
+
+
+
+ GitHub配置
+
+
+
+
+
+
+
+
+
+
+
+ 外观
+
+
+ 夜间模式 (实验性支持)
+
+
+
+
+
+
@@ -30,21 +91,21 @@
-
-
- Gist 数据同步
-
- mdi-cloud
-
-
- 最近同步于:{{syncTime}}
-
-
-
- 上传
- 恢复
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -53,11 +114,24 @@ import {axios, showError} from "@/utils";
import {format} from "timeago.js";
export default {
+ data() {
+ return {
+ status: {
+ uploading: false,
+ downloading: false
+ }
+ }
+ },
computed: {
- settings() {
- return this.$store.state.settings;
+ settings: {
+ get() {
+ return this.$store.state.settings;
+ },
+ set(value) {
+ this.$store.state.settings = value;
+ }
},
- syncTime(){
+ syncTime() {
if (this.settings.syncTime) {
return format(this.settings.syncTime, "zh_CN");
} else {
@@ -66,26 +140,41 @@ export default {
}
},
methods: {
- save() {
- axios.patch(`/settings`, this.settings);
- this.$store.dispatch("FETCH_SETTINGS");
+ async save() {
+ await axios.patch(`/settings`, this.settings);
+ await this.$store.dispatch("FETCH_SETTINGS");
this.$store.commit("SET_SUCCESS_MESSAGE", `保存成功!`);
},
// eslint-disable-next-line no-unused-vars
sync(action) {
+ const setLoading = (status) => {
+ if (action === 'upload') {
+ this.status.uploading = status;
+ } else if (action === 'download'){
+ this.status.downloading = status;
+ }
+ }
+
if (!this.settings.gistToken) {
this.$store.commit("SET_ERROR_MESSAGE", "未设置GitHub Token!");
return;
}
+
+ setLoading(true);
axios.get(`/utils/backup?action=${action}`).then(resp => {
if (resp.data.status === 'success') {
this.$store.commit("SET_SUCCESS_MESSAGE", `${action === 'upload' ? "备份" : "还原"}成功!`);
- this.settings.syncTime = new Date().getTime();
+ if (action === 'upload') {
+ this.settings.syncTime = new Date().getTime();
+ }
axios.patch(`/settings`, this.settings);
this.updateStore(this.$store);
- } else
- this.$store.commit("SET_ERROR_MESSAGE", `备份失败!${resp.data.message}`);
+ }
+ }).catch(err => {
+ this.$store.commit("SET_ERROR_MESSAGE", `备份失败!${err}`);
+ }).finally(() => {
+ setLoading(false);
});
},
@@ -96,9 +185,16 @@ export default {
store.dispatch("FETCH_COLLECTIONS").catch(() => {
showError(`无法拉取组合订阅列表!`);
});
+ store.dispatch("FETCH_SETTINGS").catch(() => {
+ showError(`无法拉取设置!`);
+ });
store.dispatch("FETCH_ARTIFACTS").catch(() => {
showError(`无法拉取同步配置!`);
});
+ },
+
+ openGist() {
+ window.open(`https://gist.github.com${'/' + this.settings.githubUser || ''}`)
}
}
}