diff --git a/.eslintrc.js b/.eslintrc.js index 00e437c1..89bcc517 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,8 @@ module.exports = { extends: [ '@nextcloud' - ] + ], + globals: { + appName: true + } }; diff --git a/appinfo/routes.php b/appinfo/routes.php index 46da55c7..b3b3a3d2 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -23,6 +23,8 @@ return [ 'routes' => [ + ['name' => 'api#setUserConfig', 'url' => '/api/v1/config/{key}', 'verb' => 'PUT'], + ['name' => 'page#index', 'url' => '/', 'verb' => 'GET'], ['name' => 'page#index', 'url' => '/videos', 'verb' => 'GET', 'postfix' => 'videos'], ['name' => 'page#index', 'url' => '/favorites', 'verb' => 'GET', 'postfix' => 'favorites'], diff --git a/js/photos-0.js b/js/photos-0.js index 8bb5b265..f909cdfb 100644 Binary files a/js/photos-0.js and b/js/photos-0.js differ diff --git a/js/photos-0.js.map b/js/photos-0.js.map index aec9950c..dfbd7f32 100644 Binary files a/js/photos-0.js.map and b/js/photos-0.js.map differ diff --git a/js/photos-1.js b/js/photos-1.js index b199056d..982e3650 100644 Binary files a/js/photos-1.js and b/js/photos-1.js differ diff --git a/js/photos-1.js.map b/js/photos-1.js.map index ed740ae7..78620799 100644 Binary files a/js/photos-1.js.map and b/js/photos-1.js.map differ diff --git a/js/photos-10.js b/js/photos-10.js index 5c8fb30d..e096c50d 100644 Binary files a/js/photos-10.js and b/js/photos-10.js differ diff --git a/js/photos-10.js.map b/js/photos-10.js.map index 8f55223c..14dd18ba 100644 Binary files a/js/photos-10.js.map and b/js/photos-10.js.map differ diff --git a/js/photos-2.js b/js/photos-2.js index 76a869d4..f22d9c72 100644 Binary files a/js/photos-2.js and b/js/photos-2.js differ diff --git a/js/photos-2.js.map b/js/photos-2.js.map index d71f0ebd..2b1057f5 100644 Binary files a/js/photos-2.js.map and b/js/photos-2.js.map differ diff --git a/js/photos-3.js b/js/photos-3.js index cead8609..bc772213 100644 Binary files a/js/photos-3.js and b/js/photos-3.js differ diff --git a/js/photos-3.js.map b/js/photos-3.js.map index a3f3b0dd..71e913cd 100644 Binary files a/js/photos-3.js.map and b/js/photos-3.js.map differ diff --git a/js/photos-4.js b/js/photos-4.js index d9c8a96e..39880392 100644 Binary files a/js/photos-4.js and b/js/photos-4.js differ diff --git a/js/photos-4.js.map b/js/photos-4.js.map index 8dac3d91..a227b21c 100644 Binary files a/js/photos-4.js.map and b/js/photos-4.js.map differ diff --git a/js/photos-5.js b/js/photos-5.js index 75c2f1dd..fa6a3235 100644 Binary files a/js/photos-5.js and b/js/photos-5.js differ diff --git a/js/photos-5.js.map b/js/photos-5.js.map index b25f9a5e..e76cae24 100644 Binary files a/js/photos-5.js.map and b/js/photos-5.js.map differ diff --git a/js/photos-6.js b/js/photos-6.js index e001267e..e1372431 100644 Binary files a/js/photos-6.js and b/js/photos-6.js differ diff --git a/js/photos-6.js.map b/js/photos-6.js.map index 70678456..87d27763 100644 Binary files a/js/photos-6.js.map and b/js/photos-6.js.map differ diff --git a/js/photos-7.js b/js/photos-7.js index 49a63f97..5374cc2e 100644 Binary files a/js/photos-7.js and b/js/photos-7.js differ diff --git a/js/photos-7.js.map b/js/photos-7.js.map index f09260de..691483ae 100644 Binary files a/js/photos-7.js.map and b/js/photos-7.js.map differ diff --git a/js/photos-8.js b/js/photos-8.js index 1d897499..7a301332 100644 Binary files a/js/photos-8.js and b/js/photos-8.js differ diff --git a/js/photos-8.js.map b/js/photos-8.js.map index 3ca9d10e..b5cd1fc2 100644 Binary files a/js/photos-8.js.map and b/js/photos-8.js.map differ diff --git a/js/photos-9.js b/js/photos-9.js index 15b08eee..48e6aa95 100644 Binary files a/js/photos-9.js and b/js/photos-9.js differ diff --git a/js/photos-9.js.map b/js/photos-9.js.map index e99bb235..15694930 100644 Binary files a/js/photos-9.js.map and b/js/photos-9.js.map differ diff --git a/js/photos-main.js b/js/photos-main.js index dd56899e..e0685630 100644 Binary files a/js/photos-main.js and b/js/photos-main.js differ diff --git a/js/photos-main.js.map b/js/photos-main.js.map index 08dcc68e..5c87d1e6 100644 Binary files a/js/photos-main.js.map and b/js/photos-main.js.map differ diff --git a/lib/Controller/ApiController.php b/lib/Controller/ApiController.php new file mode 100644 index 00000000..84566e5c --- /dev/null +++ b/lib/Controller/ApiController.php @@ -0,0 +1,73 @@ + + * + * @author John Molakvoæ + * + * @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 . + * + */ + +namespace OCA\Photos\Controller; + +use OCA\Photos\AppInfo\Application; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\JSONResponse; +use OCP\IConfig; +use OCP\IRequest; +use OCP\IUserSession; + +class ApiController extends Controller { + + /** @var IConfig */ + private $config; + + /** @var IUserSession */ + private $userSession; + + public function __construct(IRequest $request, + IConfig $config, + IUserSession $userSession) { + parent::__construct(Application::APP_ID, $request); + + $this->config = $config; + $this->userSession = $userSession; + } + + /** + * @NoAdminRequired + * + * update preferences (user setting) + * + * @param string key the identifier to change + * @param string value the value to set + * + * @return JSONResponse an empty JSONResponse with respective http status code + */ + public function setUserConfig(string $key, string $value): JSONResponse { + $user = $this->userSession->getUser(); + if (is_null($user)) { + return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); + } + + $userId = $user->getUid(); + $this->config->setUserValue($userId, Application::APP_ID, $key, $value); + return new JSONResponse([], Http::STATUS_OK); + } +} diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 3cf92ad6..7422b56f 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -28,40 +28,45 @@ namespace OCA\Photos\Controller; use OCA\Files\Event\LoadSidebar; use OCA\Photos\AppInfo\Application; use OCA\Viewer\Event\LoadViewer; +use OCP\App\IAppManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\TemplateResponse; use OCP\EventDispatcher\IEventDispatcher; +use OCP\IConfig; use OCP\IInitialStateService; use OCP\IRequest; +use OCP\IUserSession; use OCP\Util; -use OCP\IConfig; -use OCP\App\IAppManager; class PageController extends Controller { - protected $appName; + /** @var IAppManager */ + private $appManager; /** @var IEventDispatcher */ private $eventDispatcher; + /** @var IConfig */ + private $config; + /** @var IInitialStateService */ private $initialStateService; - /** @var IAppManager */ - private $appManager; + /** @var IUserSession */ + private $userSession; - public function __construct($appName, + public function __construct(IRequest $request, IAppManager $appManager, - IRequest $request, IEventDispatcher $eventDispatcher, IConfig $config, - IInitialStateService $initialStateService) { - parent::__construct($appName, $request); + IInitialStateService $initialStateService, + IUserSession $userSession) { + parent::__construct(Application::APP_ID, $request); - $this->appName = $appName; $this->appManager = $appManager; $this->eventDispatcher = $eventDispatcher; - $this->initialStateService = $initialStateService; $this->config = $config; + $this->initialStateService = $initialStateService; + $this->userSession = $userSession; } /** @@ -72,17 +77,20 @@ class PageController extends Controller { * @return TemplateResponse */ public function index(): TemplateResponse { + $user = $this->userSession->getUser(); + $this->eventDispatcher->dispatch(LoadSidebar::class, new LoadSidebar()); $this->eventDispatcher->dispatch(LoadViewer::class, new LoadViewer()); $this->initialStateService->provideInitialState($this->appName, 'image-mimes', Application::IMAGE_MIMES); $this->initialStateService->provideInitialState($this->appName, 'video-mimes', Application::VIDEO_MIMES); $this->initialStateService->provideInitialState($this->appName, 'maps', $this->appManager->isEnabledForUser('maps') === true); + $this->initialStateService->provideInitialState($this->appName, 'croppedLayout', $this->config->getUserValue($user->getUid(), Application::APP_ID, 'croppedLayout', 'false')); - Util::addScript($this->appName, 'photos-main'); - Util::addStyle($this->appName, 'icons'); + Util::addScript(Application::APP_ID, 'photos-main'); + Util::addStyle(Application::APP_ID, 'icons'); - $response = new TemplateResponse($this->appName, 'main'); + $response = new TemplateResponse(Application::APP_ID, 'main'); return $response; } } diff --git a/package-lock.json b/package-lock.json index 942365dc..e2c4cb94 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2562,11 +2562,6 @@ "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", "dev": true }, - "@types/node": { - "version": "14.0.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.11.tgz", - "integrity": "sha512-lCvvI24L21ZVeIiyIUHZ5Oflv1hhHQ5E1S25IRlKIXaRkVgmXpJMI3wUJkmym2bTbCe+WoIibQnMVAU3FguaOg==" - }, "@types/normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", @@ -2580,12 +2575,9 @@ "dev": true }, "@types/semver": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.2.0.tgz", - "integrity": "sha512-TbB0A8ACUWZt3Y6bQPstW9QNbhNeebdgLX4T/ZfkrswAfUzRiXrgd9seol+X379Wa589Pu4UEx9Uok0D4RjRCQ==", - "requires": { - "@types/node": "*" - } + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ==" }, "@types/unist": { "version": "2.0.3", diff --git a/package.json b/package.json index a0b944ae..44556976 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "@essentials/request-timeout": "^1.3.0", "@nextcloud/auth": "^1.3.0", "@nextcloud/axios": "^1.4.0", + "@nextcloud/event-bus": "^1.2.0", "@nextcloud/initial-state": "^1.2.0", "@nextcloud/l10n": "^1.4.1", "@nextcloud/router": "^1.2.0", diff --git a/src/Photos.vue b/src/Photos.vue index d812132e..f9598fa8 100644 --- a/src/Photos.vue +++ b/src/Photos.vue @@ -39,6 +39,11 @@ :title="t('photos', 'Locations')" icon="icon-address" /> + @@ -55,23 +60,29 @@ diff --git a/src/mixins/GridConfig.js b/src/mixins/GridConfig.js index e7b18817..2663d854 100644 --- a/src/mixins/GridConfig.js +++ b/src/mixins/GridConfig.js @@ -36,7 +36,7 @@ export default { getGridConfig.$on('changed', val => { this.gridConfig = val }) - console.debug('Current grid config', getGridConfig.gridConfig) + console.debug(`[${appName}]`, 'Grid config', Object.assign({}, getGridConfig.gridConfig)) this.gridConfig = getGridConfig.gridConfig }, diff --git a/src/mixins/UserConfig.js b/src/mixins/UserConfig.js new file mode 100644 index 00000000..efa123dc --- /dev/null +++ b/src/mixins/UserConfig.js @@ -0,0 +1,64 @@ +/** + * @copyright Copyright (c) 2020 John Molakvoæ + * + * @author John Molakvoæ + * + * @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 . + * + */ + +import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus' +import { generateUrl } from '@nextcloud/router' +import { loadState } from '@nextcloud/initial-state' +import axios from '@nextcloud/axios' + +const eventName = 'photos:user-config-changed' + +export default { + data() { + const croppedLayoutLocalStorage = localStorage.getItem('photos:croppedLayout') + return { + croppedLayout: croppedLayoutLocalStorage !== null + ? croppedLayoutLocalStorage === 'true' + : loadState('photos', 'croppedLayout') === 'true', + } + }, + + created() { + subscribe(eventName, this.updateLocalSetting) + }, + + beforeDestroy() { + unsubscribe(eventName, this.updateLocalSetting) + }, + + methods: { + updateLocalSetting({ setting, value }) { + this[setting] = value + }, + updateSetting(setting) { + const value = this[setting] + // Long time save setting + axios.put(generateUrl('apps/photos/api/v1/config/' + setting), { + value: value.toString(), + }) + // Current session save setting + localStorage.setItem('photos:' + setting, value) + // Visible elements update setting + emit(eventName, { setting, value }) + }, + }, +} diff --git a/webpack.js b/webpack.js index 846a729d..3a9ad670 100644 --- a/webpack.js +++ b/webpack.js @@ -2,7 +2,7 @@ const { merge } = require('webpack-merge') const webpackConfig = require('@nextcloud/webpack-vue-config') const SassGetGridConfig = require('./src/utils/SassGetGridConfig') -const ModuleReplaceWebpackPlugin = require('module-replace-webpack-plugin'); +const ModuleReplaceWebpackPlugin = require('module-replace-webpack-plugin') const BabelLoaderExcludeNodeModulesExcept = require('babel-loader-exclude-node-modules-except') const config = {