From b28f8e58a48ec35307d753a7a0007acee244f2e4 Mon Sep 17 00:00:00 2001 From: lihengxin Date: Wed, 7 Sep 2022 14:31:47 +0800 Subject: [PATCH] Add settings: Editor Auto Save Interval Change-Id: I9ce890d9f9a264582f26a1d4cb4fcc0a924ae949 --- frontend/src/i18n/en.json | 2 ++ frontend/src/views/files/Editor.vue | 17 +++++++++- frontend/src/views/settings/Profile.vue | 43 +++++++++++++++++++++++++ http/auth.go | 38 +++++++++++----------- settings/defaults.go | 20 ++++++------ users/users.go | 31 +++++++++--------- 6 files changed, 108 insertions(+), 43 deletions(-) diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index 6aaa6145..f434e664 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -178,6 +178,7 @@ "brandingDirectoryPath": "Branding directory path", "brandingHelp": "You can customize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", "changePassword": "Change Password", + "changeEditorSettings": "Change Editor Settings", "commandRunner": "Command runner", "commandRunnerHelp": "Here you can set commands that are executed in the named events. You must write one per line. The environment variables {0} and {1} will be available, being {0} relative to {1}. For more information about this feature and the available environment variables, please read the {2}.", "commandsUpdated": "Commands updated!", @@ -224,6 +225,7 @@ "rulesHelp": "Here you can define a set of allow and disallow rules for this specific user. The blocked files won't show up in the listings and they wont be accessible to the user. We support regex and paths relative to the users scope.\n", "scope": "Scope", "setDateFormat": "Set exact date format", + "editorAutoSaveInterval": "Set editor auto save interval", "settingsUpdated": "Settings updated!", "shareDuration": "Share Duration", "shareManagement": "Share Management", diff --git a/frontend/src/views/files/Editor.vue b/frontend/src/views/files/Editor.vue index 3dbabc74..b73d4829 100644 --- a/frontend/src/views/files/Editor.vue +++ b/frontend/src/views/files/Editor.vue @@ -34,6 +34,8 @@ import HeaderBar from "@/components/header/HeaderBar"; import Action from "@/components/header/Action"; import Breadcrumbs from "@/components/Breadcrumbs"; +let timeoutBox; + export default { name: "editor", components: { @@ -77,9 +79,11 @@ export default { }, }, created() { + this.autoSave(); window.addEventListener("keydown", this.keyEvent); }, beforeDestroy() { + clearTimeout(timeoutBox); window.removeEventListener("keydown", this.keyEvent); this.editor.destroy(); }, @@ -129,11 +133,22 @@ export default { } }, close() { + this.save(); this.$store.commit("updateRequest", {}); - let uri = url.removeLastDir(this.$route.path) + "/"; this.$router.push({ path: uri }); }, + autoSave() { + let editorAutoSaveInterval = this.user.editorAutoSaveInterval; + if (editorAutoSaveInterval < 0) { + return; + } + clearTimeout(timeoutBox); + timeoutBox = setTimeout(() => { + this.save(); + this.autoSave(); + }, editorAutoSaveInterval * 1000); + }, }, }; diff --git a/frontend/src/views/settings/Profile.vue b/frontend/src/views/settings/Profile.vue index 0b8af637..20254c23 100644 --- a/frontend/src/views/settings/Profile.vue +++ b/frontend/src/views/settings/Profile.vue @@ -68,6 +68,32 @@ +
+
+
+

{{ $t("settings.changeEditorSettings") }}

+
+
+ + + +
+
+ +
+
+
@@ -89,6 +115,7 @@ export default { singleClick: false, dateFormat: false, locale: "", + editorAutoSaveInterval: 60, }; }, computed: { @@ -113,6 +140,7 @@ export default { this.hideDotfiles = this.user.hideDotfiles; this.singleClick = this.user.singleClick; this.dateFormat = this.user.dateFormat; + this.editorAutoSaveInterval = this.user.editorAutoSaveInterval; }, methods: { ...mapMutations(["updateUser", "setLoading"]), @@ -155,6 +183,21 @@ export default { this.$showError(e); } }, + async updateEditorSettings(event) { + event.preventDefault(); + + try { + const data = { + id: this.user.id, + editorAutoSaveInterval: this.editorAutoSaveInterval, + }; + await api.update(data, ["editorAutoSaveInterval"]); + this.updateUser(data); + this.$showSuccess(this.$t("settings.settingsUpdated")); + } catch (e) { + this.$showError(e); + } + }, }, }; diff --git a/http/auth.go b/http/auth.go index 4df68262..83462bc7 100644 --- a/http/auth.go +++ b/http/auth.go @@ -20,15 +20,16 @@ const ( ) type userInfo struct { - ID uint `json:"id"` - Locale string `json:"locale"` - ViewMode users.ViewMode `json:"viewMode"` - SingleClick bool `json:"singleClick"` - Perm users.Permissions `json:"perm"` - Commands []string `json:"commands"` - LockPassword bool `json:"lockPassword"` - HideDotfiles bool `json:"hideDotfiles"` - DateFormat bool `json:"dateFormat"` + ID uint `json:"id"` + Locale string `json:"locale"` + ViewMode users.ViewMode `json:"viewMode"` + SingleClick bool `json:"singleClick"` + Perm users.Permissions `json:"perm"` + Commands []string `json:"commands"` + LockPassword bool `json:"lockPassword"` + HideDotfiles bool `json:"hideDotfiles"` + DateFormat bool `json:"dateFormat"` + EditorAutoSaveInterval int `json:"editorAutoSaveInterval"` } type authToken struct { @@ -179,15 +180,16 @@ var renewHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data func printToken(w http.ResponseWriter, _ *http.Request, d *data, user *users.User) (int, error) { claims := &authToken{ User: userInfo{ - ID: user.ID, - Locale: user.Locale, - ViewMode: user.ViewMode, - SingleClick: user.SingleClick, - Perm: user.Perm, - LockPassword: user.LockPassword, - Commands: user.Commands, - HideDotfiles: user.HideDotfiles, - DateFormat: user.DateFormat, + ID: user.ID, + Locale: user.Locale, + ViewMode: user.ViewMode, + SingleClick: user.SingleClick, + Perm: user.Perm, + LockPassword: user.LockPassword, + Commands: user.Commands, + HideDotfiles: user.HideDotfiles, + DateFormat: user.DateFormat, + EditorAutoSaveInterval: user.EditorAutoSaveInterval, }, RegisteredClaims: jwt.RegisteredClaims{ IssuedAt: jwt.NewNumericDate(time.Now()), diff --git a/settings/defaults.go b/settings/defaults.go index d60e36dc..1958e218 100644 --- a/settings/defaults.go +++ b/settings/defaults.go @@ -8,15 +8,16 @@ import ( // UserDefaults is a type that holds the default values // for some fields on User. type UserDefaults struct { - Scope string `json:"scope"` - Locale string `json:"locale"` - ViewMode users.ViewMode `json:"viewMode"` - SingleClick bool `json:"singleClick"` - Sorting files.Sorting `json:"sorting"` - Perm users.Permissions `json:"perm"` - Commands []string `json:"commands"` - HideDotfiles bool `json:"hideDotfiles"` - DateFormat bool `json:"dateFormat"` + Scope string `json:"scope"` + Locale string `json:"locale"` + ViewMode users.ViewMode `json:"viewMode"` + SingleClick bool `json:"singleClick"` + Sorting files.Sorting `json:"sorting"` + Perm users.Permissions `json:"perm"` + Commands []string `json:"commands"` + HideDotfiles bool `json:"hideDotfiles"` + DateFormat bool `json:"dateFormat"` + EditorAutoSaveInterval int `json:"autoSaveInterval"` } // Apply applies the default options to a user. @@ -30,4 +31,5 @@ func (d *UserDefaults) Apply(u *users.User) { u.Commands = d.Commands u.HideDotfiles = d.HideDotfiles u.DateFormat = d.DateFormat + u.EditorAutoSaveInterval = d.EditorAutoSaveInterval } diff --git a/users/users.go b/users/users.go index 120e4599..3b454d91 100644 --- a/users/users.go +++ b/users/users.go @@ -21,21 +21,22 @@ const ( // User describes a user. type User struct { - ID uint `storm:"id,increment" json:"id"` - Username string `storm:"unique" json:"username"` - Password string `json:"password"` - Scope string `json:"scope"` - Locale string `json:"locale"` - LockPassword bool `json:"lockPassword"` - ViewMode ViewMode `json:"viewMode"` - SingleClick bool `json:"singleClick"` - Perm Permissions `json:"perm"` - Commands []string `json:"commands"` - Sorting files.Sorting `json:"sorting"` - Fs afero.Fs `json:"-" yaml:"-"` - Rules []rules.Rule `json:"rules"` - HideDotfiles bool `json:"hideDotfiles"` - DateFormat bool `json:"dateFormat"` + ID uint `storm:"id,increment" json:"id"` + Username string `storm:"unique" json:"username"` + Password string `json:"password"` + Scope string `json:"scope"` + Locale string `json:"locale"` + LockPassword bool `json:"lockPassword"` + ViewMode ViewMode `json:"viewMode"` + SingleClick bool `json:"singleClick"` + Perm Permissions `json:"perm"` + Commands []string `json:"commands"` + Sorting files.Sorting `json:"sorting"` + Fs afero.Fs `json:"-" yaml:"-"` + Rules []rules.Rule `json:"rules"` + HideDotfiles bool `json:"hideDotfiles"` + DateFormat bool `json:"dateFormat"` + EditorAutoSaveInterval int `json:"editorAutoSaveInterval"` } // GetRules implements rules.Provider.