Allow to set a primary color background
Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
parent
fa2072e36b
commit
5661775568
|
@ -29,6 +29,6 @@ return [
|
||||||
['name' => 'dashboard#index', 'url' => '/', 'verb' => 'GET'],
|
['name' => 'dashboard#index', 'url' => '/', 'verb' => 'GET'],
|
||||||
['name' => 'dashboard#updateLayout', 'url' => '/layout', 'verb' => 'POST'],
|
['name' => 'dashboard#updateLayout', 'url' => '/layout', 'verb' => 'POST'],
|
||||||
['name' => 'dashboard#getBackground', 'url' => '/background', 'verb' => 'GET'],
|
['name' => 'dashboard#getBackground', 'url' => '/background', 'verb' => 'GET'],
|
||||||
['name' => 'dashboard#setBackground', 'url' => '/background', 'verb' => 'POST'],
|
['name' => 'dashboard#setBackground', 'url' => '/background/{type}', 'verb' => 'POST'],
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
|
@ -108,6 +108,7 @@ class DashboardController extends Controller {
|
||||||
$this->inititalStateService->provideInitialState('dashboard', 'firstRun', $this->config->getUserValue($this->userId, 'dashboard', 'firstRun', '1') === '1');
|
$this->inititalStateService->provideInitialState('dashboard', 'firstRun', $this->config->getUserValue($this->userId, 'dashboard', 'firstRun', '1') === '1');
|
||||||
$this->inititalStateService->provideInitialState('dashboard', 'shippedBackgrounds', BackgroundService::SHIPPED_BACKGROUNDS);
|
$this->inititalStateService->provideInitialState('dashboard', 'shippedBackgrounds', BackgroundService::SHIPPED_BACKGROUNDS);
|
||||||
$this->inititalStateService->provideInitialState('dashboard', 'background', $this->config->getUserValue($this->userId, 'dashboard', 'background', 'default'));
|
$this->inititalStateService->provideInitialState('dashboard', 'background', $this->config->getUserValue($this->userId, 'dashboard', 'background', 'default'));
|
||||||
|
$this->inititalStateService->provideInitialState('dashboard', 'version', $this->config->getUserValue($this->userId, 'dashboard', 'backgroundVersion', 0));
|
||||||
$this->config->setUserValue($this->userId, 'dashboard', 'firstRun', '0');
|
$this->config->setUserValue($this->userId, 'dashboard', 'firstRun', '0');
|
||||||
|
|
||||||
return new TemplateResponse('dashboard', 'index');
|
return new TemplateResponse('dashboard', 'index');
|
||||||
|
@ -126,18 +127,35 @@ class DashboardController extends Controller {
|
||||||
/**
|
/**
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
*/
|
*/
|
||||||
public function setBackground($path = null, $url = null, $shipped = null): JSONResponse {
|
public function setBackground(string $type = 'default', $value): JSONResponse {
|
||||||
if ($shipped !== null) {
|
$currentVersion = $this->config->getUserValue($this->userId, 'dashboard', 'backgroundVersion', 0);
|
||||||
$this->backgroundService->setShippedBackground($shipped);
|
try {
|
||||||
} else if ($path !== null) {
|
switch ($type) {
|
||||||
$this->backgroundService->setFileBackground($path);
|
case 'shipped':
|
||||||
} else if ($url !== null) {
|
$this->backgroundService->setShippedBackground($value);
|
||||||
$this->backgroundService->setUrlBackground($url);
|
break;
|
||||||
} else {
|
case 'custom':
|
||||||
$this->backgroundService->setDefaultBackground();
|
$this->backgroundService->setFileBackground($value);
|
||||||
|
break;
|
||||||
|
case 'color':
|
||||||
|
$this->backgroundService->setColorBackground($value);
|
||||||
|
break;
|
||||||
|
case 'default':
|
||||||
|
$this->backgroundService->setDefaultBackground();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return new JSONResponse(['error' => 'Invalid type provided'], Http::STATUS_BAD_REQUEST);
|
||||||
|
}
|
||||||
|
} catch (\InvalidArgumentException $e) {
|
||||||
|
return new JSONResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
$currentVersion++;
|
||||||
return new JSONResponse([]);
|
$this->config->setUserValue($this->userId, 'dashboard', 'backgroundVersion', $currentVersion);
|
||||||
|
return new JSONResponse([
|
||||||
|
'type' => $type,
|
||||||
|
'value' => $value,
|
||||||
|
'version' => $this->config->getUserValue($this->userId, 'dashboard', 'backgroundVersion', $currentVersion)
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -74,19 +74,17 @@ class BackgroundService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setShippedBackground($fileName) {
|
public function setShippedBackground($fileName) {
|
||||||
|
if (!in_array($fileName, self::SHIPPED_BACKGROUNDS)) {
|
||||||
|
throw new \InvalidArgumentException('The given file name is invalid');
|
||||||
|
}
|
||||||
$this->config->setUserValue($this->userId, 'dashboard', 'background', $fileName);
|
$this->config->setUserValue($this->userId, 'dashboard', 'background', $fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setUrlBackground($url) {
|
public function setColorBackground(string $color) {
|
||||||
$this->config->setUserValue($this->userId, 'dashboard', 'background', 'custom');
|
if (!preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $color)) {
|
||||||
if (substr($url, 0, 1) === '/') {
|
throw new \InvalidArgumentException('The given color is invalid');
|
||||||
$url = \OC::$server->getURLGenerator()->getAbsoluteURL($url);
|
|
||||||
}
|
}
|
||||||
|
$this->config->setUserValue($this->userId, 'dashboard', 'background', $color);
|
||||||
$client = \OC::$server->getHTTPClientService()->newClient();
|
|
||||||
$response = $client->get($url);
|
|
||||||
$content = $response->getBody();
|
|
||||||
$newFile = $this->dashboardUserFolder->newFile('background.jpg', $content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBackground() {
|
public function getBackground() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="app-dashboard" :style="{ backgroundImage: `url(${backgroundImage})` }">
|
<div id="app-dashboard" :style="backgroundStyle">
|
||||||
<h2>{{ greeting.text }}</h2>
|
<h2>{{ greeting.text }}</h2>
|
||||||
<div class="statuses">
|
<div class="statuses">
|
||||||
<div v-for="status in registeredStatus"
|
<div v-for="status in registeredStatus"
|
||||||
|
@ -73,28 +73,16 @@ import { getCurrentUser } from '@nextcloud/auth'
|
||||||
import { Modal } from '@nextcloud/vue'
|
import { Modal } from '@nextcloud/vue'
|
||||||
import Draggable from 'vuedraggable'
|
import Draggable from 'vuedraggable'
|
||||||
import axios from '@nextcloud/axios'
|
import axios from '@nextcloud/axios'
|
||||||
import { generateUrl, generateFilePath } from '@nextcloud/router'
|
import { generateUrl } from '@nextcloud/router'
|
||||||
import isMobile from './mixins/isMobile'
|
import isMobile from './mixins/isMobile'
|
||||||
import BackgroundSettings from './components/BackgroundSettings'
|
import BackgroundSettings from './components/BackgroundSettings'
|
||||||
|
import getBackgroundUrl from './helpers/getBackgroundUrl'
|
||||||
|
import prefixWithBaseUrl from './helpers/prefixWithBaseUrl'
|
||||||
|
|
||||||
const panels = loadState('dashboard', 'panels')
|
const panels = loadState('dashboard', 'panels')
|
||||||
const firstRun = loadState('dashboard', 'firstRun')
|
const firstRun = loadState('dashboard', 'firstRun')
|
||||||
const background = loadState('dashboard', 'background')
|
const background = loadState('dashboard', 'background')
|
||||||
|
const version = loadState('dashboard', 'version')
|
||||||
const prefixWithBaseUrl = (url) => generateFilePath('dashboard', '', 'img/') + url
|
|
||||||
|
|
||||||
// FIXME: move out duplicate
|
|
||||||
const getBackgroundUrl = (background, time = 0) => {
|
|
||||||
if (background === 'default') {
|
|
||||||
if (window.OCA.Accessibility.theme === 'dark') {
|
|
||||||
return prefixWithBaseUrl('eduardo-neves-pedra-azul.jpg')
|
|
||||||
}
|
|
||||||
return prefixWithBaseUrl('kamil-porembinski-clouds.jpg')
|
|
||||||
} else if (background === 'custom') {
|
|
||||||
return generateUrl('/apps/dashboard/background') + '?v=' + time
|
|
||||||
}
|
|
||||||
return prefixWithBaseUrl(background)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
|
@ -121,13 +109,21 @@ export default {
|
||||||
appStoreUrl: generateUrl('/settings/apps/dashboard'),
|
appStoreUrl: generateUrl('/settings/apps/dashboard'),
|
||||||
statuses: {},
|
statuses: {},
|
||||||
background,
|
background,
|
||||||
backgroundTime: Date.now(),
|
version,
|
||||||
defaultBackground: window.OCA.Accessibility.theme === 'dark' ? prefixWithBaseUrl('flickr-148302424@N05-36591009215.jpg?v=1') : prefixWithBaseUrl('flickr-paszczak000-8715851521.jpg?v=1'),
|
defaultBackground: window.OCA.Accessibility.theme === 'dark' ? prefixWithBaseUrl('flickr-148302424@N05-36591009215.jpg?v=1') : prefixWithBaseUrl('flickr-paszczak000-8715851521.jpg?v=1'),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
backgroundImage() {
|
backgroundImage() {
|
||||||
return getBackgroundUrl(this.background, this.backgroundTime)
|
return getBackgroundUrl(this.background, this.version)
|
||||||
|
},
|
||||||
|
backgroundStyle() {
|
||||||
|
if (this.background.match(/#[0-9A-Fa-f]{6}/g)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
backgroundImage: `url(${this.backgroundImage})`,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
tooltip() {
|
tooltip() {
|
||||||
if (!this.firstRun) {
|
if (!this.firstRun) {
|
||||||
|
@ -269,8 +265,9 @@ export default {
|
||||||
this.firstRun = false
|
this.firstRun = false
|
||||||
}, 1000)
|
}, 1000)
|
||||||
},
|
},
|
||||||
updateBackground(backgroundType) {
|
updateBackground(data) {
|
||||||
this.background = backgroundType
|
this.background = data.type === 'custom' || data.type === 'default' ? data.type : data.value
|
||||||
|
this.version = data.version
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,15 @@
|
||||||
{{ t('dashboard', 'Default images') }}
|
{{ t('dashboard', 'Default images') }}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
<a class="background color"
|
||||||
|
tabindex="0"
|
||||||
|
@click="pickColor"
|
||||||
|
@keyup.enter="pickColor"
|
||||||
|
@keyup.space="pickColor">
|
||||||
|
<div class="background--preview">
|
||||||
|
{{ t('dashboard', 'Plain background') }}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
<a v-for="background in shippedBackgrounds"
|
<a v-for="background in shippedBackgrounds"
|
||||||
:key="background.name"
|
:key="background.name"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
|
@ -56,24 +65,12 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from '@nextcloud/axios'
|
import axios from '@nextcloud/axios'
|
||||||
import { generateUrl, generateFilePath } from '@nextcloud/router'
|
import { generateUrl } from '@nextcloud/router'
|
||||||
import { loadState } from '@nextcloud/initial-state'
|
import { loadState } from '@nextcloud/initial-state'
|
||||||
|
import getBackgroundUrl from './../helpers/getBackgroundUrl'
|
||||||
const prefixWithBaseUrl = (url) => generateFilePath('dashboard', '', 'img/') + url
|
import prefixWithBaseUrl from './../helpers/prefixWithBaseUrl'
|
||||||
const shippedBackgroundList = loadState('dashboard', 'shippedBackgrounds')
|
const shippedBackgroundList = loadState('dashboard', 'shippedBackgrounds')
|
||||||
|
|
||||||
const getBackgroundUrl = (background, time = 0) => {
|
|
||||||
if (background === 'default') {
|
|
||||||
if (window.OCA.Accessibility.theme === 'dark') {
|
|
||||||
return prefixWithBaseUrl('eduardo-neves-pedra-azul.jpg')
|
|
||||||
}
|
|
||||||
return prefixWithBaseUrl('kamil-porembinski-clouds.jpg')
|
|
||||||
} else if (background === 'custom') {
|
|
||||||
return generateUrl('/apps/dashboard/background') + '?v=' + time
|
|
||||||
}
|
|
||||||
return prefixWithBaseUrl(background)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'BackgroundSettings',
|
name: 'BackgroundSettings',
|
||||||
data() {
|
data() {
|
||||||
|
@ -93,35 +90,36 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async update(state) {
|
async update(data) {
|
||||||
const date = Date.now()
|
const background = data.type === 'custom' || data.type === 'default' ? data.type : data.value
|
||||||
this.backgroundImage = getBackgroundUrl(state, date)
|
this.backgroundImage = getBackgroundUrl(background, data.version)
|
||||||
const image = new Image()
|
const image = new Image()
|
||||||
image.onload = () => {
|
image.onload = () => {
|
||||||
this.$emit('updateBackground', state)
|
this.$emit('updateBackground', data)
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}
|
}
|
||||||
image.src = this.backgroundImage
|
image.src = this.backgroundImage
|
||||||
},
|
},
|
||||||
async setDefault() {
|
async setDefault() {
|
||||||
console.debug('SetDefault')
|
this.loading = 'default'
|
||||||
await axios.post(generateUrl('/apps/dashboard/background'))
|
const result = await axios.post(generateUrl('/apps/dashboard/background/default'))
|
||||||
this.update('default')
|
this.update(result.data)
|
||||||
},
|
},
|
||||||
async setShipped(shipped) {
|
async setShipped(shipped) {
|
||||||
this.loading = shipped
|
this.loading = shipped
|
||||||
await axios.post(generateUrl('/apps/dashboard/background'), { shipped })
|
const result = await axios.post(generateUrl('/apps/dashboard/background/shipped'), { value: shipped })
|
||||||
this.update(shipped)
|
this.update(result.data)
|
||||||
},
|
|
||||||
async setUrl(url) {
|
|
||||||
this.loading = true
|
|
||||||
await axios.post(generateUrl('/apps/dashboard/background'), { url })
|
|
||||||
this.update('custom')
|
|
||||||
},
|
},
|
||||||
async setFile(path) {
|
async setFile(path) {
|
||||||
this.loading = true
|
this.loading = 'custom'
|
||||||
await axios.post(generateUrl('/apps/dashboard/background'), { path })
|
const result = await axios.post(generateUrl('/apps/dashboard/background/custom'), { value: path })
|
||||||
this.update('custom')
|
this.update(result.data)
|
||||||
|
},
|
||||||
|
async pickColor() {
|
||||||
|
this.loading = 'color'
|
||||||
|
const color = OCA && OCA.Theming ? OCA.Theming.color : '#0082c9'
|
||||||
|
const result = await axios.post(generateUrl('/apps/dashboard/background/color'), { value: color })
|
||||||
|
this.update(result.data)
|
||||||
},
|
},
|
||||||
pickFile() {
|
pickFile() {
|
||||||
window.OC.dialogs.filepicker(t('dashboard', 'Insert from {productName}', { productName: OC.theme.name }), (path, type) => {
|
window.OC.dialogs.filepicker(t('dashboard', 'Insert from {productName}', { productName: OC.theme.name }), (path, type) => {
|
||||||
|
@ -161,13 +159,18 @@ export default {
|
||||||
background-position: center center;
|
background-position: center center;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.filepicker, &.default {
|
&.filepicker, &.default, &.color {
|
||||||
border: 2px solid var(--color-border);
|
border: 2px solid var(--color-border);
|
||||||
.background--preview {
|
.background--preview {
|
||||||
line-height: 100px;
|
line-height: 100px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.color .background--preview {
|
||||||
|
background-color: var(--color-primary);
|
||||||
|
color: var(--color-primary-text);
|
||||||
|
}
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
border: 2px solid var(--color-primary);
|
border: 2px solid var(--color-primary);
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>
|
||||||
|
*
|
||||||
|
* @author Julius Härtl <jus@bitgrid.net>
|
||||||
|
*
|
||||||
|
* @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 { generateUrl } from '@nextcloud/router'
|
||||||
|
import prefixWithBaseUrl from './prefixWithBaseUrl'
|
||||||
|
|
||||||
|
export default (background, time = 0) => {
|
||||||
|
if (background === 'default') {
|
||||||
|
if (window.OCA.Accessibility.theme === 'dark') {
|
||||||
|
return prefixWithBaseUrl('eduardo-neves-pedra-azul.jpg')
|
||||||
|
}
|
||||||
|
return prefixWithBaseUrl('kamil-porembinski-clouds.jpg')
|
||||||
|
} else if (background === 'custom') {
|
||||||
|
return generateUrl('/apps/dashboard/background') + '?v=' + time
|
||||||
|
}
|
||||||
|
return prefixWithBaseUrl(background)
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>
|
||||||
|
*
|
||||||
|
* @author Julius Härtl <jus@bitgrid.net>
|
||||||
|
*
|
||||||
|
* @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 { generateFilePath } from '@nextcloud/router'
|
||||||
|
|
||||||
|
export default (url) => generateFilePath('dashboard', '', 'img/') + url
|
Loading…
Reference in New Issue