fixes #1759: Use InitialState service

Signed-off-by: Georg Ehrke <developer@georgehrke.com>
This commit is contained in:
Georg Ehrke 2020-02-24 13:25:11 +01:00
parent 3c2910f3b2
commit cc171a31ce
No known key found for this signature in database
GPG Key ID: 9D98FD9380A1CB43
12 changed files with 204 additions and 111 deletions

View File

@ -25,6 +25,7 @@ namespace OCA\Calendar\Controller;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IConfig;
use OCP\IInitialStateService;
use OCP\IRequest;
use OCP\IURLGenerator;
@ -40,6 +41,11 @@ class PublicViewController extends Controller {
*/
private $config;
/**
* @var IInitialStateService
*/
private $initialStateService;
/**
* @var IURLGenerator
*/
@ -49,14 +55,17 @@ class PublicViewController extends Controller {
* @param string $appName
* @param IRequest $request an instance of the request
* @param IConfig $config
* @param IInitialStateService $initialStateService
* @param IURLGenerator $urlGenerator
*/
public function __construct(string $appName,
IRequest $request,
IConfig $config,
IInitialStateService $initialStateService,
IURLGenerator $urlGenerator) {
parent::__construct($appName, $request);
$this->config = $config;
$this->initialStateService = $initialStateService;
$this->urlGenerator = $urlGenerator;
}
@ -103,15 +112,18 @@ class PublicViewController extends Controller {
$defaultSkipPopover = $this->config->getAppValue($this->appName, 'skipPopover', 'yes');
$defaultTimezone = $this->config->getAppValue($this->appName, 'timezone', 'automatic');
$appVersion = $this->config->getAppValue($this->appName, 'installed_version');
$this->initialStateService->provideInitialState($this->appName, 'app_version', $appVersion);
$this->initialStateService->provideInitialState($this->appName, 'first_run', false);
$this->initialStateService->provideInitialState($this->appName, 'initial_view', $defaultInitialView);
$this->initialStateService->provideInitialState($this->appName, 'show_weekends', ($defaultShowWeekends === 'yes'));
$this->initialStateService->provideInitialState($this->appName, 'show_week_numbers', ($defaultWeekNumbers === 'yes'));
$this->initialStateService->provideInitialState($this->appName, 'skip_popover', ($defaultSkipPopover === 'yes'));
$this->initialStateService->provideInitialState($this->appName, 'talk_enabled', false);
$this->initialStateService->provideInitialState($this->appName, 'timezone', $defaultTimezone);
return new TemplateResponse($this->appName, 'main', [
'app_version' => $this->config->getAppValue($this->appName, 'installed_version'),
'first_run' => false,
'initial_view' => $defaultInitialView,
'show_weekends' => ($defaultShowWeekends === 'yes'),
'show_week_numbers' => ($defaultWeekNumbers === 'yes'),
'skip_popover' => ($defaultSkipPopover === 'yes'),
'talk_enabled' => false,
'timezone' => $defaultTimezone,
'share_url' => $this->getShareURL(),
'preview_image' => $this->getPreviewImage(),
], $renderAs);

View File

@ -26,6 +26,7 @@ use OCP\App\IAppManager;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IConfig;
use OCP\IInitialStateService;
use OCP\IRequest;
/**
@ -45,6 +46,11 @@ class ViewController extends Controller {
*/
private $userId;
/**
* @var IInitialStateService
*/
private $initialStateService;
/**
* @var IAppManager
*/
@ -53,18 +59,21 @@ class ViewController extends Controller {
/**
* @param string $appName
* @param IRequest $request an instance of the request
* @param IAppManager $appManager
* @param IConfig $config
* @param IInitialStateService $initialStateService
* @param IAppManager $appManager
* @param string $userId
*/
public function __construct(string $appName,
IRequest $request,
IConfig $config,
IInitialStateService $initialStateService,
IAppManager $appManager,
?string $userId) {
parent::__construct($appName, $request);
$this->config = $config;
$this->userId = $userId;
$this->initialStateService = $initialStateService;
$this->appManager = $appManager;
}
@ -83,16 +92,25 @@ class ViewController extends Controller {
$defaultSkipPopover = $this->config->getAppValue($this->appName, 'skipPopover', 'no');
$defaultTimezone = $this->config->getAppValue($this->appName, 'timezone', 'automatic');
return new TemplateResponse($this->appName, 'main', [
'app_version' => $this->config->getAppValue($this->appName, 'installed_version'),
'first_run' => $this->config->getUserValue($this->userId, $this->appName, 'firstRun', 'yes') === 'yes',
'initial_view' => $this->getView($this->config->getUserValue($this->userId, $this->appName, 'currentView', $defaultInitialView)),
'show_weekends' => $this->config->getUserValue($this->userId, $this->appName, 'showWeekends', $defaultShowWeekends) === 'yes',
'show_week_numbers' => $this->config->getUserValue($this->userId, $this->appName, 'showWeekNr', $defaultWeekNumbers) === 'yes',
'skip_popover' => $this->config->getUserValue($this->userId, $this->appName, 'skipPopover', $defaultSkipPopover) === 'yes',
'talk_enabled' => $this->appManager->isEnabledForUser('spreed'),
'timezone' => $this->config->getUserValue($this->userId, $this->appName, 'timezone', $defaultTimezone),
]);
$appVersion = $this->config->getAppValue($this->appName, 'installed_version');
$firstRun = $this->config->getUserValue($this->userId, $this->appName, 'firstRun', 'yes') === 'yes';
$initialView = $this->getView($this->config->getUserValue($this->userId, $this->appName, 'currentView', $defaultInitialView));
$showWeekends = $this->config->getUserValue($this->userId, $this->appName, 'showWeekends', $defaultShowWeekends) === 'yes';
$showWeekNumbers = $this->config->getUserValue($this->userId, $this->appName, 'showWeekNr', $defaultWeekNumbers) === 'yes';
$skipPopover = $this->config->getUserValue($this->userId, $this->appName, 'skipPopover', $defaultSkipPopover) === 'yes';
$talkEnabled = $this->appManager->isEnabledForUser('spreed');
$timezone = $this->config->getUserValue($this->userId, $this->appName, 'timezone', $defaultTimezone);
$this->initialStateService->provideInitialState($this->appName, 'app_version', $appVersion);
$this->initialStateService->provideInitialState($this->appName, 'first_run', $firstRun);
$this->initialStateService->provideInitialState($this->appName, 'initial_view', $initialView);
$this->initialStateService->provideInitialState($this->appName, 'show_weekends', $showWeekends);
$this->initialStateService->provideInitialState($this->appName, 'show_week_numbers', $showWeekNumbers);
$this->initialStateService->provideInitialState($this->appName, 'skip_popover', $skipPopover);
$this->initialStateService->provideInitialState($this->appName, 'talk_enabled', $talkEnabled);
$this->initialStateService->provideInitialState($this->appName, 'timezone', $timezone);
return new TemplateResponse($this->appName, 'main');
}
/**

19
package-lock.json generated
View File

@ -4134,6 +4134,21 @@
}
}
},
"@nextcloud/initial-state": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@nextcloud/initial-state/-/initial-state-1.1.0.tgz",
"integrity": "sha512-c8VNSv7CbcPdaMNQO3ERJUMhsGyCvAgSBlvBHhugYHxGqlySjE+J+SqkpXmqB+eQ/DujDTahBX1IwoF3zjPtOw==",
"requires": {
"core-js": "3.6.1"
},
"dependencies": {
"core-js": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.1.tgz",
"integrity": "sha512-186WjSik2iTGfDjfdCZAxv2ormxtKgemjC3SI6PL31qOA0j5LhTDVjHChccoc7brwLvpvLPiMyRlcO88C4l1QQ=="
}
}
},
"@nextcloud/l10n": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@nextcloud/l10n/-/l10n-1.1.0.tgz",
@ -6293,7 +6308,7 @@
},
"calendar-js": {
"version": "git+https://github.com/georgehrke/calendar-js.git#7cc5d3b4d2e8903d2ae1aefe122903d9797fc5f6",
"from": "git+https://github.com/georgehrke/calendar-js.git#7cc5d3b4d2e8903d2ae1aefe122903d9797fc5f6",
"from": "git+https://github.com/georgehrke/calendar-js.git",
"requires": {
"ical.js": "^1.3.0",
"uuid": "^3.4.0"
@ -6364,7 +6379,7 @@
},
"cdav-library": {
"version": "github:nextcloud/cdav-library#5147f253d6f244daa9612bdadeafaa216b434069",
"from": "github:nextcloud/cdav-library#5147f253d6f244daa9612bdadeafaa216b434069",
"from": "github:nextcloud/cdav-library",
"requires": {
"core-js": "^3.6.4",
"regenerator-runtime": "^0.13.3"

View File

@ -44,6 +44,7 @@
"@fullcalendar/vue": "^4.4.0",
"@nextcloud/auth": "^1.2.1",
"@nextcloud/axios": "^1.3.1",
"@nextcloud/initial-state": "^1.1.0",
"@nextcloud/l10n": "^1.1.0",
"@nextcloud/logger": "^1.1.1",
"@nextcloud/moment": "^1.1.0",

View File

@ -1,5 +1,5 @@
/**
* @copyright Copyright (c) 2019 Georg Ehrke
* @copyright Copyright (c) 2020 Georg Ehrke
* @author Georg Ehrke <oc.list@georgehrke.com>
*
* @license GNU AGPL version 3 or any later version
@ -18,8 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { getConfigValueFromHiddenInput } from './settings.js'
import { loadState } from '@nextcloud/initial-state'
/**
* Gets the initial view
@ -27,7 +26,11 @@ import { getConfigValueFromHiddenInput } from './settings.js'
* @returns {String}
*/
export function getInitialView() {
return getConfigValueFromHiddenInput('initial-view') || 'dayGridMonth'
try {
return loadState('calendar', 'initial_view')
} catch (error) {
return 'dayGridMonth'
}
}
/**

View File

@ -21,17 +21,6 @@
*/
import { linkTo } from '@nextcloud/router'
/**
* Reads config value from hidden input field
*
* @param {string} key Key to query for
* @returns {String|null}
*/
export function getConfigValueFromHiddenInput(key) {
const elem = document.getElementById('config-' + key)
return elem ? elem.value : null
}
/**
* Get URL to modify config-key
*

View File

@ -98,7 +98,6 @@ import { Content } from '@nextcloud/vue/dist/Components/Content'
import debounce from 'debounce'
import { uidToHexColor } from '../utils/color.js'
import client from '../services/caldavService.js'
import { getConfigValueFromHiddenInput } from '../utils/settings.js'
import {
dateFactory,
getUnixTimestampFromDate,
@ -130,6 +129,7 @@ import loadMomentLocalization from '../utils/moment.js'
import eventLimitText from '../fullcalendar/eventLimitText.js'
import windowResize from '../fullcalendar/windowResize.js'
import dayRender from '../fullcalendar/dayRender.js'
import { loadState } from '@nextcloud/initial-state'
export default {
name: 'Calendar',
@ -291,13 +291,13 @@ export default {
},
async beforeMount() {
this.$store.commit('loadSettingsFromServer', {
appVersion: getConfigValueFromHiddenInput('app-version'),
firstRun: getConfigValueFromHiddenInput('first-run') === 'true',
showWeekends: getConfigValueFromHiddenInput('show-weekends') === 'true',
showWeekNumbers: getConfigValueFromHiddenInput('show-week-numbers') === 'true',
skipPopover: getConfigValueFromHiddenInput('skip-popover') === 'true',
talkEnabled: getConfigValueFromHiddenInput('talk-enabled') === 'true',
timezone: getConfigValueFromHiddenInput('timezone'),
appVersion: loadState('calendar', 'app_version'),
firstRun: loadState('calendar', 'first_run'),
showWeekends: loadState('calendar', 'show_weekends'),
showWeekNumbers: loadState('calendar', 'show_week_numbers'),
skipPopover: loadState('calendar', 'skip_popover'),
talkEnabled: loadState('calendar', 'talk_enabled'),
timezone: loadState('calendar', 'timezone'),
})
this.$store.dispatch('initializeCalendarJsConfig')

View File

@ -21,13 +21,3 @@
*/
script('calendar', 'calendar');
style('calendar', 'calendar');
?>
<input type="hidden" id="config-app-version" value="<?php p($_['app_version']); ?>">
<input type="hidden" id="config-first-run" value="<?php p($_['first_run'] ? 'true' : 'false'); ?>">
<input type="hidden" id="config-initial-view" value="<?php p($_['initial_view']); ?>">
<input type="hidden" id="config-show-weekends" value="<?php p($_['show_weekends'] ? 'true' : 'false'); ?>">
<input type="hidden" id="config-show-week-numbers" value="<?php p($_['show_week_numbers'] ? 'true' : 'false'); ?>">
<input type="hidden" id="config-skip-popover" value="<?php p($_['skip_popover'] ? 'true' : 'false'); ?>">
<input type="hidden" id="config-talk-enabled" value="<?php p($_['talk_enabled'] ? 'true' : 'false'); ?>">
<input type="hidden" id="config-timezone" value="<?php p($_['timezone']); ?>">

View File

@ -23,23 +23,23 @@ import {
getInitialView,
getPrefixedRoute
} from '../../../../src/utils/router.js'
import * as settingsUtil from '../../../../src/utils/settings.js'
import { loadState } from '@nextcloud/initial-state'
jest.mock('../../../../src/utils/settings.js')
jest.mock('@nextcloud/initial-state')
describe('utils/router test suite', () => {
it('should get the initial view', () => {
settingsUtil.getConfigValueFromHiddenInput
loadState
.mockReturnValueOnce('dayGridView')
.mockReturnValueOnce(null)
.mockImplementationOnce(() => { throw new Error() })
expect(getInitialView()).toEqual('dayGridView')
expect(getInitialView()).toEqual('dayGridMonth')
expect(settingsUtil.getConfigValueFromHiddenInput.mock.calls.length).toEqual(2)
expect(settingsUtil.getConfigValueFromHiddenInput.mock.calls[0]).toEqual(['initial-view'])
expect(settingsUtil.getConfigValueFromHiddenInput.mock.calls[1]).toEqual(['initial-view'])
expect(loadState).toHaveBeenCalledTimes(2)
expect(loadState).toHaveBeenNthCalledWith(1, 'calendar', 'initial_view')
expect(loadState).toHaveBeenNthCalledWith(2, 'calendar', 'initial_view')
})
it('should provide the prefixed route name to navigate to', () => {

View File

@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { getConfigValueFromHiddenInput, getLinkToConfig } from '../../../../src/utils/settings.js'
import { getLinkToConfig } from '../../../../src/utils/settings.js'
import { linkTo } from '@nextcloud/router'
jest.mock('@nextcloud/router')
@ -29,17 +29,6 @@ describe('utils/settings test suite', () => {
linkTo.mockClear()
})
it('should read a config value from DOM', () => {
document.body.innerHTML = `
<input id="config-first-day" value="1" />
<input id="config-show-weekends" value="0" />
`
expect(getConfigValueFromHiddenInput('first-day')).toEqual('1')
expect(getConfigValueFromHiddenInput('show-weekends')).toEqual('0')
expect(getConfigValueFromHiddenInput('show-week-numbers')).toEqual(null)
})
it('should generate a link to the config api', () => {
linkTo.mockImplementation(() => 'baseurl:')

View File

@ -24,6 +24,7 @@ namespace OCA\Calendar\Controller;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IConfig;
use OCP\IInitialStateService;
use OCP\IRequest;
use OCP\IURLGenerator;
use ChristophWurst\Nextcloud\Testing\TestCase;
@ -39,6 +40,9 @@ class PublicViewControllerTest extends TestCase {
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
private $config;
/** @var IInitialStateService|\PHPUnit_Framework_MockObject_MockObject */
private $initialStateService;
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
private $urlGenerator;
@ -49,10 +53,11 @@ class PublicViewControllerTest extends TestCase {
$this->appName = 'calendar';
$this->request = $this->createMock(IRequest::class);
$this->config = $this->createMock(IConfig::class);
$this->initialStateService = $this->createMock(IInitialStateService::class);
$this->urlGenerator = $this->createMock(IURLGenerator::class);
$this->controller = new PublicViewController($this->appName, $this->request,
$this->config, $this->urlGenerator);
$this->config, $this->initialStateService, $this->urlGenerator);
}
public function testPublicIndexWithBranding():void {
@ -104,18 +109,35 @@ class PublicViewControllerTest extends TestCase {
->with('imagePath456')
->willReturn('absoluteImagePath456');
$this->initialStateService->expects($this->at(0))
->method('provideInitialState')
->with('calendar', 'app_version', '1.0.0');
$this->initialStateService->expects($this->at(1))
->method('provideInitialState')
->with('calendar', 'first_run', false);
$this->initialStateService->expects($this->at(2))
->method('provideInitialState')
->with('calendar', 'initial_view', 'defaultCurrentView');
$this->initialStateService->expects($this->at(3))
->method('provideInitialState')
->with('calendar', 'show_weekends', false);
$this->initialStateService->expects($this->at(4))
->method('provideInitialState')
->with('calendar', 'show_week_numbers', true);
$this->initialStateService->expects($this->at(5))
->method('provideInitialState')
->with('calendar', 'skip_popover', true);
$this->initialStateService->expects($this->at(6))
->method('provideInitialState')
->with('calendar', 'talk_enabled', false);
$this->initialStateService->expects($this->at(7))
->method('provideInitialState')
->with('calendar', 'timezone', 'defaultTimezone');
$response = $this->controller->publicIndexWithBranding('');
$this->assertInstanceOf(TemplateResponse::class, $response);
$this->assertEquals([
'app_version' => '1.0.0',
'first_run' => false,
'initial_view' => 'defaultCurrentView',
'show_weekends' => false,
'show_week_numbers' => true,
'skip_popover' => true,
'talk_enabled' => false,
'timezone' => 'defaultTimezone',
'share_url' => 'protocol://host123/456',
'preview_image' => 'absoluteImagePath456'
], $response->getParams());
@ -172,18 +194,35 @@ class PublicViewControllerTest extends TestCase {
->with('imagePath456')
->willReturn('absoluteImagePath456');
$this->initialStateService->expects($this->at(0))
->method('provideInitialState')
->with('calendar', 'app_version', '1.0.0');
$this->initialStateService->expects($this->at(1))
->method('provideInitialState')
->with('calendar', 'first_run', false);
$this->initialStateService->expects($this->at(2))
->method('provideInitialState')
->with('calendar', 'initial_view', 'defaultCurrentView');
$this->initialStateService->expects($this->at(3))
->method('provideInitialState')
->with('calendar', 'show_weekends', false);
$this->initialStateService->expects($this->at(4))
->method('provideInitialState')
->with('calendar', 'show_week_numbers', true);
$this->initialStateService->expects($this->at(5))
->method('provideInitialState')
->with('calendar', 'skip_popover', true);
$this->initialStateService->expects($this->at(6))
->method('provideInitialState')
->with('calendar', 'talk_enabled', false);
$this->initialStateService->expects($this->at(7))
->method('provideInitialState')
->with('calendar', 'timezone', 'defaultTimezone');
$response = $this->controller->publicIndexForEmbedding('');
$this->assertInstanceOf(TemplateResponse::class, $response);
$this->assertEquals([
'app_version' => '1.0.0',
'first_run' => false,
'initial_view' => 'defaultCurrentView',
'show_weekends' => false,
'show_week_numbers' => true,
'skip_popover' => true,
'talk_enabled' => false,
'timezone' => 'defaultTimezone',
'share_url' => 'protocol://host123/456',
'preview_image' => 'absoluteImagePath456'
], $response->getParams());

View File

@ -25,6 +25,7 @@ namespace OCA\Calendar\Controller;
use OCP\App\IAppManager;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IConfig;
use OCP\IInitialStateService;
use OCP\IRequest;
use ChristophWurst\Nextcloud\Testing\TestCase;
@ -42,6 +43,9 @@ class ViewControllerTest extends TestCase {
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
private $config;
/** @var IInitialStateService|\PHPUnit_Framework_MockObject_MockObject */
private $initialStateService;
/** @var string */
private $userId;
@ -53,10 +57,11 @@ class ViewControllerTest extends TestCase {
$this->request = $this->createMock(IRequest::class);
$this->appManager = $this->createMock(IAppManager::class);
$this->config = $this->createMock(IConfig::class);
$this->initialStateService = $this->createMock(IInitialStateService::class);
$this->userId = 'user123';
$this->controller = new ViewController($this->appName, $this->request,
$this->config, $this->appManager, $this->userId);
$this->config, $this->initialStateService, $this->appManager, $this->userId);
}
public function testIndex():void {
@ -114,19 +119,35 @@ class ViewControllerTest extends TestCase {
->with('spreed')
->willReturn(true);
$this->initialStateService->expects($this->at(0))
->method('provideInitialState')
->with('calendar', 'app_version', '1.0.0');
$this->initialStateService->expects($this->at(1))
->method('provideInitialState')
->with('calendar', 'first_run', true);
$this->initialStateService->expects($this->at(2))
->method('provideInitialState')
->with('calendar', 'initial_view', 'timeGridWeek');
$this->initialStateService->expects($this->at(3))
->method('provideInitialState')
->with('calendar', 'show_weekends', true);
$this->initialStateService->expects($this->at(4))
->method('provideInitialState')
->with('calendar', 'show_week_numbers', true);
$this->initialStateService->expects($this->at(5))
->method('provideInitialState')
->with('calendar', 'skip_popover', true);
$this->initialStateService->expects($this->at(6))
->method('provideInitialState')
->with('calendar', 'talk_enabled', true);
$this->initialStateService->expects($this->at(7))
->method('provideInitialState')
->with('calendar', 'timezone', 'Europe/Berlin');
$response = $this->controller->index();
$this->assertInstanceOf(TemplateResponse::class, $response);
$this->assertEquals([
'app_version' => '1.0.0',
'first_run' => true,
'initial_view' => 'timeGridWeek',
'show_weekends' => true,
'show_week_numbers' => true,
'skip_popover' => true,
'talk_enabled' => true,
'timezone' => 'Europe/Berlin',
], $response->getParams());
$this->assertEquals([], $response->getParams());
$this->assertEquals('user', $response->getRenderAs());
$this->assertEquals('main', $response->getTemplateName());
}
@ -192,19 +213,35 @@ class ViewControllerTest extends TestCase {
->with('spreed')
->willReturn(true);
$this->initialStateService->expects($this->at(0))
->method('provideInitialState')
->with('calendar', 'app_version', '1.0.0');
$this->initialStateService->expects($this->at(1))
->method('provideInitialState')
->with('calendar', 'first_run', true);
$this->initialStateService->expects($this->at(2))
->method('provideInitialState')
->with('calendar', 'initial_view', $expectedView);
$this->initialStateService->expects($this->at(3))
->method('provideInitialState')
->with('calendar', 'show_weekends', true);
$this->initialStateService->expects($this->at(4))
->method('provideInitialState')
->with('calendar', 'show_week_numbers', true);
$this->initialStateService->expects($this->at(5))
->method('provideInitialState')
->with('calendar', 'skip_popover', true);
$this->initialStateService->expects($this->at(6))
->method('provideInitialState')
->with('calendar', 'talk_enabled', true);
$this->initialStateService->expects($this->at(7))
->method('provideInitialState')
->with('calendar', 'timezone', 'Europe/Berlin');
$response = $this->controller->index();
$this->assertInstanceOf(TemplateResponse::class, $response);
$this->assertEquals([
'app_version' => '1.0.0',
'first_run' => true,
'initial_view' => $expectedView,
'show_weekends' => true,
'show_week_numbers' => true,
'skip_popover' => true,
'talk_enabled' => true,
'timezone' => 'Europe/Berlin',
], $response->getParams());
$this->assertEquals([], $response->getParams());
$this->assertEquals('user', $response->getRenderAs());
$this->assertEquals('main', $response->getTemplateName());
}