summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis Chemineau <louis@chmn.me>2024-02-06 19:29:26 +0100
committerLouis Chemineau <louis@chmn.me>2024-02-15 16:24:02 +0100
commitbc85b66765e86f76bf5096ceb9243e17b403bd9d (patch)
tree1840cf9ab3cf3771b5ef23824e20630ef8dac476
parente038644eb1691a48fd1a553accb64cbeecebb2fe (diff)
Use store to manage user config
Signed-off-by: Louis Chemineau <louis@chmn.me>
-rw-r--r--src/components/Settings/PhotosFolder.vue6
-rw-r--r--src/components/Settings/PhotosSourceLocationsSettings.vue20
-rw-r--r--src/components/Settings/PhotosUploadLocationSettings.vue15
-rw-r--r--src/main.js2
-rw-r--r--src/store/index.js2
-rw-r--r--src/store/userConfig.js97
6 files changed, 125 insertions, 17 deletions
diff --git a/src/components/Settings/PhotosFolder.vue b/src/components/Settings/PhotosFolder.vue
index 4b65b1c0..bc3aa630 100644
--- a/src/components/Settings/PhotosFolder.vue
+++ b/src/components/Settings/PhotosFolder.vue
@@ -48,6 +48,10 @@ export default defineComponent({
type: Boolean,
default: false,
},
+ rootFolderLabel: {
+ type: String,
+ required: true,
+ },
},
emits: ['remove-folder'],
@@ -55,7 +59,7 @@ export default defineComponent({
computed: {
folderName() {
if (this.path === '/') {
- return t('photos', 'All folders')
+ return this.rootFolderLabel
} else {
return this.path.split('/').pop()
}
diff --git a/src/components/Settings/PhotosSourceLocationsSettings.vue b/src/components/Settings/PhotosSourceLocationsSettings.vue
index 3c301a41..514c1483 100644
--- a/src/components/Settings/PhotosSourceLocationsSettings.vue
+++ b/src/components/Settings/PhotosSourceLocationsSettings.vue
@@ -25,7 +25,7 @@
<ul>
<li v-for="(source, index) in photosSourceFolders"
:key="index">
- <PhotosFolder :path="source" :can-delete="photosSourceFolders.length !== 1" @remove-folder="removeSourceFolder(index)" />
+ <PhotosFolder :path="source" :can-delete="photosSourceFolders.length !== 1" @remove-folder="removeSourceFolder(index)" :root-folder-label="t('photos', 'All folders')"/>
</li>
</ul>
@@ -49,7 +49,6 @@ import { NcButton } from '@nextcloud/vue'
import { getFilePickerBuilder } from '@nextcloud/dialogs'
import { translate as t } from '@nextcloud/l10n'
-import UserConfig from '../../mixins/UserConfig.js'
import PhotosFolder from './PhotosFolder.vue'
export default defineComponent({
@@ -61,9 +60,12 @@ export default defineComponent({
PhotosFolder,
},
- mixins: [
- UserConfig,
- ],
+ computed: {
+ /** @return {string[]} */
+ photosSourceFolders() {
+ return this.$store.state.userConfig.photosSourceFolders
+ },
+ },
methods: {
debounceAddSourceFolder: debounce(function(...args) {
@@ -87,13 +89,13 @@ export default defineComponent({
if (this.photosSourceFolders.includes(pickedFolder)) {
return
}
- this.photosSourceFolders.push(pickedFolder)
- this.updateSetting('photosSourceFolders')
+ this.$store.dispatch('updateUserConfig', { key: 'photosSourceFolders', value: [...this.photosSourceFolders, pickedFolder] })
},
removeSourceFolder(index) {
- this.photosSourceFolders.splice(index, 1)
- this.updateSetting('photosSourceFolders')
+ const folders = [...this.photosSourceFolders]
+ folders.splice(index, 1)
+ this.$store.dispatch('updateUserConfig', { key: 'photosSourceFolders', value: folders })
},
t,
diff --git a/src/components/Settings/PhotosUploadLocationSettings.vue b/src/components/Settings/PhotosUploadLocationSettings.vue
index bed20675..2a637e4e 100644
--- a/src/components/Settings/PhotosUploadLocationSettings.vue
+++ b/src/components/Settings/PhotosUploadLocationSettings.vue
@@ -22,7 +22,7 @@
<template>
<div class="photos-location">
- <PhotosFolder :path="photosLocation" />
+ <PhotosFolder :path="photosLocation" :root-folder-label="t('photos', 'Root folder')" />
<NcButton :aria-label="t('photos', 'Choose default Photos upload and Albums location')"
@click="debounceSelectPhotosFolder">
@@ -39,7 +39,6 @@ import { NcButton } from '@nextcloud/vue'
import { getFilePickerBuilder } from '@nextcloud/dialogs'
import { translate as t } from '@nextcloud/l10n'
-import UserConfig from '../../mixins/UserConfig.js'
import PhotosFolder from './PhotosFolder.vue'
export default defineComponent({
@@ -50,9 +49,12 @@ export default defineComponent({
PhotosFolder,
},
- mixins: [
- UserConfig,
- ],
+ computed: {
+ /** @return {string} */
+ photosLocation() {
+ return this.$store.state.userConfig.photosLocation
+ },
+ },
methods: {
debounceSelectPhotosFolder: debounce(function() {
@@ -78,8 +80,7 @@ export default defineComponent({
},
updatePhotosFolder(path) {
- this.photosLocation = path
- this.updateSetting('photosLocation')
+ this.$store.dispatch('updateUserConfig', { key: 'photosLocation', value: path })
},
t,
diff --git a/src/main.js b/src/main.js
index 5e281653..aca61424 100644
--- a/src/main.js
+++ b/src/main.js
@@ -65,3 +65,5 @@ export default new Vue({
store,
render: h => h(Photos),
})
+
+store.dispatch('initUserConfig') \ No newline at end of file
diff --git a/src/store/index.js b/src/store/index.js
index f9bb7841..ad1ff6de 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -32,6 +32,7 @@ import places from './places.js'
import faces from './faces.js'
import folders from './folders.js'
import systemtags from './systemtags.js'
+import userConfig from './userConfig.js'
Vue.use(Vuex)
export default new Store({
@@ -45,6 +46,7 @@ export default new Store({
systemtags,
collections,
places,
+ userConfig,
},
strict: process.env.NODE_ENV !== 'production',
diff --git a/src/store/userConfig.js b/src/store/userConfig.js
new file mode 100644
index 00000000..87929039
--- /dev/null
+++ b/src/store/userConfig.js
@@ -0,0 +1,97 @@
+/* eslint-disable jsdoc/require-jsdoc */
+/**
+ * @copyright Copyright (c) 2024 Louis Chmn <louis@chmn.me>
+ *
+ * @author Louis Chmn <louis@chmn.me>
+ *
+ * @license AGPL-3.0-or-later
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+import { Folder, davGetClient, davGetDefaultPropfind, davResultToNode, davRootPath } from '@nextcloud/files'
+import { loadState } from '@nextcloud/initial-state'
+import { joinPaths } from '@nextcloud/paths'
+import { showError } from '@nextcloud/dialogs'
+import { translate as t } from '@nextcloud/l10n'
+import { generateUrl } from '@nextcloud/router'
+import axios from '@nextcloud/axios'
+
+import logger from '../services/logger.js'
+
+export const configChangedEvent = 'photos:user-config-changed'
+
+export async function getFolder(path) {
+ const davClient = davGetClient()
+ const location = joinPaths(davRootPath, path) + '/'
+ try {
+ const stat = await davClient.stat(location, { details: true, data: davGetDefaultPropfind() })
+ return davResultToNode(stat.data)
+ } catch (error) {
+ if (error.response?.status === 404) {
+ logger.debug('Photo location does not exist, creating it.')
+ await davClient.createDirectory(location)
+ const stat = await davClient.stat(location, { details: true, data: davGetDefaultPropfind() })
+ return davResultToNode(stat.data)
+ } else {
+ logger.fatal(error)
+ showError(t('photos', 'Could not load photos folder'))
+ }
+ }
+
+ throw new Error("Couldn't fetch photos upload folder")
+}
+
+/**
+ * @typedef {object} UserConfigState
+ * @property {boolean} croppedLayout
+ * @property {string} photosSourceFolder
+ * @property {string} photosLocation
+ * @property {Folder} [photosLocationFolder]
+ */
+
+/** @type {import('vuex').Module<UserConfigState, object>} */
+const module = {
+ state() {
+ return {
+ croppedLayout: loadState('photos', 'croppedLayout', 'false') === 'true',
+ photosSourceFolder: loadState('photos', 'photosSourceFolder', ''),
+ photosLocation: loadState('photos', 'photosLocation', ''),
+ photosLocationFolder: undefined,
+ }
+ },
+ mutations: {
+ updateUserConfig(state, { key, value }) {
+ state[key] = value
+ },
+ },
+ actions: {
+ async initUserConfig({ commit }) {
+ const photosLocationFolder = await getFolder(loadState('photos', 'photosLocation', ''))
+ commit('updateUserConfig', { key: 'photosLocationFolder', value: photosLocationFolder })
+ },
+ async updateUserConfig({ commit }, { key, value }) {
+ commit('updateUserConfig', { key, value })
+
+ // Long time save setting
+ await axios.put(generateUrl('apps/photos/api/v1/config/' + key), {
+ // Stringify non string values.
+ value: (typeof value === 'string') ? value : JSON.stringify(value),
+ })
+ },
+ },
+}
+
+export default module