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 + @@ -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 || ''}`) } } }