Signed-off-by: Julius Härtl <jus@bitgrid.net>tags/v20.0.0beta1
@@ -33,11 +33,13 @@ use OCP\AppFramework\Controller; | |||
use OCP\AppFramework\Http; | |||
use OCP\AppFramework\Http\FileDisplayResponse; | |||
use OCP\AppFramework\Http\JSONResponse; | |||
use OCP\AppFramework\Http\NotFoundResponse; | |||
use OCP\AppFramework\Http\TemplateResponse; | |||
use OCP\Dashboard\IManager; | |||
use OCP\Dashboard\IWidget; | |||
use OCP\Dashboard\RegisterWidgetEvent; | |||
use OCP\EventDispatcher\IEventDispatcher; | |||
use OCP\Files\NotFoundException; | |||
use OCP\IConfig; | |||
use OCP\IInitialStateService; | |||
use OCP\IRequest; | |||
@@ -105,6 +107,7 @@ class DashboardController extends Controller { | |||
$this->inititalStateService->provideInitialState('dashboard', 'layout', $userLayout); | |||
$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', 'background', $this->config->getUserValue($this->userId, 'dashboard', 'background', 'default')); | |||
$this->config->setUserValue($this->userId, 'dashboard', 'firstRun', '0'); | |||
return new TemplateResponse('dashboard', 'index'); | |||
@@ -123,16 +126,20 @@ class DashboardController extends Controller { | |||
/** | |||
* @NoAdminRequired | |||
*/ | |||
public function setBackground($path = null, $url = null): JSONResponse { | |||
public function setBackground($path = null, $url = null, $shipped = null): JSONResponse { | |||
// FIXME: store current version of the background and return the result | |||
// FIXME: handle shipped backgrounds avoid file duplication | |||
// FIXME: allow to reset to default ones | |||
if ($shipped !== null) { | |||
$this->backgroundService->setShippedBackground($shipped); | |||
} | |||
if ($path !== null) { | |||
$this->backgroundService->setFileBackground($path); | |||
} | |||
if ($url !== null) { | |||
$this->backgroundService->setUrlBackground($url); | |||
} | |||
$this->backgroundService->setDefaultBackground(); | |||
return new JSONResponse([]); | |||
} | |||
@@ -140,9 +147,13 @@ class DashboardController extends Controller { | |||
* @NoAdminRequired | |||
* @NoCSRFRequired | |||
*/ | |||
public function getBackground(): FileDisplayResponse { | |||
public function getBackground() { | |||
$file = $this->backgroundService->getBackground(); | |||
$response = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => $file->getMimeType()]); | |||
return $response; | |||
if ($file !== null) { | |||
$response = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => $file->getMimeType()]); | |||
$response->cacheFor(24 * 60 * 60); | |||
return $response; | |||
} | |||
return new NotFoundResponse(); | |||
} | |||
} |
@@ -32,6 +32,7 @@ use OCP\Files\IAppData; | |||
use OCP\Files\IRootFolder; | |||
use OCP\Files\NotFoundException; | |||
use OCP\Files\SimpleFS\ISimpleFile; | |||
use OCP\IConfig; | |||
class BackgroundService { | |||
@@ -64,7 +65,7 @@ class BackgroundService { | |||
'yana-sichikova-sergey-ovachev-stone-flower-2k.jpg', | |||
]; | |||
public function __construct(IRootFolder $rootFolder, IAppData $appData, $userId) { | |||
public function __construct(IRootFolder $rootFolder, IAppData $appData, IConfig $config, $userId) { | |||
if ($userId === null) { | |||
return; | |||
} | |||
@@ -74,14 +75,26 @@ class BackgroundService { | |||
} catch (NotFoundException $e) { | |||
$this->dashboardUserFolder = $appData->newFolder($userId); | |||
} | |||
$this->config = $config; | |||
$this->userId = $userId; | |||
} | |||
public function setDefaultBackground() { | |||
$this->config->deleteUserValue($this->userId, 'dashboard', 'background'); | |||
} | |||
public function setFileBackground($path) { | |||
$this->config->setUserValue($this->userId, 'dashboard', 'background', 'custom'); | |||
$file = $this->userFolder->get($path); | |||
$newFile = $this->dashboardUserFolder->newFile('background.jpg', $file->fopen('r')); | |||
} | |||
public function setShippedBackground($fileName) { | |||
$this->config->setUserValue($this->userId, 'dashboard', 'background', $fileName); | |||
} | |||
public function setUrlBackground($url) { | |||
$this->config->setUserValue($this->userId, 'dashboard', 'background', 'custom'); | |||
if (substr($url, 0, 1) === '/') { | |||
$url = \OC::$server->getURLGenerator()->getAbsoluteURL($url); | |||
} | |||
@@ -92,11 +105,15 @@ class BackgroundService { | |||
$newFile = $this->dashboardUserFolder->newFile('background.jpg', $content); | |||
} | |||
/** | |||
* @throws NotFoundException | |||
*/ | |||
public function getBackground(): ISimpleFile { | |||
return $this->dashboardUserFolder->getFile('background.jpg'); | |||
public function getBackground() { | |||
$background = $this->config->getUserValue($this->userId, 'dashboard', 'background', 'default'); | |||
if ($background === 'custom') { | |||
try { | |||
return $this->dashboardUserFolder->getFile('background.jpg'); | |||
} catch (NotFoundException $e) { | |||
} | |||
} | |||
return null; | |||
} | |||
} |
@@ -76,6 +76,7 @@ import BackgroundSettings from './components/BackgroundSettings' | |||
const panels = loadState('dashboard', 'panels') | |||
const firstRun = loadState('dashboard', 'firstRun') | |||
const background = loadState('dashboard', 'background') | |||
const prefixWithBaseUrl = (url) => generateFilePath('dashboard', '', 'img/') + url | |||
@@ -103,18 +104,22 @@ export default { | |||
modal: false, | |||
appStoreUrl: generateUrl('/settings/apps/dashboard'), | |||
statuses: {}, | |||
background, | |||
backgroundTime: Date.now(), | |||
defaultBackground: window.OCA.Accessibility.theme === 'dark' ? prefixWithBaseUrl('flickr-148302424@N05-36591009215.jpg?v=1') : prefixWithBaseUrl('flickr-paszczak000-8715851521.jpg?v=1'), | |||
} | |||
}, | |||
computed: { | |||
backgroundImage() { | |||
// FIXME: make this dependent if the default is set or not | |||
return generateUrl('/apps/dashboard/background') + '?v=' + this.backgroundTime | |||
if (window.OCA.Accessibility.theme === 'dark') { | |||
return !isMobile ? prefixWithBaseUrl('flickr-148302424@N05-36591009215.jpg?v=1') : prefixWithBaseUrl('flickr-148302424@N05-36591009215-mobile.jpg?v=1') | |||
if (this.background === 'default') { | |||
if (window.OCA.Accessibility.theme === 'dark') { | |||
return !isMobile ? prefixWithBaseUrl('flickr-148302424@N05-36591009215.jpg?v=1') : prefixWithBaseUrl('flickr-148302424@N05-36591009215-mobile.jpg?v=1') | |||
} | |||
return !isMobile ? prefixWithBaseUrl('flickr-paszczak000-8715851521.jpg?v=1') : prefixWithBaseUrl('flickr-paszczak000-8715851521-mobile.jpg?v=1') | |||
} else if (this.background === 'custom') { | |||
return generateUrl('/apps/dashboard/background') + '?v=' + this.backgroundTime | |||
} | |||
return !isMobile ? prefixWithBaseUrl('flickr-paszczak000-8715851521.jpg?v=1') : prefixWithBaseUrl('flickr-paszczak000-8715851521-mobile.jpg?v=1') | |||
return prefixWithBaseUrl(this.background) | |||
}, | |||
tooltip() { | |||
if (!this.firstRun) { | |||
@@ -254,8 +259,8 @@ export default { | |||
this.firstRun = false | |||
}, 1000) | |||
}, | |||
updateBackground(date) { | |||
this.backgroundTime = date | |||
updateBackground(backgroundType) { | |||
this.background = backgroundType | |||
}, | |||
}, | |||
} |
@@ -22,18 +22,25 @@ | |||
<template> | |||
<div class="background-selector"> | |||
<div v-if="loading">Loading</div> | |||
<div v-for="background in shippedBackgrounds" | |||
:key="background" | |||
class="background" | |||
@click="setUrl(background)"> | |||
<img :src="background"> | |||
<div class="background default" | |||
:class="{ 'icon-loading': loading === 'default' }" | |||
@click="setDefault()"> | |||
<div class="background--preview"> | |||
Default | |||
</div> | |||
</div> | |||
<div class="background" @click="pickFile"> | |||
<a> | |||
{{ t('dashboard', 'Pick an image from your files') }} | |||
</a> | |||
</div> | |||
<div v-for="background in shippedBackgrounds" | |||
:key="background.name" | |||
class="background" | |||
:class="{ 'icon-loading': loading === background.name }" | |||
@click="setShipped(background.name)"> | |||
<div class="background--preview" :style="{ 'background-image': 'url(' + background.url + ')' }" /> | |||
</div> | |||
</div> | |||
</template> | |||
@@ -41,10 +48,23 @@ | |||
import axios from '@nextcloud/axios' | |||
import { generateUrl, generateFilePath } from '@nextcloud/router' | |||
import { loadState } from '@nextcloud/initial-state' | |||
import isMobile from '../mixins/isMobile' | |||
const prefixWithBaseUrl = (url) => generateFilePath('dashboard', '', 'img/') + url | |||
const shippedBackgroundList = loadState('dashboard', 'shippedBackgrounds') | |||
const getBackgroundUrl = (background, time = 0) => { | |||
if (background === 'default') { | |||
if (window.OCA.Accessibility.theme === 'dark') { | |||
return !isMobile ? prefixWithBaseUrl('flickr-148302424@N05-36591009215.jpg?v=1') : prefixWithBaseUrl('flickr-148302424@N05-36591009215-mobile.jpg?v=1') | |||
} | |||
return !isMobile ? prefixWithBaseUrl('flickr-paszczak000-8715851521.jpg?v=1') : prefixWithBaseUrl('flickr-paszczak000-8715851521-mobile.jpg?v=1') | |||
} else if (background === 'custom') { | |||
return generateUrl('/apps/dashboard/background') + '?v=' + time | |||
} | |||
return prefixWithBaseUrl(background) | |||
} | |||
export default { | |||
name: 'BackgroundSettings', | |||
data() { | |||
@@ -56,36 +76,43 @@ export default { | |||
computed: { | |||
shippedBackgrounds() { | |||
return shippedBackgroundList.map((item) => { | |||
return prefixWithBaseUrl(item) | |||
return { | |||
name: item, | |||
url: prefixWithBaseUrl(item), | |||
} | |||
}) | |||
}, | |||
}, | |||
methods: { | |||
async update() { | |||
async update(state) { | |||
const date = Date.now() | |||
this.backgroundImage = generateUrl('/apps/dashboard/background') + '?v=' + date | |||
this.backgroundImage = getBackgroundUrl(state, date) | |||
const image = new Image() | |||
image.onload = () => { | |||
this.$emit('updateBackground', date) | |||
this.$emit('updateBackground', state) | |||
this.loading = false | |||
} | |||
image.src = this.backgroundImage | |||
}, | |||
setDefault() { | |||
async setDefault() { | |||
console.debug('SetDefault') | |||
this.update() | |||
await axios.post(generateUrl('/apps/dashboard/background')) | |||
this.update('default') | |||
}, | |||
async setShipped(shipped) { | |||
this.loading = shipped | |||
await axios.post(generateUrl('/apps/dashboard/background'), { shipped }) | |||
this.update(shipped) | |||
}, | |||
async setUrl(url) { | |||
this.loading = true | |||
console.debug('SetUrl ' + url) | |||
await axios.post(generateUrl('/apps/dashboard/background'), { url }) | |||
this.update() | |||
this.update('custom') | |||
}, | |||
async setFile(path) { | |||
this.loading = true | |||
console.debug('SetFile ' + path) | |||
await axios.post(generateUrl('/apps/dashboard/background'), { path }) | |||
this.update() | |||
this.update('custom') | |||
}, | |||
pickFile() { | |||
window.OC.dialogs.filepicker(t('dashboard', 'Insert from {productName}', { productName: OC.theme.name }), (path, type) => { | |||
@@ -114,8 +141,11 @@ export default { | |||
background-image: var(--color-background-dark); | |||
} | |||
& img { | |||
&--preview { | |||
width: 140px; | |||
height: 90px; | |||
background-size: cover; | |||
background-position: center center; | |||
} | |||
&:hover { |