diff options
author | Joas Schilling <coding@schilljs.com> | 2020-02-19 15:55:07 +0300 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2020-02-25 11:50:00 +0300 |
commit | 531b5a9aad088ae2d410976e1ae091a1827fed91 (patch) | |
tree | 59b03725782d7e2e17d08388c9c4e82991fede52 | |
parent | f318ef65e15812d4189771351629b5f4f07f0ea6 (diff) |
Allow to select an attachment folder
Signed-off-by: Joas Schilling <coding@schilljs.com>
-rw-r--r-- | appinfo/routes.php | 12 | ||||
-rw-r--r-- | lib/Config.php | 4 | ||||
-rw-r--r-- | lib/Controller/PageController.php | 5 | ||||
-rw-r--r-- | lib/Controller/SettingsController.php | 101 | ||||
-rw-r--r-- | src/components/LeftSidebar/LeftSidebar.vue | 43 | ||||
-rw-r--r-- | src/services/settingsService.js | 41 |
6 files changed, 206 insertions, 0 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php index f0729ba87..94676923f 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -397,6 +397,18 @@ return [ 'token' => '^[a-z0-9]{4,30}$', ], ], + + /** + * UserSettings + */ + [ + 'name' => 'Settings#setUserSetting', + 'url' => '/api/{apiVersion}/settings/user', + 'verb' => 'POST', + 'requirements' => [ + 'apiVersion' => 'v1', + ], + ], ], ]; diff --git a/lib/Config.php b/lib/Config.php index 8c0ad3e52..de032f2ec 100644 --- a/lib/Config.php +++ b/lib/Config.php @@ -68,6 +68,10 @@ class Config { return empty(array_intersect($allowedGroups, $userGroups)); } + public function getAttachmentFolder(string $userId): string { + return $this->config->getUserValue($userId, 'spreed', 'attachment_folder', '/Talk'); + } + public function getSettings(?string $userId): array { $stun = []; $stunServer = $this->getStunServer(); diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index ee40c7112..48b5b3d02 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -211,6 +211,11 @@ class PageController extends Controller { $this->appManager->isEnabledForUser('circles', $user) ); + $this->initialStateService->provideInitialState( + 'talk', 'attachment_folder', + $this->config->getAttachmentFolder($user->getUID()) + ); + $params = [ 'token' => $token, 'signaling-settings' => $this->config->getSettings($this->userId), diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php new file mode 100644 index 000000000..8b96818dc --- /dev/null +++ b/lib/Controller/SettingsController.php @@ -0,0 +1,101 @@ +<?php +declare(strict_types=1); +/** + * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @license GNU AGPL version 3 or any later version + * + * 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/>. + * + */ + +namespace OCA\Talk\Controller; + +use OCA\Files_Sharing\SharedStorage; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\OCSController; +use OCP\Files\Folder; +use OCP\Files\IRootFolder; +use OCP\Files\NotFoundException; +use OCP\Files\NotPermittedException; +use OCP\IConfig; +use OCP\ILogger; +use OCP\IRequest; + +class SettingsController extends OCSController { + + /** @var IRootFolder */ + protected $rootFolder; + /** @var IConfig */ + protected $config; + /** @var ILogger */ + protected $logger; + /** @var string|null */ + protected $userId; + + public function __construct(string $appName, + IRequest $request, + IRootFolder $rootFolder, + IConfig $config, + ILogger $logger, + ?string $userId) { + parent::__construct($appName, $request); + $this->rootFolder = $rootFolder; + $this->config = $config; + $this->logger = $logger; + $this->userId = $userId; + } + + /** + * @NoAdminRequired + * + * @param string $key + * @param string|null $value + * @return DataResponse + */ + public function setUserSetting(string $key, ?string $value): DataResponse { + if (!$this->validateUserSetting($key, $value)) { + return new DataResponse([], Http::STATUS_BAD_REQUEST); + } + + $this->config->setUserValue($this->userId, 'spreed', $key, $value); + + return new DataResponse(); + } + + protected function validateUserSetting(string $setting, ?string $value): bool { + if ($setting === 'attachment_folder') { + $userFolder = $this->rootFolder->getUserFolder($this->userId); + try { + $node = $userFolder->get($value); + if (!$node instanceof Folder) { + throw new NotPermittedException('Node is not a directory'); + } + return !$node->getStorage()->instanceOfStorage(SharedStorage::class); + } catch (NotFoundException $e) { + $userFolder->newFolder($value); + return true; + } catch (NotPermittedException $e) { + } catch (\Exception $e) { + $this->logger->logException($e); + } + return false; + } + + return false; + } +} diff --git a/src/components/LeftSidebar/LeftSidebar.vue b/src/components/LeftSidebar/LeftSidebar.vue index c7bd30067..9d77f4877 100644 --- a/src/components/LeftSidebar/LeftSidebar.vue +++ b/src/components/LeftSidebar/LeftSidebar.vue @@ -72,11 +72,21 @@ <Hint v-else :hint="t('spreed', 'No search results')" /> </template> </ul> + + <AppNavigationSettings> + <label>{{ t('spreed', 'Default location for attachments') }}</label> + <input + type="text" + :value="attachmentFolder" + :disabled="attachmentFolderLoading" + @click="selectAttachmentFolder"> + </AppNavigationSettings> </AppNavigation> </template> <script> import AppNavigation from '@nextcloud/vue/dist/Components/AppNavigation' +import AppNavigationSettings from '@nextcloud/vue/dist/Components/AppNavigationSettings' import Caption from '../Caption' import ConversationsList from './ConversationsList/ConversationsList' import ConversationsOptionsList from '../ConversationsOptionsList' @@ -88,9 +98,20 @@ import { createGroupConversation, createOneToOneConversation, searchPossibleConversations, } from '../../services/conversationsService' +import { setAttachmentFolder } from '../../services/settingsService' import { CONVERSATION } from '../../constants' import { loadState } from '@nextcloud/initial-state' import NewGroupConversation from './NewGroupConversation/NewGroupConversation' +import { getFilePickerBuilder } from '@nextcloud/dialogs' + +const picker = getFilePickerBuilder(t('spreed', 'Select default location for attachments')) + .setMultiSelect(false) + .setModal(true) + .setType(1) + .addMimeTypeFilter(['httpd/unix-directory']) + .allowDirectories() + .startAt(loadState('talk', 'attachment_folder')) + .build() export default { @@ -98,6 +119,7 @@ export default { components: { AppNavigation, + AppNavigationSettings, Caption, ConversationsList, ConversationsOptionsList, @@ -115,6 +137,8 @@ export default { searchResultsCircles: [], contactsLoading: false, isCirclesEnabled: loadState('talk', 'circles_enabled'), + attachmentFolder: loadState('talk', 'attachment_folder'), + attachmentFolderLoading: false, } }, @@ -220,6 +244,25 @@ export default { handleClickConversation() { this.searchText = '' }, + + selectAttachmentFolder() { + picker.pick() + .then(async(path) => { + console.debug(`Path '${path}' selected for talk attachments`) + if (path !== '' && !path.startsWith('/')) { + throw new Error(t('spreed', 'Invalid path selected')) + } + + this.attachmentFolderLoading = true + this.attachmentFolder = path + try { + await setAttachmentFolder(path) + } catch (exception) { + OCP.Toast.error(t('spreed', 'Error while setting attachment folder')) + } + this.attachmentFolderLoading = false + }) + }, }, } </script> diff --git a/src/services/settingsService.js b/src/services/settingsService.js new file mode 100644 index 000000000..65e262658 --- /dev/null +++ b/src/services/settingsService.js @@ -0,0 +1,41 @@ +/** + * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @license GNU AGPL version 3 or any later version + * + * 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 axios from '@nextcloud/axios' +import { generateOcsUrl } from '@nextcloud/router' + +/** + * Gets the conversation token for a given file id + * + * @param {string} path The name of the folder + * @returns {Object} The axios response + */ +const setAttachmentFolder = async function(path) { + return axios.post(generateOcsUrl('apps/spreed/api/v1/settings', 2) + 'user', { + key: 'attachment_folder', + value: path, + }) +} + +export { + setAttachmentFolder, +} |