diff options
author | Louis Chemineau <louis@chmn.me> | 2024-02-06 19:29:26 +0100 |
---|---|---|
committer | Louis Chemineau <louis@chmn.me> | 2024-02-15 16:24:02 +0100 |
commit | bc85b66765e86f76bf5096ceb9243e17b403bd9d (patch) | |
tree | 1840cf9ab3cf3771b5ef23824e20630ef8dac476 | |
parent | e038644eb1691a48fd1a553accb64cbeecebb2fe (diff) |
Use store to manage user config
Signed-off-by: Louis Chemineau <louis@chmn.me>
-rw-r--r-- | src/components/Settings/PhotosFolder.vue | 6 | ||||
-rw-r--r-- | src/components/Settings/PhotosSourceLocationsSettings.vue | 20 | ||||
-rw-r--r-- | src/components/Settings/PhotosUploadLocationSettings.vue | 15 | ||||
-rw-r--r-- | src/main.js | 2 | ||||
-rw-r--r-- | src/store/index.js | 2 | ||||
-rw-r--r-- | src/store/userConfig.js | 97 |
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 |