Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/dav/tests/unit/Connector/Sabre/FileTest.php4
-rw-r--r--apps/files/lib/Controller/ViewController.php2
-rw-r--r--apps/files_sharing/css/public.css8
-rw-r--r--apps/files_sharing/css/public.css.map2
-rw-r--r--apps/files_sharing/css/public.scss10
-rw-r--r--apps/files_sharing/css/publicView.css8
-rw-r--r--apps/files_sharing/css/publicView.css.map2
-rw-r--r--apps/theming/css/default.css21
-rw-r--r--apps/theming/css/settings-admin.css2
-rw-r--r--apps/theming/css/settings-admin.scss4
-rw-r--r--apps/theming/lib/Service/BackgroundService.php5
-rw-r--r--apps/theming/lib/Themes/DefaultTheme.php19
-rw-r--r--apps/theming/lib/ThemingDefaults.php83
-rw-r--r--apps/theming/src/components/BackgroundSettings.vue2
-rw-r--r--apps/theming/tests/Service/ThemesServiceTest.php10
-rw-r--r--apps/theming/tests/Settings/PersonalTest.php8
-rw-r--r--apps/theming/tests/Themes/DefaultThemeTest.php3
-rw-r--r--apps/theming/tests/Themes/DyslexiaFontTest.php6
-rw-r--r--apps/theming/tests/ThemingDefaultsTest.php11
-rw-r--r--core/BackgroundJobs/BackgroundCleanupUpdaterBackupsJob.php4
-rw-r--r--core/Controller/ReferenceApiController.php2
-rw-r--r--core/css/guest.css2
-rw-r--r--core/css/public.css2
-rw-r--r--core/css/public.scss2
-rw-r--r--core/css/server.css2
-rw-r--r--dist/theming-theming-settings.js4
-rw-r--r--dist/theming-theming-settings.js.map2
-rw-r--r--lib/private/Collaboration/Collaborators/MailPlugin.php16
-rw-r--r--lib/private/Contacts/ContactsMenu/ContactsStore.php7
-rw-r--r--lib/private/Files/Cache/Propagator.php46
-rw-r--r--lib/private/Files/Storage/Local.php9
-rw-r--r--lib/private/Files/View.php12
-rw-r--r--lib/private/OCS/CoreCapabilities.php5
-rw-r--r--lib/private/Server.php1
-rw-r--r--lib/public/Collaboration/Reference/IReference.php2
-rw-r--r--lib/public/Collaboration/Reference/Reference.php4
-rw-r--r--lib/public/IURLGenerator.php11
-rw-r--r--ocs/v1.php1
-rw-r--r--tests/acceptance/features/app-theming.feature8
-rw-r--r--tests/acceptance/features/bootstrap/ThemingAppContext.php17
-rw-r--r--tests/lib/Contacts/ContactsMenu/ContactsStoreTest.php6
-rw-r--r--tests/lib/Files/ViewTest.php19
42 files changed, 265 insertions, 129 deletions
diff --git a/apps/dav/tests/unit/Connector/Sabre/FileTest.php b/apps/dav/tests/unit/Connector/Sabre/FileTest.php
index 6a954378d02..91e49d331e9 100644
--- a/apps/dav/tests/unit/Connector/Sabre/FileTest.php
+++ b/apps/dav/tests/unit/Connector/Sabre/FileTest.php
@@ -1151,7 +1151,7 @@ class FileTest extends TestCase {
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [
'permissions' => \OCP\Constants::PERMISSION_ALL,
- 'type' => FileInfo::TYPE_FOLDER,
+ 'type' => FileInfo::TYPE_FILE,
], null);
$file = new \OCA\DAV\Connector\Sabre\File($view, $info);
@@ -1172,7 +1172,7 @@ class FileTest extends TestCase {
$info = new \OC\Files\FileInfo('/test.txt', $this->getMockStorage(), null, [
'permissions' => \OCP\Constants::PERMISSION_ALL,
- 'type' => FileInfo::TYPE_FOLDER,
+ 'type' => FileInfo::TYPE_FILE,
], null);
$file = new \OCA\DAV\Connector\Sabre\File($view, $info);
diff --git a/apps/files/lib/Controller/ViewController.php b/apps/files/lib/Controller/ViewController.php
index 82f56be9f18..cfbc9afce2b 100644
--- a/apps/files/lib/Controller/ViewController.php
+++ b/apps/files/lib/Controller/ViewController.php
@@ -266,7 +266,7 @@ class ViewController extends Controller {
$nav->assign('quota', $storageInfo['quota']);
$nav->assign('usage_relative', $storageInfo['relative']);
- $nav->assign('webdav_url', \OCP\Util::linkToRemote('dav/files/' . $user));
+ $nav->assign('webdav_url', \OCP\Util::linkToRemote('dav/files/' . rawurlencode($user)));
$contentItems = [];
diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css
index 79c5fe9c04d..816ee1fb6f9 100644
--- a/apps/files_sharing/css/public.css
+++ b/apps/files_sharing/css/public.css
@@ -47,7 +47,7 @@
}
#imgframe img {
- max-height: calc(100vh - var(--header-height) - 65px - 200px) !important;
+ max-height: calc(100vh - var(--header-height) - 65px - 200px - 16px) !important;
max-width: 100% !important;
width: unset !important;
}
@@ -57,7 +57,7 @@
}
#imgframe video {
- max-height: calc(100vh - var(--header-height) - 65px - 200px);
+ max-height: calc(100vh - var(--header-height) - 65px - 200px - 16px);
}
#imgframe audio {
@@ -98,6 +98,10 @@
max-height: 100%;
}
+.app-files_sharing #app-content footer {
+ position: sticky !important;
+}
+
/* fix multiselect bar offset on shared page */
thead {
left: 0 !important;
diff --git a/apps/files_sharing/css/public.css.map b/apps/files_sharing/css/public.css.map
index 909bcc0dd97..59a23875931 100644
--- a/apps/files_sharing/css/public.css.map
+++ b/apps/files_sharing/css/public.css.map
@@ -1 +1 @@
-{"version":3,"sourceRoot":"","sources":["../../../core/css/variables.scss","public.scss"],"names":[],"mappings":";AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACKA;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACI;;;AAGJ;EACC;;;AAGD;EACC;EACA;EACA;;;AAGD;EAEI;;;AAGJ;EACI;;;AAGJ;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;AACA;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;AACA;EACC;;;AAED;AAAA;AAAA;EAGC;EACA;;;AAED;AAAA;AAAA;AAGC;EACA;;;AAGD;EACC;;;AAIA;EACC;;;AAIF;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;AAAA;EAEC;EACA;EACA;;;AAGD;EACC;EACA;EACA;;AACA;EACC;EACA;;;AAIF;EACC;EACA;;;AAKD;EAII;IACC;;;AAQL;EAGG;IACC","file":"public.css"} \ No newline at end of file
+{"version":3,"sourceRoot":"","sources":["../../../core/css/variables.scss","public.scss"],"names":[],"mappings":";AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACMA;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACI;;;AAGJ;EACC;;;AAGD;EACC;EACA;EACA;;;AAGD;EAEI;;;AAGJ;EACI;;;AAGJ;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAID;EACC;;;AAGD;AACA;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;AACA;EACC;;;AAED;AAAA;AAAA;EAGC;EACA;;;AAED;AAAA;AAAA;AAGC;EACA;;;AAGD;EACC;;;AAIA;EACC;;;AAIF;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;AAAA;EAEC;EACA;EACA;;;AAGD;EACC;EACA;EACA;;AACA;EACC;EACA;;;AAIF;EACC;EACA;;;AAKD;EAII;IACC;;;AAQL;EAGG;IACC","file":"public.css"} \ No newline at end of file
diff --git a/apps/files_sharing/css/public.scss b/apps/files_sharing/css/public.scss
index 1e5e6ee229e..f325622ea2c 100644
--- a/apps/files_sharing/css/public.scss
+++ b/apps/files_sharing/css/public.scss
@@ -1,6 +1,7 @@
@use 'variables';
$footer-height: 65px;
+$footer-padding-height: 16px;
$download-button-section-height: 200px;
#preview {
@@ -30,7 +31,7 @@ $download-button-section-height: 200px;
}
#imgframe img {
- max-height: calc(100vh - var(--header-height) - #{$footer-height} - #{$download-button-section-height}) !important;
+ max-height: calc(100vh - var(--header-height) - #{$footer-height} - #{$download-button-section-height} - #{$footer-padding-height}) !important;
max-width: 100% !important;
width: unset !important;
}
@@ -40,7 +41,7 @@ $download-button-section-height: 200px;
}
#imgframe video {
- max-height: calc(100vh - var(--header-height) - #{$footer-height} - #{$download-button-section-height});
+ max-height: calc(100vh - var(--header-height) - #{$footer-height} - #{$download-button-section-height} - #{$footer-padding-height});
}
#imgframe audio {
@@ -82,6 +83,11 @@ $download-button-section-height: 200px;
max-height: 100%;
}
+
+.app-files_sharing #app-content footer {
+ position: sticky !important;
+}
+
/* fix multiselect bar offset on shared page */
thead {
left: 0 !important;
diff --git a/apps/files_sharing/css/publicView.css b/apps/files_sharing/css/publicView.css
index 87065766e4b..6debc033ede 100644
--- a/apps/files_sharing/css/publicView.css
+++ b/apps/files_sharing/css/publicView.css
@@ -47,7 +47,7 @@
}
#imgframe img {
- max-height: calc(100vh - var(--header-height) - 65px - 200px) !important;
+ max-height: calc(100vh - var(--header-height) - 65px - 200px - 16px) !important;
max-width: 100% !important;
width: unset !important;
}
@@ -57,7 +57,7 @@
}
#imgframe video {
- max-height: calc(100vh - var(--header-height) - 65px - 200px);
+ max-height: calc(100vh - var(--header-height) - 65px - 200px - 16px);
}
#imgframe audio {
@@ -98,6 +98,10 @@
max-height: 100%;
}
+.app-files_sharing #app-content footer {
+ position: sticky !important;
+}
+
/* fix multiselect bar offset on shared page */
thead {
left: 0 !important;
diff --git a/apps/files_sharing/css/publicView.css.map b/apps/files_sharing/css/publicView.css.map
index 3ac8588952c..c196ee11a5a 100644
--- a/apps/files_sharing/css/publicView.css.map
+++ b/apps/files_sharing/css/publicView.css.map
@@ -1 +1 @@
-{"version":3,"sourceRoot":"","sources":["../../../core/css/variables.scss","public.scss","mobile.scss"],"names":[],"mappings":";AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACKA;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACI;;;AAGJ;EACC;;;AAGD;EACC;EACA;EACA;;;AAGD;EAEI;;;AAGJ;EACI;;;AAGJ;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;AACA;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;AACA;EACC;;;AAED;AAAA;AAAA;EAGC;EACA;;;AAED;AAAA;AAAA;AAGC;EACA;;;AAGD;EACC;;;AAIA;EACC;;;AAIF;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;AAAA;EAEC;EACA;EACA;;;AAGD;EACC;EACA;EACA;;AACA;EACC;EACA;;;AAIF;EACC;EACA;;;AAKD;EAII;IACC;;;AAQL;EAGG;IACC;;;ADnQJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AEEA;AAEA;EACA;IACC;;;AAGD;EACA;AAAA;AAAA;AAAA;IAIC;;;AAGD;EACA;IACC;;;AAGD;EACA;IACC;IACA;;;AAED;EACA;IACC;;;AAGD;EACA;IACC;;;AAED;EACA;IACC;;;AAGD;EACA;IACC;IACA;IACA;IACA;;;EAGD;IACI;IACA;;;EAEJ;IACC;;;EAGD;IACC","file":"publicView.css"} \ No newline at end of file
+{"version":3,"sourceRoot":"","sources":["../../../core/css/variables.scss","public.scss","mobile.scss"],"names":[],"mappings":";AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACMA;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACI;;;AAGJ;EACC;;;AAGD;EACC;EACA;EACA;;;AAGD;EAEI;;;AAGJ;EACI;;;AAGJ;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAID;EACC;;;AAGD;AACA;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;AACA;EACC;;;AAED;AAAA;AAAA;EAGC;EACA;;;AAED;AAAA;AAAA;AAGC;EACA;;;AAGD;EACC;;;AAIA;EACC;;;AAIF;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;AAAA;EAEC;EACA;EACA;;;AAGD;EACC;EACA;EACA;;AACA;EACC;EACA;;;AAIF;EACC;EACA;;;AAKD;EAII;IACC;;;AAQL;EAGG;IACC;;;ADzQJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AEEA;AAEA;EACA;IACC;;;AAGD;EACA;AAAA;AAAA;AAAA;IAIC;;;AAGD;EACA;IACC;;;AAGD;EACA;IACC;IACA;;;AAED;EACA;IACC;;;AAGD;EACA;IACC;;;AAED;EACA;IACC;;;AAGD;EACA;IACC;IACA;IACA;IACA;;;EAGD;IACI;IACA;;;EAEJ;IACC;;;EAGD;IACC","file":"publicView.css"} \ No newline at end of file
diff --git a/apps/theming/css/default.css b/apps/theming/css/default.css
index e7403ee69cc..19d02a53f9b 100644
--- a/apps/theming/css/default.css
+++ b/apps/theming/css/default.css
@@ -1,5 +1,6 @@
:root {
--color-main-background: #ffffff;
+ --color-main-background-not-plain: #0082c9;
--color-main-background-rgb: 255,255,255;
--color-main-background-translucent: rgba(var(--color-main-background-rgb), .97);
--color-main-background-blur: rgba(var(--color-main-background-rgb), .8);
@@ -53,19 +54,19 @@
--background-invert-if-dark: no;
--background-invert-if-bright: invert(100%);
--image-main-background: url('/core/img/app-background.jpg');
- --color-primary: #0082c9;
+ --color-primary: #00639a;
--color-primary-text: #ffffff;
- --color-primary-hover: #329bd3;
- --color-primary-light: #e5f2f9;
- --color-primary-light-text: #003450;
- --color-primary-light-hover: #dbe7ee;
+ --color-primary-hover: #3282ae;
+ --color-primary-light: #e5eff4;
+ --color-primary-light-text: #00273d;
+ --color-primary-light-hover: #dbe4e9;
--color-primary-text-dark: #ededed;
- --color-primary-element: #0082c9;
+ --color-primary-element: #00639a;
--color-primary-element-text: #ffffff;
- --color-primary-element-hover: #329bd3;
- --color-primary-element-light: #e5f2f9;
- --color-primary-element-light-text: #003450;
- --color-primary-element-light-hover: #dbe7ee;
+ --color-primary-element-hover: #3282ae;
+ --color-primary-element-light: #e5eff4;
+ --color-primary-element-light-text: #00273d;
+ --color-primary-element-light-hover: #dbe4e9;
--color-primary-element-text-dark: #ededed;
--gradient-primary-background: linear-gradient(40deg, var(--color-primary) 0%, var(--color-primary-hover) 100%);
}
diff --git a/apps/theming/css/settings-admin.css b/apps/theming/css/settings-admin.css
index bb154de2737..2b91404ec3b 100644
--- a/apps/theming/css/settings-admin.css
+++ b/apps/theming/css/settings-admin.css
@@ -89,7 +89,7 @@
margin-top: 10px;
margin-bottom: 20px;
cursor: pointer;
- background-color: var(--color-primary);
+ background-color: var(--color-main-background-not-plain, var(--color-primary));
background-image: var(--image-background, var(--image-background-plain, url("../../../core/img/app-background.jpg"), linear-gradient(40deg, #0082c9 0%, #30b6ff 100%)));
}
#theming #theming-preview #theming-preview-logo {
diff --git a/apps/theming/css/settings-admin.scss b/apps/theming/css/settings-admin.scss
index 6b37a48622e..706bd37f495 100644
--- a/apps/theming/css/settings-admin.scss
+++ b/apps/theming/css/settings-admin.scss
@@ -100,7 +100,7 @@
margin-top: 10px;
margin-bottom: 20px;
cursor: pointer;
- background-color: var(--color-primary);
+ background-color: var(--color-main-background-not-plain, var(--color-primary));
background-image: var(--image-background, var(--image-background-plain, url('../../../core/img/app-background.jpg'), linear-gradient(40deg, #0082c9 0%, #30b6ff 100%)));
#theming-preview-logo {
@@ -145,4 +145,4 @@
svg, img {
transition: 500ms filter linear;
}
-} \ No newline at end of file
+}
diff --git a/apps/theming/lib/Service/BackgroundService.php b/apps/theming/lib/Service/BackgroundService.php
index bbf7bde9e5f..0614fe00357 100644
--- a/apps/theming/lib/Service/BackgroundService.php
+++ b/apps/theming/lib/Service/BackgroundService.php
@@ -44,6 +44,8 @@ use OCP\PreConditionNotMetException;
class BackgroundService {
// true when the background is bright and need dark icons
public const THEMING_MODE_DARK = 'dark';
+ public const DEFAULT_COLOR = '#0082c9';
+ public const DEFAULT_ACCESSIBLE_COLOR = '#00639a';
public const SHIPPED_BACKGROUNDS = [
'anatoly-mikhaltsov-butterfly-wing-scale.jpg' => [
@@ -90,8 +92,7 @@ class BackgroundService {
'kamil-porembinski-clouds.jpg' => [
'attribution' => 'Clouds (Kamil Porembiński, CC BY-SA)',
'attribution_url' => 'https://www.flickr.com/photos/paszczak000/8715851521/',
- // Originally #0082c9 but adjusted for accessibility
- 'primary_color' => '#00639a',
+ 'primary_color' => self::DEFAULT_COLOR,
],
'bernard-spragg-new-zealand-fern.jpg' => [
'attribution' => 'New zealand fern (Bernard Spragg, CC0)',
diff --git a/apps/theming/lib/Themes/DefaultTheme.php b/apps/theming/lib/Themes/DefaultTheme.php
index 203e03757c8..413902d7813 100644
--- a/apps/theming/lib/Themes/DefaultTheme.php
+++ b/apps/theming/lib/Themes/DefaultTheme.php
@@ -27,6 +27,7 @@ namespace OCA\Theming\Themes;
use OCA\Theming\AppInfo\Application;
use OCA\Theming\ImageManager;
use OCA\Theming\ITheme;
+use OCA\Theming\Service\BackgroundService;
use OCA\Theming\ThemingDefaults;
use OCA\Theming\Util;
use OCP\App\IAppManager;
@@ -41,6 +42,7 @@ class DefaultTheme implements ITheme {
public Util $util;
public ThemingDefaults $themingDefaults;
+ public IUserSession $userSession;
public IURLGenerator $urlGenerator;
public ImageManager $imageManager;
public IConfig $config;
@@ -50,18 +52,22 @@ class DefaultTheme implements ITheme {
public function __construct(Util $util,
ThemingDefaults $themingDefaults,
+ IUserSession $userSession,
IURLGenerator $urlGenerator,
ImageManager $imageManager,
IConfig $config,
IL10N $l) {
$this->util = $util;
$this->themingDefaults = $themingDefaults;
+ $this->userSession = $userSession;
$this->urlGenerator = $urlGenerator;
$this->imageManager = $imageManager;
$this->config = $config;
$this->l = $l;
- $this->primaryColor = $this->themingDefaults->getColorPrimary();
+ $initialPrimaryColor = $this->themingDefaults->getColorPrimary();
+ // Override default color if set to improve accessibility
+ $this->primaryColor = $initialPrimaryColor === BackgroundService::DEFAULT_COLOR ? BackgroundService::DEFAULT_ACCESSIBLE_COLOR : $initialPrimaryColor;
}
public function getId(): string {
@@ -101,6 +107,7 @@ class DefaultTheme implements ITheme {
$variables = [
'--color-main-background' => $colorMainBackground,
+ '--color-main-background-not-plain' => $this->themingDefaults->getColorPrimary(),
'--color-main-background-rgb' => $colorMainBackgroundRGB,
'--color-main-background-translucent' => 'rgba(var(--color-main-background-rgb), .97)',
'--color-main-background-blur' => 'rgba(var(--color-main-background-rgb), .8)',
@@ -221,21 +228,17 @@ class DefaultTheme implements ITheme {
}
$appManager = Server::get(IAppManager::class);
- $userSession = Server::get(IUserSession::class);
- $user = $userSession->getUser();
+ $user = $this->userSession->getUser();
if ($appManager->isEnabledForUser(Application::APP_ID) && $user !== null) {
$themingBackground = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'background', 'default');
if ($themingBackground === 'custom') {
- // Custom
$variables['--image-main-background'] = "url('" . $this->urlGenerator->linkToRouteAbsolute('theming.userTheme.getBackground') . "')";
- } elseif ($themingBackground !== 'default' && substr($themingBackground, 0, 1) !== '#') {
- // Shipped background
+ } elseif (isset(BackgroundService::SHIPPED_BACKGROUNDS[$themingBackground])) {
$variables['--image-main-background'] = "url('" . $this->urlGenerator->linkTo(Application::APP_ID, "/img/background/$themingBackground") . "')";
} elseif (substr($themingBackground, 0, 1) === '#') {
- // Color
unset($variables['--image-main-background']);
- $variables['--color-main-background-plain'] = $this->primaryColor;
+ $variables['--color-main-background-plain'] = $this->themingDefaults->getColorPrimary();
}
}
diff --git a/apps/theming/lib/ThemingDefaults.php b/apps/theming/lib/ThemingDefaults.php
index 3d7aaee2064..5fa5656d928 100644
--- a/apps/theming/lib/ThemingDefaults.php
+++ b/apps/theming/lib/ThemingDefaults.php
@@ -40,6 +40,8 @@
*/
namespace OCA\Theming;
+use OCA\Theming\AppInfo\Application;
+use OCA\Theming\Service\BackgroundService;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\Files\NotFoundException;
@@ -49,47 +51,31 @@ use OCP\IConfig;
use OCP\IL10N;
use OCP\INavigationManager;
use OCP\IURLGenerator;
+use OCP\IUserSession;
class ThemingDefaults extends \OC_Defaults {
- /** @var IConfig */
- private $config;
- /** @var IL10N */
- private $l;
- /** @var ImageManager */
- private $imageManager;
- /** @var IURLGenerator */
- private $urlGenerator;
- /** @var ICacheFactory */
- private $cacheFactory;
- /** @var Util */
- private $util;
- /** @var IAppManager */
- private $appManager;
- /** @var INavigationManager */
- private $navigationManager;
-
- /** @var string */
- private $name;
- /** @var string */
- private $title;
- /** @var string */
- private $entity;
- /** @var string */
- private $productName;
- /** @var string */
- private $url;
- /** @var string */
- private $color;
-
- /** @var string */
- private $iTunesAppId;
- /** @var string */
- private $iOSClientUrl;
- /** @var string */
- private $AndroidClientUrl;
- /** @var string */
- private $FDroidClientUrl;
+ private IConfig $config;
+ private IL10N $l;
+ private ImageManager $imageManager;
+ private IUserSession $userSession;
+ private IURLGenerator $urlGenerator;
+ private ICacheFactory $cacheFactory;
+ private Util $util;
+ private IAppManager $appManager;
+ private INavigationManager $navigationManager;
+
+ private string $name;
+ private string $title;
+ private string $entity;
+ private string $productName;
+ private string $url;
+ private string $color;
+
+ private string $iTunesAppId;
+ private string $iOSClientUrl;
+ private string $AndroidClientUrl;
+ private string $FDroidClientUrl;
/**
* ThemingDefaults constructor.
@@ -97,6 +83,7 @@ class ThemingDefaults extends \OC_Defaults {
* @param IConfig $config
* @param IL10N $l
* @param ImageManager $imageManager
+ * @param IUserSession $userSession
* @param IURLGenerator $urlGenerator
* @param ICacheFactory $cacheFactory
* @param Util $util
@@ -104,6 +91,7 @@ class ThemingDefaults extends \OC_Defaults {
*/
public function __construct(IConfig $config,
IL10N $l,
+ IUserSession $userSession,
IURLGenerator $urlGenerator,
ICacheFactory $cacheFactory,
Util $util,
@@ -115,6 +103,7 @@ class ThemingDefaults extends \OC_Defaults {
$this->config = $config;
$this->l = $l;
$this->imageManager = $imageManager;
+ $this->userSession = $userSession;
$this->urlGenerator = $urlGenerator;
$this->cacheFactory = $cacheFactory;
$this->util = $util;
@@ -229,10 +218,24 @@ class ThemingDefaults extends \OC_Defaults {
* @return string
*/
public function getColorPrimary() {
- $color = $this->config->getAppValue('theming', 'color', $this->color);
+ $user = $this->userSession->getUser();
+ $color = $this->config->getAppValue(Application::APP_ID, 'color', '');
+
+ if ($color === '' && !empty($user)) {
+ $themingBackground = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'background', 'default');
+ if ($themingBackground === 'default') {
+ $this->increaseCacheBuster();
+ return BackgroundService::DEFAULT_COLOR;
+ } else if (isset(BackgroundService::SHIPPED_BACKGROUNDS[$themingBackground]['primary_color'])) {
+ $this->increaseCacheBuster();
+ return BackgroundService::SHIPPED_BACKGROUNDS[$themingBackground]['primary_color'];
+ }
+ }
+
if (!preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $color)) {
- $color = '#0082c9';
+ return BackgroundService::DEFAULT_COLOR;
}
+
return $color;
}
diff --git a/apps/theming/src/components/BackgroundSettings.vue b/apps/theming/src/components/BackgroundSettings.vue
index 359723bcf49..39210569689 100644
--- a/apps/theming/src/components/BackgroundSettings.vue
+++ b/apps/theming/src/components/BackgroundSettings.vue
@@ -171,7 +171,7 @@ export default {
}
&.color {
- background-color: var(--color-primary);
+ background-color: var(--color-main-background-not-plain, var(--color-primary));
color: var(--color-primary-text);
}
diff --git a/apps/theming/tests/Service/ThemesServiceTest.php b/apps/theming/tests/Service/ThemesServiceTest.php
index 3be8881669a..5a2907ec073 100644
--- a/apps/theming/tests/Service/ThemesServiceTest.php
+++ b/apps/theming/tests/Service/ThemesServiceTest.php
@@ -156,7 +156,7 @@ class ThemesServiceTest extends TestCase {
->method('getUserValue')
->with('user', Application::APP_ID, 'enabled-themes', '[]')
->willReturn(json_encode($enabledThemes));
-
+
$this->assertEquals($expectedEnabled, $this->themesService->disableTheme($this->themes[$toDisable]));
}
@@ -190,7 +190,7 @@ class ThemesServiceTest extends TestCase {
->method('getUserValue')
->with('user', Application::APP_ID, 'enabled-themes', '[]')
->willReturn(json_encode($enabledThemes));
-
+
$this->assertEquals($expected, $this->themesService->isEnabled($this->themes[$themeId]));
}
@@ -281,6 +281,7 @@ class ThemesServiceTest extends TestCase {
'default' => new DefaultTheme(
$util,
$this->themingDefaults,
+ $this->userSession,
$urlGenerator,
$imageManager,
$this->config,
@@ -289,6 +290,7 @@ class ThemesServiceTest extends TestCase {
'light' => new LightTheme(
$util,
$this->themingDefaults,
+ $this->userSession,
$urlGenerator,
$imageManager,
$this->config,
@@ -297,6 +299,7 @@ class ThemesServiceTest extends TestCase {
'dark' => new DarkTheme(
$util,
$this->themingDefaults,
+ $this->userSession,
$urlGenerator,
$imageManager,
$this->config,
@@ -305,6 +308,7 @@ class ThemesServiceTest extends TestCase {
'light-highcontrast' => new HighContrastTheme(
$util,
$this->themingDefaults,
+ $this->userSession,
$urlGenerator,
$imageManager,
$this->config,
@@ -313,6 +317,7 @@ class ThemesServiceTest extends TestCase {
'dark-highcontrast' => new DarkHighContrastTheme(
$util,
$this->themingDefaults,
+ $this->userSession,
$urlGenerator,
$imageManager,
$this->config,
@@ -321,6 +326,7 @@ class ThemesServiceTest extends TestCase {
'opendyslexic' => new DyslexiaFont(
$util,
$this->themingDefaults,
+ $this->userSession,
$urlGenerator,
$imageManager,
$this->config,
diff --git a/apps/theming/tests/Settings/PersonalTest.php b/apps/theming/tests/Settings/PersonalTest.php
index 8e121c0a057..0cb289cb86a 100644
--- a/apps/theming/tests/Settings/PersonalTest.php
+++ b/apps/theming/tests/Settings/PersonalTest.php
@@ -45,6 +45,7 @@ use OCP\AppFramework\Services\IInitialState;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IURLGenerator;
+use OCP\IUserSession;
use Test\TestCase;
class PersonalTest extends TestCase {
@@ -128,6 +129,7 @@ class PersonalTest extends TestCase {
private function initThemes() {
$util = $this->createMock(Util::class);
$themingDefaults = $this->createMock(ThemingDefaults::class);
+ $userSession = $this->createMock(IUserSession::class);
$urlGenerator = $this->createMock(IURLGenerator::class);
$imageManager = $this->createMock(ImageManager::class);
$config = $this->createMock(IConfig::class);
@@ -141,6 +143,7 @@ class PersonalTest extends TestCase {
'default' => new DefaultTheme(
$util,
$themingDefaults,
+ $userSession,
$urlGenerator,
$imageManager,
$config,
@@ -149,6 +152,7 @@ class PersonalTest extends TestCase {
'light' => new LightTheme(
$util,
$themingDefaults,
+ $userSession,
$urlGenerator,
$imageManager,
$config,
@@ -157,6 +161,7 @@ class PersonalTest extends TestCase {
'dark' => new DarkTheme(
$util,
$themingDefaults,
+ $userSession,
$urlGenerator,
$imageManager,
$config,
@@ -165,6 +170,7 @@ class PersonalTest extends TestCase {
'light-highcontrast' => new HighContrastTheme(
$util,
$themingDefaults,
+ $userSession,
$urlGenerator,
$imageManager,
$config,
@@ -173,6 +179,7 @@ class PersonalTest extends TestCase {
'dark-highcontrast' => new DarkHighContrastTheme(
$util,
$themingDefaults,
+ $userSession,
$urlGenerator,
$imageManager,
$config,
@@ -181,6 +188,7 @@ class PersonalTest extends TestCase {
'opendyslexic' => new DyslexiaFont(
$util,
$themingDefaults,
+ $userSession,
$urlGenerator,
$imageManager,
$config,
diff --git a/apps/theming/tests/Themes/DefaultThemeTest.php b/apps/theming/tests/Themes/DefaultThemeTest.php
index 84430360897..c1de2810396 100644
--- a/apps/theming/tests/Themes/DefaultThemeTest.php
+++ b/apps/theming/tests/Themes/DefaultThemeTest.php
@@ -32,6 +32,7 @@ use OCP\Files\IAppData;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IURLGenerator;
+use OCP\IUserSession;
use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
@@ -52,6 +53,7 @@ class DefaultThemeTest extends TestCase {
protected function setUp(): void {
$this->themingDefaults = $this->createMock(ThemingDefaults::class);
+ $this->userSession = $this->createMock(IUserSession::class);
$this->urlGenerator = $this->createMock(IURLGenerator::class);
$this->imageManager = $this->createMock(ImageManager::class);
$this->config = $this->createMock(IConfig::class);
@@ -85,6 +87,7 @@ class DefaultThemeTest extends TestCase {
$this->defaultTheme = new DefaultTheme(
$util,
$this->themingDefaults,
+ $this->userSession,
$this->urlGenerator,
$this->imageManager,
$this->config,
diff --git a/apps/theming/tests/Themes/DyslexiaFontTest.php b/apps/theming/tests/Themes/DyslexiaFontTest.php
index 30472aeb6f2..77eb77a2818 100644
--- a/apps/theming/tests/Themes/DyslexiaFontTest.php
+++ b/apps/theming/tests/Themes/DyslexiaFontTest.php
@@ -56,6 +56,7 @@ class DyslexiaFontTest extends TestCase {
protected function setUp(): void {
$this->themingDefaults = $this->createMock(ThemingDefaults::class);
+ $this->userSession = $this->createMock(IUserSession::class);
$this->imageManager = $this->createMock(ImageManager::class);
$this->config = $this->createMock(IConfig::class);
$this->l10n = $this->createMock(IL10N::class);
@@ -93,6 +94,7 @@ class DyslexiaFontTest extends TestCase {
$this->dyslexiaFont = new DyslexiaFont(
$util,
$this->themingDefaults,
+ $this->userSession,
$this->urlGenerator,
$this->imageManager,
$this->config,
@@ -142,7 +144,7 @@ class DyslexiaFontTest extends TestCase {
/**
* @dataProvider dataTestGetCustomCss
- *
+ *
* Ensure the fonts are always loaded from the web root
* despite having url rewriting enabled or not
*
@@ -155,7 +157,7 @@ class DyslexiaFontTest extends TestCase {
->method('getSystemValue')
->with('htaccess.IgnoreFrontController', false)
->willReturn($prettyUrlsEnabled);
-
+
$this->assertStringContainsString("'$webRoot/apps/theming/fonts/OpenDyslexic-Regular.woff'", $this->dyslexiaFont->getCustomCss());
$this->assertStringNotContainsString('index.php', $this->dyslexiaFont->getCustomCss());
}
diff --git a/apps/theming/tests/ThemingDefaultsTest.php b/apps/theming/tests/ThemingDefaultsTest.php
index 20c153f1e96..5aa36211053 100644
--- a/apps/theming/tests/ThemingDefaultsTest.php
+++ b/apps/theming/tests/ThemingDefaultsTest.php
@@ -46,6 +46,7 @@ use OCP\IConfig;
use OCP\IL10N;
use OCP\INavigationManager;
use OCP\IURLGenerator;
+use OCP\IUserSession;
use Test\TestCase;
class ThemingDefaultsTest extends TestCase {
@@ -53,6 +54,8 @@ class ThemingDefaultsTest extends TestCase {
private $config;
/** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */
private $l10n;
+ /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */
+ private $userSession;
/** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */
private $urlGenerator;
/** @var \OC_Defaults|\PHPUnit\Framework\MockObject\MockObject */
@@ -78,6 +81,7 @@ class ThemingDefaultsTest extends TestCase {
parent::setUp();
$this->config = $this->createMock(IConfig::class);
$this->l10n = $this->createMock(IL10N::class);
+ $this->userSession = $this->createMock(IUserSession::class);
$this->urlGenerator = $this->createMock(IURLGenerator::class);
$this->cacheFactory = $this->createMock(ICacheFactory::class);
$this->cache = $this->createMock(ICache::class);
@@ -93,6 +97,7 @@ class ThemingDefaultsTest extends TestCase {
$this->template = new ThemingDefaults(
$this->config,
$this->l10n,
+ $this->userSession,
$this->urlGenerator,
$this->cacheFactory,
$this->util,
@@ -419,7 +424,7 @@ class ThemingDefaultsTest extends TestCase {
$this->config
->expects($this->once())
->method('getAppValue')
- ->with('theming', 'color', $this->defaults->getColorPrimary())
+ ->with('theming', 'color', null)
->willReturn($this->defaults->getColorPrimary());
$this->assertEquals($this->defaults->getColorPrimary(), $this->template->getColorPrimary());
@@ -429,7 +434,7 @@ class ThemingDefaultsTest extends TestCase {
$this->config
->expects($this->once())
->method('getAppValue')
- ->with('theming', 'color', $this->defaults->getColorPrimary())
+ ->with('theming', 'color', null)
->willReturn('#fff');
$this->assertEquals('#fff', $this->template->getColorPrimary());
@@ -542,7 +547,7 @@ class ThemingDefaultsTest extends TestCase {
->method('getAppValue')
->withConsecutive(
['theming', 'cachebuster', '0'],
- ['theming', 'color', $this->defaults->getColorPrimary()],
+ ['theming', 'color', null],
)->willReturnOnConsecutiveCalls(
'15',
$this->defaults->getColorPrimary(),
diff --git a/core/BackgroundJobs/BackgroundCleanupUpdaterBackupsJob.php b/core/BackgroundJobs/BackgroundCleanupUpdaterBackupsJob.php
index 7ab9fb47d54..df5d8de8eb7 100644
--- a/core/BackgroundJobs/BackgroundCleanupUpdaterBackupsJob.php
+++ b/core/BackgroundJobs/BackgroundCleanupUpdaterBackupsJob.php
@@ -45,14 +45,14 @@ class BackgroundCleanupUpdaterBackupsJob extends QueuedJob {
* This job cleans up all backups except the latest 3 from the updaters backup directory
*/
public function run($arguments) {
- $dataDir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data');
+ $updateDir = $this->config->getSystemValue('updatedirectory', null) ?? $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data');
$instanceId = $this->config->getSystemValue('instanceid', null);
if (!is_string($instanceId) || empty($instanceId)) {
return;
}
- $updaterFolderPath = $dataDir . '/updater-' . $instanceId;
+ $updaterFolderPath = $updateDir . '/updater-' . $instanceId;
$backupFolderPath = $updaterFolderPath . '/backups';
if (file_exists($backupFolderPath)) {
$this->log->info("$backupFolderPath exists - start to clean it up");
diff --git a/core/Controller/ReferenceApiController.php b/core/Controller/ReferenceApiController.php
index b9706796460..266532113d8 100644
--- a/core/Controller/ReferenceApiController.php
+++ b/core/Controller/ReferenceApiController.php
@@ -61,7 +61,7 @@ class ReferenceApiController extends \OCP\AppFramework\OCSController {
* @NoAdminRequired
*/
public function resolveOne(string $reference): DataResponse {
- $resolvedReference = $this->referenceManager->resolveReference($reference);
+ $resolvedReference = $this->referenceManager->resolveReference(trim($reference));
$response = new DataResponse(['references' => [ $reference => $resolvedReference ]]);
$response->cacheFor(3600, false, true);
diff --git a/core/css/guest.css b/core/css/guest.css
index 3883d66000e..c0a24e0d70c 100644
--- a/core/css/guest.css
+++ b/core/css/guest.css
@@ -23,7 +23,7 @@ body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
color: var(--color-text);
text-align: center;
- background-color: var(--color-primary);
+ background-color: var(--color-main-background-not-plain, var(--color-primary));
background-image: var(--image-background, var(--image-background-plain, url('../../../core/img/app-background.jpg'), linear-gradient(40deg, #0082c9 0%, #30b6ff 100%)));
background-attachment: fixed;
min-height: 100%; /* fix sticky footer */
diff --git a/core/css/public.css b/core/css/public.css
index 2ad3b80c52f..3e8ca2bbb34 100644
--- a/core/css/public.css
+++ b/core/css/public.css
@@ -49,7 +49,7 @@
text-align: center;
}
#body-public footer {
- position: sticky !important;
+ position: fixed;
display: flex;
align-items: center;
justify-content: center;
diff --git a/core/css/public.scss b/core/css/public.scss
index 514c3fbba70..0e75a938cfa 100644
--- a/core/css/public.scss
+++ b/core/css/public.scss
@@ -69,7 +69,7 @@ $footer-height: 65px;
/* public footer */
footer {
- position: sticky !important;
+ position: fixed;
display: flex;
align-items: center;
justify-content: center;
diff --git a/core/css/server.css b/core/css/server.css
index 014897459dd..da94d3e21eb 100644
--- a/core/css/server.css
+++ b/core/css/server.css
@@ -4998,7 +4998,7 @@ kbd {
text-align: center;
}
#body-public footer {
- position: sticky !important;
+ position: fixed;
display: flex;
align-items: center;
justify-content: center;
diff --git a/dist/theming-theming-settings.js b/dist/theming-theming-settings.js
index 88dbefbbde9..7929e8c2073 100644
--- a/dist/theming-theming-settings.js
+++ b/dist/theming-theming-settings.js
@@ -1,3 +1,3 @@
/*! For license information please see theming-theming-settings.js.LICENSE.txt */
-!function(){"use strict";var n,e={94818:function(n,e,r){var a=r(20144),o=r(79753),i=r(16453),c=r(4820),s=r(20571),u=r.n(s),d=r(13299),l=r.n(d),g=r(15168),p=r.n(g),h=function(n){return(0,o.generateFilePath)("theming","","img/background/")+n},m=function(n){var e,t,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",i=(null===(e=window.OCA)||void 0===e||null===(t=e.Theming)||void 0===t?void 0:t.enabledThemes)||[],c=0===i.length||"default"===i[0]?window.matchMedia("(prefers-color-scheme: dark)").matches:-1!==i.join("").indexOf("dark");return"default"===n?a&&"backgroundColor"!==a?(0,o.generateUrl)("/apps/theming/image/background")+"?v="+window.OCA.Theming.cacheBuster:h(c?"eduardo-neves-pedra-azul.jpg":"kamil-porembinski-clouds.jpg"):"custom"===n?(0,o.generateUrl)("/apps/theming/background")+"?v="+r:h(n)};function A(n,e,t,r,a,o,i){try{var c=n[o](i),s=c.value}catch(n){return void t(n)}c.done?e(s):Promise.resolve(s).then(r,a)}function f(n){return function(){var e=this,t=arguments;return new Promise((function(r,a){var o=n.apply(e,t);function i(n){A(o,r,a,i,c,"next",n)}function c(n){A(o,r,a,i,c,"throw",n)}i(void 0)}))}}var b=(0,i.loadState)("theming","shippedBackgrounds"),v={name:"BackgroundSettings",directives:{Tooltip:p()},props:{background:{type:String,default:"default"},themingDefaultBackground:{type:String,default:""}},data:function(){return{backgroundImage:(0,o.generateUrl)("/apps/theming/background")+"?v="+Date.now(),loading:!1}},computed:{shippedBackgrounds:function(){return Object.keys(b).map((function(n){return{name:n,url:h(n),preview:h("preview/"+n),details:b[n]}}))}},methods:{update:function(n){var e=this;return f(regeneratorRuntime.mark((function t(){var r,a;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(r="custom"===n.type||"default"===n.type?n.type:n.value,e.backgroundImage=m(r,n.version,e.themingDefaultBackground),"color"!==n.type&&("default"!==n.type||"backgroundColor"!==e.themingDefaultBackground)){t.next=6;break}return e.$emit("update:background",n),e.loading=!1,t.abrupt("return");case 6:(a=new Image).onload=function(){e.$emit("update:background",n),e.loading=!1},a.src=e.backgroundImage;case 9:case"end":return t.stop()}}),t)})))()},setDefault:function(){var n=this;return f(regeneratorRuntime.mark((function e(){var t;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n.loading="default",e.next=3,c.default.post((0,o.generateUrl)("/apps/theming/background/default"));case 3:t=e.sent,n.update(t.data);case 5:case"end":return e.stop()}}),e)})))()},setShipped:function(n){var e=this;return f(regeneratorRuntime.mark((function t(){var r;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return e.loading=n,t.next=3,c.default.post((0,o.generateUrl)("/apps/theming/background/shipped"),{value:n});case 3:r=t.sent,e.update(r.data);case 5:case"end":return t.stop()}}),t)})))()},setFile:function(n){var e=this;return f(regeneratorRuntime.mark((function t(){var r;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return e.loading="custom",t.next=3,c.default.post((0,o.generateUrl)("/apps/theming/background/custom"),{value:n});case 3:r=t.sent,e.update(r.data);case 5:case"end":return t.stop()}}),t)})))()},pickColor:function(){var n=this;return f(regeneratorRuntime.mark((function e(){var t,r;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n.loading="color",t=OCA&&OCA.Theming?OCA.Theming.color:"#0082c9",e.next=4,c.default.post((0,o.generateUrl)("/apps/theming/background/color"),{value:t});case 4:r=e.sent,n.update(r.data);case 6:case"end":return e.stop()}}),e)})))()},pickFile:function(){var n=this;window.OC.dialogs.filepicker(t("theming","Insert from {productName}",{productName:OC.theme.name}),(function(e,t){t===OC.dialogs.FILEPICKER_TYPE_CHOOSE&&n.setFile(e)}),!1,["image/png","image/gif","image/jpeg","image/svg"],!0,OC.dialogs.FILEPICKER_TYPE_CHOOSE)}}},k=v,C=r(93379),y=r.n(C),w=r(7795),_=r.n(w),x=r(90569),S=r.n(x),B=r(3565),T=r.n(B),I=r(19216),E=r.n(I),O=r(44589),D=r.n(O),P=r(35684),j={};j.styleTagTransform=D(),j.setAttributes=T(),j.insert=S().bind(null,"head"),j.domAPI=_(),j.insertStyleElement=E(),y()(P.Z,j),P.Z&&P.Z.locals&&P.Z.locals;var R=r(51900),q=(0,R.Z)(k,(function(){var n=this,e=n.$createElement,t=n._self._c||e;return t("div",{staticClass:"background-selector"},[t("button",{staticClass:"background filepicker",class:{active:"custom"===n.background},attrs:{tabindex:"0"},on:{click:n.pickFile}},[n._v("\n\t\t"+n._s(n.t("theming","Pick from Files"))+"\n\t")]),n._v(" "),t("button",{staticClass:"background default",class:{"icon-loading":"default"===n.loading,active:"default"===n.background},attrs:{tabindex:"0"},on:{click:n.setDefault}},[n._v("\n\t\t"+n._s(n.t("theming","Default image"))+"\n\t")]),n._v(" "),t("button",{staticClass:"background color",class:{active:n.background.startsWith("#")},attrs:{tabindex:"0"},on:{click:n.pickColor}},[n._v("\n\t\t"+n._s(n.t("theming","Plain background"))+"\n\t")]),n._v(" "),n._l(n.shippedBackgrounds,(function(e){return t("button",{directives:[{name:"tooltip",rawName:"v-tooltip",value:e.details.attribution,expression:"shippedBackground.details.attribution"}],key:e.name,staticClass:"background",class:{"icon-loading":n.loading===e.name,active:n.background===e.name},style:{"background-image":"url("+e.preview+")"},attrs:{tabindex:"0"},on:{click:function(t){return n.setShipped(e.name)}}})}))],2)}),[],!1,null,"5ccad868",null).exports,U={name:"ItemPreview",components:{NcCheckboxRadioSwitch:u()},props:{enforced:{type:Boolean,default:!1},selected:{type:Boolean,default:!1},theme:{type:Object,required:!0},type:{type:String,default:""},unique:{type:Boolean,default:!1}},computed:{switchType:function(){return this.unique?"switch":"radio"},name:function(){return this.unique?null:this.type},img:function(){return(0,o.generateFilePath)("theming","img",this.theme.id+".jpg")},checked:{get:function(){return this.selected},set:function(n){console.debug("Changed theme",this.theme.id,n),this.unique?this.$emit("change",{enabled:!0===n,id:this.theme.id}):this.$emit("change",{enabled:!0,id:this.theme.id})}}},methods:{onToggle:function(){"radio"!==this.switchType?this.checked=!this.checked:this.checked=!0}}},Z=r(83005),F={};F.styleTagTransform=D(),F.setAttributes=T(),F.insert=S().bind(null,"head"),F.domAPI=_(),F.insertStyleElement=E(),y()(Z.Z,F),Z.Z&&Z.Z.locals&&Z.Z.locals;var L=(0,R.Z)(U,(function(){var n=this,e=n.$createElement,t=n._self._c||e;return t("div",{staticClass:"theming__preview",class:"theming__preview--"+n.theme.id},[t("div",{staticClass:"theming__preview-image",style:{backgroundImage:"url("+n.img+")"},on:{click:n.onToggle}}),n._v(" "),t("div",{staticClass:"theming__preview-description"},[t("h3",[n._v(n._s(n.theme.title))]),n._v(" "),t("p",[n._v(n._s(n.theme.description))]),n._v(" "),n.enforced?t("span",{staticClass:"theming__preview-warning",attrs:{role:"note"}},[n._v("\n\t\t\t"+n._s(n.t("theming","Theme selection is enforced"))+"\n\t\t")]):n._e(),n._v(" "),t("NcCheckboxRadioSwitch",{staticClass:"theming__preview-toggle",attrs:{checked:n.checked,disabled:n.enforced,name:n.name,type:n.switchType},on:{"update:checked":function(e){n.checked=e}}},[n._v("\n\t\t\t"+n._s(n.theme.enableLabel)+"\n\t\t")])],1)])}),[],!1,null,"37ca8ab2",null).exports;function G(n){return function(n){if(Array.isArray(n))return N(n)}(n)||function(n){if("undefined"!=typeof Symbol&&null!=n[Symbol.iterator]||null!=n["@@iterator"])return Array.from(n)}(n)||function(n,e){if(n){if("string"==typeof n)return N(n,e);var t=Object.prototype.toString.call(n).slice(8,-1);return"Object"===t&&n.constructor&&(t=n.constructor.name),"Map"===t||"Set"===t?Array.from(n):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?N(n,e):void 0}}(n)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function N(n,e){(null==e||e>n.length)&&(e=n.length);for(var t=0,r=new Array(e);t<e;t++)r[t]=n[t];return r}function $(n,e,t,r,a,o,i){try{var c=n[o](i),s=c.value}catch(n){return void t(n)}c.done?e(s):Promise.resolve(s).then(r,a)}function W(n){return function(){var e=this,t=arguments;return new Promise((function(r,a){var o=n.apply(e,t);function i(n){$(o,r,a,i,c,"next",n)}function c(n){$(o,r,a,i,c,"throw",n)}i(void 0)}))}}var K=(0,i.loadState)("theming","themes",[]),M=(0,i.loadState)("theming","enforceTheme",""),z=(0,i.loadState)("theming","shortcutsDisabled",!1),Y=(0,i.loadState)("theming","background"),H=(0,i.loadState)("theming","backgroundVersion"),V=(0,i.loadState)("theming","themingDefaultBackground"),J=(0,i.loadState)("theming","shippedBackgrounds");console.debug("Available themes",K);var Q={name:"UserThemes",components:{ItemPreview:L,NcCheckboxRadioSwitch:u(),NcSettingsSection:l(),BackgroundSettings:q},data:function(){return{availableThemes:K,enforceTheme:M,shortcutsDisabled:z,background:Y,backgroundVersion:H,themingDefaultBackground:V}},computed:{themes:function(){return this.availableThemes.filter((function(n){return 1===n.type}))},fonts:function(){return this.availableThemes.filter((function(n){return 2===n.type}))},selectedTheme:function(){return this.themes.find((function(n){return!0===n.enabled}))||this.themes[0]},description:function(){return t("theming","Universal access is very important to us. We follow web standards and check to make everything usable also without mouse, and assistive software such as screenreaders. We aim to be compliant with the {guidelines}Web Content Accessibility Guidelines{linkend} 2.1 on AA level, with the high contrast theme even on AAA level.").replace("{guidelines}",this.guidelinesLink).replace("{linkend}","</a>")},guidelinesLink:function(){return'<a target="_blank" href="https://www.w3.org/WAI/standards-guidelines/wcag/" rel="noreferrer nofollow">'},descriptionDetail:function(){return t("theming","If you find any issues, do not hesitate to report them on {issuetracker}our issue tracker{linkend}. And if you want to get involved, come join {designteam}our design team{linkend}!").replace("{issuetracker}",this.issuetrackerLink).replace("{designteam}",this.designteamLink).replace(/\{linkend\}/g,"</a>")},issuetrackerLink:function(){return'<a target="_blank" href="https://github.com/nextcloud/server/issues/" rel="noreferrer nofollow">'},designteamLink:function(){return'<a target="_blank" href="https://nextcloud.com/design" rel="noreferrer nofollow">'}},mounted:function(){this.updateGlobalStyles()},watch:{shortcutsDisabled:function(n){this.changeShortcutsDisabled(n)}},methods:{updateBackground:function(n){this.background="custom"===n.type||"default"===n.type?n.type:n.value,this.backgroundVersion=n.version,this.updateGlobalStyles(),this.$emit("update:background")},updateGlobalStyles:function(){var n;"dark"===(null===(n=J[this.background])||void 0===n?void 0:n.theming)?(document.querySelector("#header").style.setProperty("--primary-invert-if-bright","invert(100%)"),document.querySelector("#header").style.setProperty("--color-primary-text","#000000")):(document.querySelector("#header").style.setProperty("--primary-invert-if-bright","no"),document.querySelector("#header").style.setProperty("--color-primary-text","#ffffff"))},changeTheme:function(n){var e=n.enabled,t=n.id;this.themes.forEach((function(n){n.id===t&&e?n.enabled=!0:n.enabled=!1})),this.updateBodyAttributes(),this.selectItem(e,t)},changeFont:function(n){var e=n.enabled,t=n.id;this.fonts.forEach((function(n){n.id===t&&e?n.enabled=!0:n.enabled=!1})),this.updateBodyAttributes(),this.selectItem(e,t)},changeShortcutsDisabled:function(n){return W(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!n){e.next=5;break}return e.next=3,(0,c.default)({url:(0,o.generateOcsUrl)("apps/provisioning_api/api/v1/config/users/{appId}/{configKey}",{appId:"theming",configKey:"shortcuts_disabled"}),data:{configValue:"yes"},method:"POST"});case 3:e.next=7;break;case 5:return e.next=7,(0,c.default)({url:(0,o.generateOcsUrl)("apps/provisioning_api/api/v1/config/users/{appId}/{configKey}",{appId:"theming",configKey:"shortcuts_disabled"}),method:"DELETE"});case 7:case"end":return e.stop()}}),e)})))()},updateBodyAttributes:function(){var n=this.themes.filter((function(n){return!0===n.enabled})).map((function(n){return n.id})),e=this.fonts.filter((function(n){return!0===n.enabled})).map((function(n){return n.id}));this.themes.forEach((function(n){document.body.toggleAttribute("data-theme-".concat(n.id),n.enabled)})),this.fonts.forEach((function(n){document.body.toggleAttribute("data-theme-".concat(n.id),n.enabled)})),document.body.setAttribute("data-themes",[].concat(G(n),G(e)).join(","))},selectItem:function(n,e){return W(regeneratorRuntime.mark((function r(){return regeneratorRuntime.wrap((function(r){for(;;)switch(r.prev=r.next){case 0:if(r.prev=0,!n){r.next=6;break}return r.next=4,(0,c.default)({url:(0,o.generateOcsUrl)("apps/theming/api/v1/theme/{themeId}/enable",{themeId:e}),method:"PUT"});case 4:r.next=8;break;case 6:return r.next=8,(0,c.default)({url:(0,o.generateOcsUrl)("apps/theming/api/v1/theme/{themeId}",{themeId:e}),method:"DELETE"});case 8:r.next=14;break;case 10:r.prev=10,r.t0=r.catch(0),console.error(r.t0,r.t0.response),OC.Notification.showTemporary(t("theming",r.t0.response.data.ocs.meta.message+". Unable to apply the setting."));case 14:case"end":return r.stop()}}),r,null,[[0,10]])})))()}}},X=r(41936),nn={};nn.styleTagTransform=D(),nn.setAttributes=T(),nn.insert=S().bind(null,"head"),nn.domAPI=_(),nn.insertStyleElement=E(),y()(X.Z,nn),X.Z&&X.Z.locals&&X.Z.locals;var en=(0,R.Z)(Q,(function(){var n=this,e=n.$createElement,t=n._self._c||e;return t("section",[t("NcSettingsSection",{staticClass:"theming",attrs:{title:n.t("theming","Appearance and accessibility"),"limit-width":!1}},[t("p",{domProps:{innerHTML:n._s(n.description)}}),n._v(" "),t("p",{domProps:{innerHTML:n._s(n.descriptionDetail)}}),n._v(" "),t("div",{staticClass:"theming__preview-list"},n._l(n.themes,(function(e){return t("ItemPreview",{key:e.id,attrs:{enforced:e.id===n.enforceTheme,selected:n.selectedTheme.id===e.id,theme:e,unique:1===n.themes.length,type:"theme"},on:{change:n.changeTheme}})})),1),n._v(" "),t("div",{staticClass:"theming__preview-list"},n._l(n.fonts,(function(e){return t("ItemPreview",{key:e.id,attrs:{selected:e.enabled,theme:e,unique:1===n.fonts.length,type:"font"},on:{change:n.changeFont}})})),1)]),n._v(" "),t("NcSettingsSection",{attrs:{title:n.t("theming","Keyboard shortcuts")}},[t("p",[n._v(n._s(n.t("theming","In some cases keyboard shortcuts can interfer with accessibility tools. In order to allow focusing on your tool correctly you can disable all keyboard shortcuts here. This will also disable all available shortcuts in apps.")))]),n._v(" "),t("NcCheckboxRadioSwitch",{staticClass:"theming__preview-toggle",attrs:{checked:n.shortcutsDisabled,name:"shortcuts_disabled",type:"switch"},on:{"update:checked":function(e){n.shortcutsDisabled=e},change:n.changeShortcutsDisabled}},[n._v("\n\t\t\t"+n._s(n.t("theming","Disable all keyboard shortcuts"))+"\n\t\t")])],1),n._v(" "),t("NcSettingsSection",{staticClass:"background",attrs:{title:n.t("theming","Background")}},[t("p",[n._v(n._s(n.t("theming","Set a custom background")))]),n._v(" "),t("BackgroundSettings",{staticClass:"background__grid",attrs:{background:n.background,"theming-default-background":n.themingDefaultBackground},on:{"update:background":n.updateBackground}})],1)],1)}),[],!1,null,"a788b9b8",null).exports;function tn(n,e){(null==e||e>n.length)&&(e=n.length);for(var t=0,r=new Array(e);t<e;t++)r[t]=n[t];return r}a.ZP.prototype.OC=OC,a.ZP.prototype.t=t;var rn=new(a.ZP.extend(en));rn.$mount("#theming"),rn.$on("update:background",(function(){var n;(n=document.head.querySelectorAll("link.theme"),function(n){if(Array.isArray(n))return tn(n)}(n)||function(n){if("undefined"!=typeof Symbol&&null!=n[Symbol.iterator]||null!=n["@@iterator"])return Array.from(n)}(n)||function(n,e){if(n){if("string"==typeof n)return tn(n,e);var t=Object.prototype.toString.call(n).slice(8,-1);return"Object"===t&&n.constructor&&(t=n.constructor.name),"Map"===t||"Set"===t?Array.from(n):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?tn(n,e):void 0}}(n)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()).forEach((function(n){var e=new URL(n.href);e.searchParams.set("v",Date.now());var t=n.cloneNode();t.href=e.toString(),t.onload=function(){return n.remove()},document.head.append(t)}))}))},41936:function(n,e,t){var r=t(87537),a=t.n(r),o=t(23645),i=t.n(o)()(a());i.push([n.id,".theming p[data-v-a788b9b8]{max-width:800px}.theming[data-v-a788b9b8] a{font-weight:bold}.theming[data-v-a788b9b8] a:hover,.theming[data-v-a788b9b8] a:focus{text-decoration:underline}.theming__preview-list[data-v-a788b9b8]{--gap: 30px;display:grid;margin-top:var(--gap);column-gap:var(--gap);row-gap:var(--gap);grid-template-columns:1fr 1fr}.background__grid[data-v-a788b9b8]{margin-top:30px}@media(max-width: 1440px){.theming__preview-list[data-v-a788b9b8]{display:flex;flex-direction:column}}","",{version:3,sources:["webpack://./apps/theming/src/UserThemes.vue"],names:[],mappings:"AA+RC,4BACC,eAAA,CAID,4BACC,gBAAA,CAEA,oEAEC,yBAAA,CAIF,wCACC,WAAA,CAEA,YAAA,CACA,qBAAA,CACA,qBAAA,CACA,kBAAA,CACA,6BAAA,CAKD,mCACC,eAAA,CAIF,0BACC,wCACC,YAAA,CACA,qBAAA,CAAA",sourcesContent:["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.theming {\n\t// Limit width of settings sections for readability\n\tp {\n\t\tmax-width: 800px;\n\t}\n\n\t// Proper highlight for links and focus feedback\n\t&::v-deep a {\n\t\tfont-weight: bold;\n\n\t\t&:hover,\n\t\t&:focus {\n\t\t\ttext-decoration: underline;\n\t\t}\n\t}\n\n\t&__preview-list {\n\t\t--gap: 30px;\n\n\t\tdisplay: grid;\n\t\tmargin-top: var(--gap);\n\t\tcolumn-gap: var(--gap);\n\t\trow-gap: var(--gap);\n\t\tgrid-template-columns: 1fr 1fr;\n\t}\n}\n\n.background {\n\t&__grid {\n\t\tmargin-top: 30px;\n\t}\n}\n\n@media (max-width: 1440px) {\n\t.theming__preview-list {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t}\n}\n"],sourceRoot:""}]),e.Z=i},35684:function(n,e,t){var r=t(87537),a=t.n(r),o=t(23645),i=t.n(o)()(a());i.push([n.id,'.background-selector[data-v-5ccad868]{display:flex;flex-wrap:wrap;justify-content:center}.background-selector .background[data-v-5ccad868]{width:176px;height:96px;margin:8px;background-size:cover;background-position:center center;text-align:center;border-radius:var(--border-radius-large);border:2px solid var(--color-main-background);overflow:hidden}.background-selector .background.current[data-v-5ccad868]{background-image:var(--color-background-dark)}.background-selector .background.filepicker[data-v-5ccad868],.background-selector .background.default[data-v-5ccad868],.background-selector .background.color[data-v-5ccad868]{border-color:var(--color-border)}.background-selector .background.color[data-v-5ccad868]{background-color:var(--color-primary);color:var(--color-primary-text)}.background-selector .background.active[data-v-5ccad868],.background-selector .background[data-v-5ccad868]:hover,.background-selector .background[data-v-5ccad868]:focus{border:2px solid var(--color-primary)}.background-selector .background.active[data-v-5ccad868]:not(.icon-loading):after{background-image:var(--icon-checkmark-white);background-repeat:no-repeat;background-position:center;background-size:44px;content:"";display:block;height:100%}',"",{version:3,sources:["webpack://./apps/theming/src/components/BackgroundSettings.vue"],names:[],mappings:"AAoJA,sCACC,YAAA,CACA,cAAA,CACA,sBAAA,CAEA,kDACC,WAAA,CACA,WAAA,CACA,UAAA,CACA,qBAAA,CACA,iCAAA,CACA,iBAAA,CACA,wCAAA,CACA,6CAAA,CACA,eAAA,CAEA,0DACC,6CAAA,CAGD,+KACC,gCAAA,CAGD,wDACC,qCAAA,CACA,+BAAA,CAGD,yKAGC,qCAAA,CAGD,kFACC,4CAAA,CACA,2BAAA,CACA,0BAAA,CACA,oBAAA,CACA,UAAA,CACA,aAAA,CACA,WAAA",sourcesContent:["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.background-selector {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tjustify-content: center;\n\n\t.background {\n\t\twidth: 176px;\n\t\theight: 96px;\n\t\tmargin: 8px;\n\t\tbackground-size: cover;\n\t\tbackground-position: center center;\n\t\ttext-align: center;\n\t\tborder-radius: var(--border-radius-large);\n\t\tborder: 2px solid var(--color-main-background);\n\t\toverflow: hidden;\n\n\t\t&.current {\n\t\t\tbackground-image: var(--color-background-dark);\n\t\t}\n\n\t\t&.filepicker, &.default, &.color {\n\t\t\tborder-color: var(--color-border);\n\t\t}\n\n\t\t&.color {\n\t\t\tbackground-color: var(--color-primary);\n\t\t\tcolor: var(--color-primary-text);\n\t\t}\n\n\t\t&.active,\n\t\t&:hover,\n\t\t&:focus {\n\t\t\tborder: 2px solid var(--color-primary);\n\t\t}\n\n\t\t&.active:not(.icon-loading):after {\n\t\t\tbackground-image: var(--icon-checkmark-white);\n\t\t\tbackground-repeat: no-repeat;\n\t\t\tbackground-position: center;\n\t\t\tbackground-size: 44px;\n\t\t\tcontent: '';\n\t\t\tdisplay: block;\n\t\t\theight: 100%;\n\t\t}\n\t}\n}\n"],sourceRoot:""}]),e.Z=i},83005:function(n,e,t){var r=t(87537),a=t.n(r),o=t(23645),i=t.n(o)()(a());i.push([n.id,".theming__preview[data-v-37ca8ab2]{--ratio: 16;position:relative;display:flex;justify-content:flex-start;max-width:800px}.theming__preview[data-v-37ca8ab2],.theming__preview *[data-v-37ca8ab2]{user-select:none}.theming__preview-image[data-v-37ca8ab2]{flex-basis:calc(16px*var(--ratio));flex-shrink:0;height:calc(10px*var(--ratio));margin-right:var(--gap);cursor:pointer;border-radius:var(--border-radius);background-repeat:no-repeat;background-position:top left;background-size:cover}.theming__preview-description[data-v-37ca8ab2]{display:flex;flex-direction:column}.theming__preview-description label[data-v-37ca8ab2]{padding:12px 0}.theming__preview--default[data-v-37ca8ab2]{grid-column:span 2}.theming__preview-warning[data-v-37ca8ab2]{color:var(--color-warning)}@media(max-width: 682.6666666667px){.theming__preview[data-v-37ca8ab2]{flex-direction:column}.theming__preview-image[data-v-37ca8ab2]{margin:0}}","",{version:3,sources:["webpack://./apps/theming/src/components/ItemPreview.vue"],names:[],mappings:"AAiGA,mCAEC,WAAA,CAEA,iBAAA,CACA,YAAA,CACA,0BAAA,CACA,eAAA,CAEA,wEAEC,gBAAA,CAGD,yCACC,kCAAA,CACA,aAAA,CACA,8BAAA,CACA,uBAAA,CACA,cAAA,CACA,kCAAA,CACA,2BAAA,CACA,4BAAA,CACA,qBAAA,CAGD,+CACC,YAAA,CACA,qBAAA,CAEA,qDACC,cAAA,CAIF,4CACC,kBAAA,CAGD,2CACC,0BAAA,CAIF,oCACC,mCACC,qBAAA,CAEA,yCACC,QAAA,CAAA",sourcesContent:["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.theming__preview {\n\t// We make previews on 16/10 screens\n\t--ratio: 16;\n\n\tposition: relative;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\tmax-width: 800px;\n\n\t&,\n\t* {\n\t\tuser-select: none;\n\t}\n\n\t&-image {\n\t\tflex-basis: calc(16px * var(--ratio));\n\t\tflex-shrink: 0;\n\t\theight: calc(10px * var(--ratio));\n\t\tmargin-right: var(--gap);\n\t\tcursor: pointer;\n\t\tborder-radius: var(--border-radius);\n\t\tbackground-repeat: no-repeat;\n\t\tbackground-position: top left;\n\t\tbackground-size: cover;\n\t}\n\n\t&-description {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\n\t\tlabel {\n\t\t\tpadding: 12px 0;\n\t\t}\n\t}\n\n\t&--default {\n\t\tgrid-column: span 2;\n\t}\n\n\t&-warning {\n\t\tcolor: var(--color-warning);\n\t}\n}\n\n@media (max-width: (1024px / 1.5)) {\n\t.theming__preview {\n\t\tflex-direction: column;\n\n\t\t&-image {\n\t\t\tmargin: 0;\n\t\t}\n\t}\n}\n\n"],sourceRoot:""}]),e.Z=i}},r={};function a(n){var t=r[n];if(void 0!==t)return t.exports;var o=r[n]={id:n,loaded:!1,exports:{}};return e[n].call(o.exports,o,o.exports,a),o.loaded=!0,o.exports}a.m=e,a.amdD=function(){throw new Error("define cannot be used indirect")},a.amdO={},n=[],a.O=function(e,t,r,o){if(!t){var i=1/0;for(d=0;d<n.length;d++){t=n[d][0],r=n[d][1],o=n[d][2];for(var c=!0,s=0;s<t.length;s++)(!1&o||i>=o)&&Object.keys(a.O).every((function(n){return a.O[n](t[s])}))?t.splice(s--,1):(c=!1,o<i&&(i=o));if(c){n.splice(d--,1);var u=r();void 0!==u&&(e=u)}}return e}o=o||0;for(var d=n.length;d>0&&n[d-1][2]>o;d--)n[d]=n[d-1];n[d]=[t,r,o]},a.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return a.d(e,{a:e}),e},a.d=function(n,e){for(var t in e)a.o(e,t)&&!a.o(n,t)&&Object.defineProperty(n,t,{enumerable:!0,get:e[t]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(n){if("object"==typeof window)return window}}(),a.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},a.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},a.nmd=function(n){return n.paths=[],n.children||(n.children=[]),n},a.j=6755,function(){a.b=document.baseURI||self.location.href;var n={6755:0};a.O.j=function(e){return 0===n[e]};var e=function(e,t){var r,o,i=t[0],c=t[1],s=t[2],u=0;if(i.some((function(e){return 0!==n[e]}))){for(r in c)a.o(c,r)&&(a.m[r]=c[r]);if(s)var d=s(a)}for(e&&e(t);u<i.length;u++)o=i[u],a.o(n,o)&&n[o]&&n[o][0](),n[o]=0;return a.O(d)},t=self.webpackChunknextcloud=self.webpackChunknextcloud||[];t.forEach(e.bind(null,0)),t.push=e.bind(null,t.push.bind(t))}(),a.nc=void 0;var o=a.O(void 0,[7874],(function(){return a(94818)}));o=a.O(o)}();
-//# sourceMappingURL=theming-theming-settings.js.map?v=7c6c2a5e9a4ab6b66a54 \ No newline at end of file
+!function(){"use strict";var n,e={58078:function(n,e,r){var a=r(20144),o=r(79753),i=r(16453),c=r(4820),s=r(20571),u=r.n(s),d=r(13299),l=r.n(d),g=r(15168),p=r.n(g),h=function(n){return(0,o.generateFilePath)("theming","","img/background/")+n},m=function(n){var e,t,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",i=(null===(e=window.OCA)||void 0===e||null===(t=e.Theming)||void 0===t?void 0:t.enabledThemes)||[],c=0===i.length||"default"===i[0]?window.matchMedia("(prefers-color-scheme: dark)").matches:-1!==i.join("").indexOf("dark");return"default"===n?a&&"backgroundColor"!==a?(0,o.generateUrl)("/apps/theming/image/background")+"?v="+window.OCA.Theming.cacheBuster:h(c?"eduardo-neves-pedra-azul.jpg":"kamil-porembinski-clouds.jpg"):"custom"===n?(0,o.generateUrl)("/apps/theming/background")+"?v="+r:h(n)};function A(n,e,t,r,a,o,i){try{var c=n[o](i),s=c.value}catch(n){return void t(n)}c.done?e(s):Promise.resolve(s).then(r,a)}function f(n){return function(){var e=this,t=arguments;return new Promise((function(r,a){var o=n.apply(e,t);function i(n){A(o,r,a,i,c,"next",n)}function c(n){A(o,r,a,i,c,"throw",n)}i(void 0)}))}}var b=(0,i.loadState)("theming","shippedBackgrounds"),v={name:"BackgroundSettings",directives:{Tooltip:p()},props:{background:{type:String,default:"default"},themingDefaultBackground:{type:String,default:""}},data:function(){return{backgroundImage:(0,o.generateUrl)("/apps/theming/background")+"?v="+Date.now(),loading:!1}},computed:{shippedBackgrounds:function(){return Object.keys(b).map((function(n){return{name:n,url:h(n),preview:h("preview/"+n),details:b[n]}}))}},methods:{update:function(n){var e=this;return f(regeneratorRuntime.mark((function t(){var r,a;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(r="custom"===n.type||"default"===n.type?n.type:n.value,e.backgroundImage=m(r,n.version,e.themingDefaultBackground),"color"!==n.type&&("default"!==n.type||"backgroundColor"!==e.themingDefaultBackground)){t.next=6;break}return e.$emit("update:background",n),e.loading=!1,t.abrupt("return");case 6:(a=new Image).onload=function(){e.$emit("update:background",n),e.loading=!1},a.src=e.backgroundImage;case 9:case"end":return t.stop()}}),t)})))()},setDefault:function(){var n=this;return f(regeneratorRuntime.mark((function e(){var t;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n.loading="default",e.next=3,c.default.post((0,o.generateUrl)("/apps/theming/background/default"));case 3:t=e.sent,n.update(t.data);case 5:case"end":return e.stop()}}),e)})))()},setShipped:function(n){var e=this;return f(regeneratorRuntime.mark((function t(){var r;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return e.loading=n,t.next=3,c.default.post((0,o.generateUrl)("/apps/theming/background/shipped"),{value:n});case 3:r=t.sent,e.update(r.data);case 5:case"end":return t.stop()}}),t)})))()},setFile:function(n){var e=this;return f(regeneratorRuntime.mark((function t(){var r;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return e.loading="custom",t.next=3,c.default.post((0,o.generateUrl)("/apps/theming/background/custom"),{value:n});case 3:r=t.sent,e.update(r.data);case 5:case"end":return t.stop()}}),t)})))()},pickColor:function(){var n=this;return f(regeneratorRuntime.mark((function e(){var t,r;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n.loading="color",t=OCA&&OCA.Theming?OCA.Theming.color:"#0082c9",e.next=4,c.default.post((0,o.generateUrl)("/apps/theming/background/color"),{value:t});case 4:r=e.sent,n.update(r.data);case 6:case"end":return e.stop()}}),e)})))()},pickFile:function(){var n=this;window.OC.dialogs.filepicker(t("theming","Insert from {productName}",{productName:OC.theme.name}),(function(e,t){t===OC.dialogs.FILEPICKER_TYPE_CHOOSE&&n.setFile(e)}),!1,["image/png","image/gif","image/jpeg","image/svg"],!0,OC.dialogs.FILEPICKER_TYPE_CHOOSE)}}},k=v,C=r(93379),y=r.n(C),w=r(7795),_=r.n(w),x=r(90569),S=r.n(x),B=r(3565),T=r.n(B),I=r(19216),E=r.n(I),O=r(44589),D=r.n(O),P=r(79993),j={};j.styleTagTransform=D(),j.setAttributes=T(),j.insert=S().bind(null,"head"),j.domAPI=_(),j.insertStyleElement=E(),y()(P.Z,j),P.Z&&P.Z.locals&&P.Z.locals;var R=r(51900),U=(0,R.Z)(k,(function(){var n=this,e=n.$createElement,t=n._self._c||e;return t("div",{staticClass:"background-selector"},[t("button",{staticClass:"background filepicker",class:{active:"custom"===n.background},attrs:{tabindex:"0"},on:{click:n.pickFile}},[n._v("\n\t\t"+n._s(n.t("theming","Pick from Files"))+"\n\t")]),n._v(" "),t("button",{staticClass:"background default",class:{"icon-loading":"default"===n.loading,active:"default"===n.background},attrs:{tabindex:"0"},on:{click:n.setDefault}},[n._v("\n\t\t"+n._s(n.t("theming","Default image"))+"\n\t")]),n._v(" "),t("button",{staticClass:"background color",class:{active:n.background.startsWith("#")},attrs:{tabindex:"0"},on:{click:n.pickColor}},[n._v("\n\t\t"+n._s(n.t("theming","Plain background"))+"\n\t")]),n._v(" "),n._l(n.shippedBackgrounds,(function(e){return t("button",{directives:[{name:"tooltip",rawName:"v-tooltip",value:e.details.attribution,expression:"shippedBackground.details.attribution"}],key:e.name,staticClass:"background",class:{"icon-loading":n.loading===e.name,active:n.background===e.name},style:{"background-image":"url("+e.preview+")"},attrs:{tabindex:"0"},on:{click:function(t){return n.setShipped(e.name)}}})}))],2)}),[],!1,null,"48e565ba",null).exports,q={name:"ItemPreview",components:{NcCheckboxRadioSwitch:u()},props:{enforced:{type:Boolean,default:!1},selected:{type:Boolean,default:!1},theme:{type:Object,required:!0},type:{type:String,default:""},unique:{type:Boolean,default:!1}},computed:{switchType:function(){return this.unique?"switch":"radio"},name:function(){return this.unique?null:this.type},img:function(){return(0,o.generateFilePath)("theming","img",this.theme.id+".jpg")},checked:{get:function(){return this.selected},set:function(n){console.debug("Changed theme",this.theme.id,n),this.unique?this.$emit("change",{enabled:!0===n,id:this.theme.id}):this.$emit("change",{enabled:!0,id:this.theme.id})}}},methods:{onToggle:function(){"radio"!==this.switchType?this.checked=!this.checked:this.checked=!0}}},Z=r(83005),F={};F.styleTagTransform=D(),F.setAttributes=T(),F.insert=S().bind(null,"head"),F.domAPI=_(),F.insertStyleElement=E(),y()(Z.Z,F),Z.Z&&Z.Z.locals&&Z.Z.locals;var L=(0,R.Z)(q,(function(){var n=this,e=n.$createElement,t=n._self._c||e;return t("div",{staticClass:"theming__preview",class:"theming__preview--"+n.theme.id},[t("div",{staticClass:"theming__preview-image",style:{backgroundImage:"url("+n.img+")"},on:{click:n.onToggle}}),n._v(" "),t("div",{staticClass:"theming__preview-description"},[t("h3",[n._v(n._s(n.theme.title))]),n._v(" "),t("p",[n._v(n._s(n.theme.description))]),n._v(" "),n.enforced?t("span",{staticClass:"theming__preview-warning",attrs:{role:"note"}},[n._v("\n\t\t\t"+n._s(n.t("theming","Theme selection is enforced"))+"\n\t\t")]):n._e(),n._v(" "),t("NcCheckboxRadioSwitch",{staticClass:"theming__preview-toggle",attrs:{checked:n.checked,disabled:n.enforced,name:n.name,type:n.switchType},on:{"update:checked":function(e){n.checked=e}}},[n._v("\n\t\t\t"+n._s(n.theme.enableLabel)+"\n\t\t")])],1)])}),[],!1,null,"37ca8ab2",null).exports;function G(n){return function(n){if(Array.isArray(n))return N(n)}(n)||function(n){if("undefined"!=typeof Symbol&&null!=n[Symbol.iterator]||null!=n["@@iterator"])return Array.from(n)}(n)||function(n,e){if(n){if("string"==typeof n)return N(n,e);var t=Object.prototype.toString.call(n).slice(8,-1);return"Object"===t&&n.constructor&&(t=n.constructor.name),"Map"===t||"Set"===t?Array.from(n):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?N(n,e):void 0}}(n)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function N(n,e){(null==e||e>n.length)&&(e=n.length);for(var t=0,r=new Array(e);t<e;t++)r[t]=n[t];return r}function $(n,e,t,r,a,o,i){try{var c=n[o](i),s=c.value}catch(n){return void t(n)}c.done?e(s):Promise.resolve(s).then(r,a)}function W(n){return function(){var e=this,t=arguments;return new Promise((function(r,a){var o=n.apply(e,t);function i(n){$(o,r,a,i,c,"next",n)}function c(n){$(o,r,a,i,c,"throw",n)}i(void 0)}))}}var K=(0,i.loadState)("theming","themes",[]),M=(0,i.loadState)("theming","enforceTheme",""),z=(0,i.loadState)("theming","shortcutsDisabled",!1),Y=(0,i.loadState)("theming","background"),H=(0,i.loadState)("theming","backgroundVersion"),V=(0,i.loadState)("theming","themingDefaultBackground"),J=(0,i.loadState)("theming","shippedBackgrounds");console.debug("Available themes",K);var Q={name:"UserThemes",components:{ItemPreview:L,NcCheckboxRadioSwitch:u(),NcSettingsSection:l(),BackgroundSettings:U},data:function(){return{availableThemes:K,enforceTheme:M,shortcutsDisabled:z,background:Y,backgroundVersion:H,themingDefaultBackground:V}},computed:{themes:function(){return this.availableThemes.filter((function(n){return 1===n.type}))},fonts:function(){return this.availableThemes.filter((function(n){return 2===n.type}))},selectedTheme:function(){return this.themes.find((function(n){return!0===n.enabled}))||this.themes[0]},description:function(){return t("theming","Universal access is very important to us. We follow web standards and check to make everything usable also without mouse, and assistive software such as screenreaders. We aim to be compliant with the {guidelines}Web Content Accessibility Guidelines{linkend} 2.1 on AA level, with the high contrast theme even on AAA level.").replace("{guidelines}",this.guidelinesLink).replace("{linkend}","</a>")},guidelinesLink:function(){return'<a target="_blank" href="https://www.w3.org/WAI/standards-guidelines/wcag/" rel="noreferrer nofollow">'},descriptionDetail:function(){return t("theming","If you find any issues, do not hesitate to report them on {issuetracker}our issue tracker{linkend}. And if you want to get involved, come join {designteam}our design team{linkend}!").replace("{issuetracker}",this.issuetrackerLink).replace("{designteam}",this.designteamLink).replace(/\{linkend\}/g,"</a>")},issuetrackerLink:function(){return'<a target="_blank" href="https://github.com/nextcloud/server/issues/" rel="noreferrer nofollow">'},designteamLink:function(){return'<a target="_blank" href="https://nextcloud.com/design" rel="noreferrer nofollow">'}},mounted:function(){this.updateGlobalStyles()},watch:{shortcutsDisabled:function(n){this.changeShortcutsDisabled(n)}},methods:{updateBackground:function(n){this.background="custom"===n.type||"default"===n.type?n.type:n.value,this.backgroundVersion=n.version,this.updateGlobalStyles(),this.$emit("update:background")},updateGlobalStyles:function(){var n;"dark"===(null===(n=J[this.background])||void 0===n?void 0:n.theming)?(document.querySelector("#header").style.setProperty("--primary-invert-if-bright","invert(100%)"),document.querySelector("#header").style.setProperty("--color-primary-text","#000000")):(document.querySelector("#header").style.setProperty("--primary-invert-if-bright","no"),document.querySelector("#header").style.setProperty("--color-primary-text","#ffffff"))},changeTheme:function(n){var e=n.enabled,t=n.id;this.themes.forEach((function(n){n.id===t&&e?n.enabled=!0:n.enabled=!1})),this.updateBodyAttributes(),this.selectItem(e,t)},changeFont:function(n){var e=n.enabled,t=n.id;this.fonts.forEach((function(n){n.id===t&&e?n.enabled=!0:n.enabled=!1})),this.updateBodyAttributes(),this.selectItem(e,t)},changeShortcutsDisabled:function(n){return W(regeneratorRuntime.mark((function e(){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!n){e.next=5;break}return e.next=3,(0,c.default)({url:(0,o.generateOcsUrl)("apps/provisioning_api/api/v1/config/users/{appId}/{configKey}",{appId:"theming",configKey:"shortcuts_disabled"}),data:{configValue:"yes"},method:"POST"});case 3:e.next=7;break;case 5:return e.next=7,(0,c.default)({url:(0,o.generateOcsUrl)("apps/provisioning_api/api/v1/config/users/{appId}/{configKey}",{appId:"theming",configKey:"shortcuts_disabled"}),method:"DELETE"});case 7:case"end":return e.stop()}}),e)})))()},updateBodyAttributes:function(){var n=this.themes.filter((function(n){return!0===n.enabled})).map((function(n){return n.id})),e=this.fonts.filter((function(n){return!0===n.enabled})).map((function(n){return n.id}));this.themes.forEach((function(n){document.body.toggleAttribute("data-theme-".concat(n.id),n.enabled)})),this.fonts.forEach((function(n){document.body.toggleAttribute("data-theme-".concat(n.id),n.enabled)})),document.body.setAttribute("data-themes",[].concat(G(n),G(e)).join(","))},selectItem:function(n,e){return W(regeneratorRuntime.mark((function r(){return regeneratorRuntime.wrap((function(r){for(;;)switch(r.prev=r.next){case 0:if(r.prev=0,!n){r.next=6;break}return r.next=4,(0,c.default)({url:(0,o.generateOcsUrl)("apps/theming/api/v1/theme/{themeId}/enable",{themeId:e}),method:"PUT"});case 4:r.next=8;break;case 6:return r.next=8,(0,c.default)({url:(0,o.generateOcsUrl)("apps/theming/api/v1/theme/{themeId}",{themeId:e}),method:"DELETE"});case 8:r.next=14;break;case 10:r.prev=10,r.t0=r.catch(0),console.error(r.t0,r.t0.response),OC.Notification.showTemporary(t("theming",r.t0.response.data.ocs.meta.message+". Unable to apply the setting."));case 14:case"end":return r.stop()}}),r,null,[[0,10]])})))()}}},X=r(41936),nn={};nn.styleTagTransform=D(),nn.setAttributes=T(),nn.insert=S().bind(null,"head"),nn.domAPI=_(),nn.insertStyleElement=E(),y()(X.Z,nn),X.Z&&X.Z.locals&&X.Z.locals;var en=(0,R.Z)(Q,(function(){var n=this,e=n.$createElement,t=n._self._c||e;return t("section",[t("NcSettingsSection",{staticClass:"theming",attrs:{title:n.t("theming","Appearance and accessibility"),"limit-width":!1}},[t("p",{domProps:{innerHTML:n._s(n.description)}}),n._v(" "),t("p",{domProps:{innerHTML:n._s(n.descriptionDetail)}}),n._v(" "),t("div",{staticClass:"theming__preview-list"},n._l(n.themes,(function(e){return t("ItemPreview",{key:e.id,attrs:{enforced:e.id===n.enforceTheme,selected:n.selectedTheme.id===e.id,theme:e,unique:1===n.themes.length,type:"theme"},on:{change:n.changeTheme}})})),1),n._v(" "),t("div",{staticClass:"theming__preview-list"},n._l(n.fonts,(function(e){return t("ItemPreview",{key:e.id,attrs:{selected:e.enabled,theme:e,unique:1===n.fonts.length,type:"font"},on:{change:n.changeFont}})})),1)]),n._v(" "),t("NcSettingsSection",{attrs:{title:n.t("theming","Keyboard shortcuts")}},[t("p",[n._v(n._s(n.t("theming","In some cases keyboard shortcuts can interfer with accessibility tools. In order to allow focusing on your tool correctly you can disable all keyboard shortcuts here. This will also disable all available shortcuts in apps.")))]),n._v(" "),t("NcCheckboxRadioSwitch",{staticClass:"theming__preview-toggle",attrs:{checked:n.shortcutsDisabled,name:"shortcuts_disabled",type:"switch"},on:{"update:checked":function(e){n.shortcutsDisabled=e},change:n.changeShortcutsDisabled}},[n._v("\n\t\t\t"+n._s(n.t("theming","Disable all keyboard shortcuts"))+"\n\t\t")])],1),n._v(" "),t("NcSettingsSection",{staticClass:"background",attrs:{title:n.t("theming","Background")}},[t("p",[n._v(n._s(n.t("theming","Set a custom background")))]),n._v(" "),t("BackgroundSettings",{staticClass:"background__grid",attrs:{background:n.background,"theming-default-background":n.themingDefaultBackground},on:{"update:background":n.updateBackground}})],1)],1)}),[],!1,null,"a788b9b8",null).exports;function tn(n,e){(null==e||e>n.length)&&(e=n.length);for(var t=0,r=new Array(e);t<e;t++)r[t]=n[t];return r}a.ZP.prototype.OC=OC,a.ZP.prototype.t=t;var rn=new(a.ZP.extend(en));rn.$mount("#theming"),rn.$on("update:background",(function(){var n;(n=document.head.querySelectorAll("link.theme"),function(n){if(Array.isArray(n))return tn(n)}(n)||function(n){if("undefined"!=typeof Symbol&&null!=n[Symbol.iterator]||null!=n["@@iterator"])return Array.from(n)}(n)||function(n,e){if(n){if("string"==typeof n)return tn(n,e);var t=Object.prototype.toString.call(n).slice(8,-1);return"Object"===t&&n.constructor&&(t=n.constructor.name),"Map"===t||"Set"===t?Array.from(n):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?tn(n,e):void 0}}(n)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()).forEach((function(n){var e=new URL(n.href);e.searchParams.set("v",Date.now());var t=n.cloneNode();t.href=e.toString(),t.onload=function(){return n.remove()},document.head.append(t)}))}))},41936:function(n,e,t){var r=t(87537),a=t.n(r),o=t(23645),i=t.n(o)()(a());i.push([n.id,".theming p[data-v-a788b9b8]{max-width:800px}.theming[data-v-a788b9b8] a{font-weight:bold}.theming[data-v-a788b9b8] a:hover,.theming[data-v-a788b9b8] a:focus{text-decoration:underline}.theming__preview-list[data-v-a788b9b8]{--gap: 30px;display:grid;margin-top:var(--gap);column-gap:var(--gap);row-gap:var(--gap);grid-template-columns:1fr 1fr}.background__grid[data-v-a788b9b8]{margin-top:30px}@media(max-width: 1440px){.theming__preview-list[data-v-a788b9b8]{display:flex;flex-direction:column}}","",{version:3,sources:["webpack://./apps/theming/src/UserThemes.vue"],names:[],mappings:"AA+RC,4BACC,eAAA,CAID,4BACC,gBAAA,CAEA,oEAEC,yBAAA,CAIF,wCACC,WAAA,CAEA,YAAA,CACA,qBAAA,CACA,qBAAA,CACA,kBAAA,CACA,6BAAA,CAKD,mCACC,eAAA,CAIF,0BACC,wCACC,YAAA,CACA,qBAAA,CAAA",sourcesContent:["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.theming {\n\t// Limit width of settings sections for readability\n\tp {\n\t\tmax-width: 800px;\n\t}\n\n\t// Proper highlight for links and focus feedback\n\t&::v-deep a {\n\t\tfont-weight: bold;\n\n\t\t&:hover,\n\t\t&:focus {\n\t\t\ttext-decoration: underline;\n\t\t}\n\t}\n\n\t&__preview-list {\n\t\t--gap: 30px;\n\n\t\tdisplay: grid;\n\t\tmargin-top: var(--gap);\n\t\tcolumn-gap: var(--gap);\n\t\trow-gap: var(--gap);\n\t\tgrid-template-columns: 1fr 1fr;\n\t}\n}\n\n.background {\n\t&__grid {\n\t\tmargin-top: 30px;\n\t}\n}\n\n@media (max-width: 1440px) {\n\t.theming__preview-list {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t}\n}\n"],sourceRoot:""}]),e.Z=i},79993:function(n,e,t){var r=t(87537),a=t.n(r),o=t(23645),i=t.n(o)()(a());i.push([n.id,'.background-selector[data-v-48e565ba]{display:flex;flex-wrap:wrap;justify-content:center}.background-selector .background[data-v-48e565ba]{width:176px;height:96px;margin:8px;background-size:cover;background-position:center center;text-align:center;border-radius:var(--border-radius-large);border:2px solid var(--color-main-background);overflow:hidden}.background-selector .background.current[data-v-48e565ba]{background-image:var(--color-background-dark)}.background-selector .background.filepicker[data-v-48e565ba],.background-selector .background.default[data-v-48e565ba],.background-selector .background.color[data-v-48e565ba]{border-color:var(--color-border)}.background-selector .background.color[data-v-48e565ba]{background-color:var(--color-main-background-not-plain, var(--color-primary));color:var(--color-primary-text)}.background-selector .background.active[data-v-48e565ba],.background-selector .background[data-v-48e565ba]:hover,.background-selector .background[data-v-48e565ba]:focus{border:2px solid var(--color-primary)}.background-selector .background.active[data-v-48e565ba]:not(.icon-loading):after{background-image:var(--icon-checkmark-white);background-repeat:no-repeat;background-position:center;background-size:44px;content:"";display:block;height:100%}',"",{version:3,sources:["webpack://./apps/theming/src/components/BackgroundSettings.vue"],names:[],mappings:"AAoJA,sCACC,YAAA,CACA,cAAA,CACA,sBAAA,CAEA,kDACC,WAAA,CACA,WAAA,CACA,UAAA,CACA,qBAAA,CACA,iCAAA,CACA,iBAAA,CACA,wCAAA,CACA,6CAAA,CACA,eAAA,CAEA,0DACC,6CAAA,CAGD,+KACC,gCAAA,CAGD,wDACC,6EAAA,CACA,+BAAA,CAGD,yKAGC,qCAAA,CAGD,kFACC,4CAAA,CACA,2BAAA,CACA,0BAAA,CACA,oBAAA,CACA,UAAA,CACA,aAAA,CACA,WAAA",sourcesContent:["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.background-selector {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tjustify-content: center;\n\n\t.background {\n\t\twidth: 176px;\n\t\theight: 96px;\n\t\tmargin: 8px;\n\t\tbackground-size: cover;\n\t\tbackground-position: center center;\n\t\ttext-align: center;\n\t\tborder-radius: var(--border-radius-large);\n\t\tborder: 2px solid var(--color-main-background);\n\t\toverflow: hidden;\n\n\t\t&.current {\n\t\t\tbackground-image: var(--color-background-dark);\n\t\t}\n\n\t\t&.filepicker, &.default, &.color {\n\t\t\tborder-color: var(--color-border);\n\t\t}\n\n\t\t&.color {\n\t\t\tbackground-color: var(--color-main-background-not-plain, var(--color-primary));\n\t\t\tcolor: var(--color-primary-text);\n\t\t}\n\n\t\t&.active,\n\t\t&:hover,\n\t\t&:focus {\n\t\t\tborder: 2px solid var(--color-primary);\n\t\t}\n\n\t\t&.active:not(.icon-loading):after {\n\t\t\tbackground-image: var(--icon-checkmark-white);\n\t\t\tbackground-repeat: no-repeat;\n\t\t\tbackground-position: center;\n\t\t\tbackground-size: 44px;\n\t\t\tcontent: '';\n\t\t\tdisplay: block;\n\t\t\theight: 100%;\n\t\t}\n\t}\n}\n"],sourceRoot:""}]),e.Z=i},83005:function(n,e,t){var r=t(87537),a=t.n(r),o=t(23645),i=t.n(o)()(a());i.push([n.id,".theming__preview[data-v-37ca8ab2]{--ratio: 16;position:relative;display:flex;justify-content:flex-start;max-width:800px}.theming__preview[data-v-37ca8ab2],.theming__preview *[data-v-37ca8ab2]{user-select:none}.theming__preview-image[data-v-37ca8ab2]{flex-basis:calc(16px*var(--ratio));flex-shrink:0;height:calc(10px*var(--ratio));margin-right:var(--gap);cursor:pointer;border-radius:var(--border-radius);background-repeat:no-repeat;background-position:top left;background-size:cover}.theming__preview-description[data-v-37ca8ab2]{display:flex;flex-direction:column}.theming__preview-description label[data-v-37ca8ab2]{padding:12px 0}.theming__preview--default[data-v-37ca8ab2]{grid-column:span 2}.theming__preview-warning[data-v-37ca8ab2]{color:var(--color-warning)}@media(max-width: 682.6666666667px){.theming__preview[data-v-37ca8ab2]{flex-direction:column}.theming__preview-image[data-v-37ca8ab2]{margin:0}}","",{version:3,sources:["webpack://./apps/theming/src/components/ItemPreview.vue"],names:[],mappings:"AAiGA,mCAEC,WAAA,CAEA,iBAAA,CACA,YAAA,CACA,0BAAA,CACA,eAAA,CAEA,wEAEC,gBAAA,CAGD,yCACC,kCAAA,CACA,aAAA,CACA,8BAAA,CACA,uBAAA,CACA,cAAA,CACA,kCAAA,CACA,2BAAA,CACA,4BAAA,CACA,qBAAA,CAGD,+CACC,YAAA,CACA,qBAAA,CAEA,qDACC,cAAA,CAIF,4CACC,kBAAA,CAGD,2CACC,0BAAA,CAIF,oCACC,mCACC,qBAAA,CAEA,yCACC,QAAA,CAAA",sourcesContent:["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.theming__preview {\n\t// We make previews on 16/10 screens\n\t--ratio: 16;\n\n\tposition: relative;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\tmax-width: 800px;\n\n\t&,\n\t* {\n\t\tuser-select: none;\n\t}\n\n\t&-image {\n\t\tflex-basis: calc(16px * var(--ratio));\n\t\tflex-shrink: 0;\n\t\theight: calc(10px * var(--ratio));\n\t\tmargin-right: var(--gap);\n\t\tcursor: pointer;\n\t\tborder-radius: var(--border-radius);\n\t\tbackground-repeat: no-repeat;\n\t\tbackground-position: top left;\n\t\tbackground-size: cover;\n\t}\n\n\t&-description {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\n\t\tlabel {\n\t\t\tpadding: 12px 0;\n\t\t}\n\t}\n\n\t&--default {\n\t\tgrid-column: span 2;\n\t}\n\n\t&-warning {\n\t\tcolor: var(--color-warning);\n\t}\n}\n\n@media (max-width: (1024px / 1.5)) {\n\t.theming__preview {\n\t\tflex-direction: column;\n\n\t\t&-image {\n\t\t\tmargin: 0;\n\t\t}\n\t}\n}\n\n"],sourceRoot:""}]),e.Z=i}},r={};function a(n){var t=r[n];if(void 0!==t)return t.exports;var o=r[n]={id:n,loaded:!1,exports:{}};return e[n].call(o.exports,o,o.exports,a),o.loaded=!0,o.exports}a.m=e,a.amdD=function(){throw new Error("define cannot be used indirect")},a.amdO={},n=[],a.O=function(e,t,r,o){if(!t){var i=1/0;for(d=0;d<n.length;d++){t=n[d][0],r=n[d][1],o=n[d][2];for(var c=!0,s=0;s<t.length;s++)(!1&o||i>=o)&&Object.keys(a.O).every((function(n){return a.O[n](t[s])}))?t.splice(s--,1):(c=!1,o<i&&(i=o));if(c){n.splice(d--,1);var u=r();void 0!==u&&(e=u)}}return e}o=o||0;for(var d=n.length;d>0&&n[d-1][2]>o;d--)n[d]=n[d-1];n[d]=[t,r,o]},a.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return a.d(e,{a:e}),e},a.d=function(n,e){for(var t in e)a.o(e,t)&&!a.o(n,t)&&Object.defineProperty(n,t,{enumerable:!0,get:e[t]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(n){if("object"==typeof window)return window}}(),a.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},a.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},a.nmd=function(n){return n.paths=[],n.children||(n.children=[]),n},a.j=6755,function(){a.b=document.baseURI||self.location.href;var n={6755:0};a.O.j=function(e){return 0===n[e]};var e=function(e,t){var r,o,i=t[0],c=t[1],s=t[2],u=0;if(i.some((function(e){return 0!==n[e]}))){for(r in c)a.o(c,r)&&(a.m[r]=c[r]);if(s)var d=s(a)}for(e&&e(t);u<i.length;u++)o=i[u],a.o(n,o)&&n[o]&&n[o][0](),n[o]=0;return a.O(d)},t=self.webpackChunknextcloud=self.webpackChunknextcloud||[];t.forEach(e.bind(null,0)),t.push=e.bind(null,t.push.bind(t))}(),a.nc=void 0;var o=a.O(void 0,[7874],(function(){return a(58078)}));o=a.O(o)}();
+//# sourceMappingURL=theming-theming-settings.js.map?v=478aa74ec2979a9203af \ No newline at end of file
diff --git a/dist/theming-theming-settings.js.map b/dist/theming-theming-settings.js.map
index 5b32270cc3d..7a624787221 100644
--- a/dist/theming-theming-settings.js.map
+++ b/dist/theming-theming-settings.js.map
@@ -1 +1 @@
-{"version":3,"file":"theming-theming-settings.js?v=7c6c2a5e9a4ab6b66a54","mappings":"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","sources":["webpack:///nextcloud/webpack/runtime/chunk loaded","webpack:///nextcloud/apps/theming/src/helpers/prefixWithBaseUrl.js","webpack:///nextcloud/apps/theming/src/helpers/getBackgroundUrl.js","webpack:///nextcloud/apps/theming/src/components/BackgroundSettings.vue","webpack:///nextcloud/apps/theming/src/components/BackgroundSettings.vue?vue&type=script&lang=js&","webpack://nextcloud/./apps/theming/src/components/BackgroundSettings.vue?8c38","webpack://nextcloud/./apps/theming/src/components/BackgroundSettings.vue?65db","webpack:///nextcloud/apps/theming/src/components/BackgroundSettings.vue?vue&type=template&id=5ccad868&scoped=true&","webpack:///nextcloud/apps/theming/src/components/ItemPreview.vue?vue&type=script&lang=js&","webpack:///nextcloud/apps/theming/src/components/ItemPreview.vue","webpack://nextcloud/./apps/theming/src/components/ItemPreview.vue?f1c6","webpack://nextcloud/./apps/theming/src/components/ItemPreview.vue?8797","webpack:///nextcloud/apps/theming/src/components/ItemPreview.vue?vue&type=template&id=37ca8ab2&scoped=true&","webpack:///nextcloud/apps/theming/src/UserThemes.vue","webpack:///nextcloud/apps/theming/src/UserThemes.vue?vue&type=script&lang=js&","webpack://nextcloud/./apps/theming/src/UserThemes.vue?52b2","webpack://nextcloud/./apps/theming/src/UserThemes.vue?7eb2","webpack:///nextcloud/apps/theming/src/UserThemes.vue?vue&type=template&id=a788b9b8&scoped=true&","webpack:///nextcloud/apps/theming/src/settings.js","webpack:///nextcloud/apps/theming/src/UserThemes.vue?vue&type=style&index=0&id=a788b9b8&lang=scss&scoped=true&","webpack:///nextcloud/apps/theming/src/components/BackgroundSettings.vue?vue&type=style&index=0&id=5ccad868&scoped=true&lang=scss&","webpack:///nextcloud/apps/theming/src/components/ItemPreview.vue?vue&type=style&index=0&id=37ca8ab2&lang=scss&scoped=true&","webpack:///nextcloud/webpack/bootstrap","webpack:///nextcloud/webpack/runtime/amd define","webpack:///nextcloud/webpack/runtime/amd options","webpack:///nextcloud/webpack/runtime/compat get default export","webpack:///nextcloud/webpack/runtime/define property getters","webpack:///nextcloud/webpack/runtime/global","webpack:///nextcloud/webpack/runtime/hasOwnProperty shorthand","webpack:///nextcloud/webpack/runtime/make namespace object","webpack:///nextcloud/webpack/runtime/node module decorator","webpack:///nextcloud/webpack/runtime/runtimeId","webpack:///nextcloud/webpack/runtime/jsonp chunk loading","webpack:///nextcloud/webpack/runtime/nonce","webpack:///nextcloud/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = function(result, chunkIds, fn, priority) {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","/**\n * @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>\n *\n * @author Julius Härtl <jus@bitgrid.net>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { generateFilePath } from '@nextcloud/router'\n\nexport const prefixWithBaseUrl = (url) => generateFilePath('theming', '', 'img/background/') + url\n","/**\n * @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>\n *\n * @author Avior <florian.bouillon@delta-wings.net>\n * @author Julien Veyssier <eneiluj@posteo.net>\n * @author Julius Härtl <jus@bitgrid.net>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { generateUrl } from '@nextcloud/router'\nimport { prefixWithBaseUrl } from './prefixWithBaseUrl.js'\n\nexport const getBackgroundUrl = (background, time = 0, themingDefaultBackground = '') => {\n\tconst enabledThemes = window.OCA?.Theming?.enabledThemes || []\n\tconst isDarkTheme = (enabledThemes.length === 0 || enabledThemes[0] === 'default')\n\t\t? window.matchMedia('(prefers-color-scheme: dark)').matches\n\t\t: enabledThemes.join('').indexOf('dark') !== -1\n\n\tif (background === 'default') {\n\t\tif (themingDefaultBackground && themingDefaultBackground !== 'backgroundColor') {\n\t\t\treturn generateUrl('/apps/theming/image/background') + '?v=' + window.OCA.Theming.cacheBuster\n\t\t}\n\n\t\tif (isDarkTheme) {\n\t\t\treturn prefixWithBaseUrl('eduardo-neves-pedra-azul.jpg')\n\t\t}\n\n\t\treturn prefixWithBaseUrl('kamil-porembinski-clouds.jpg')\n\t} else if (background === 'custom') {\n\t\treturn generateUrl('/apps/theming/background') + '?v=' + time\n\t}\n\n\treturn prefixWithBaseUrl(background)\n}\n","<!--\n - @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>\n - @copyright Copyright (c) 2022 Greta Doci <gretadoci@gmail.com>\n -\n - @author Julius Härtl <jus@bitgrid.net>\n - @author Greta Doci <gretadoci@gmail.com>\n - @author Christopher Ng <chrng8@gmail.com>\n -\n - @license GNU AGPL version 3 or any later version\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<template>\n\t<div class=\"background-selector\">\n\t\t<button class=\"background filepicker\"\n\t\t\t:class=\"{ active: background === 'custom' }\"\n\t\t\ttabindex=\"0\"\n\t\t\t@click=\"pickFile\">\n\t\t\t{{ t('theming', 'Pick from Files') }}\n\t\t</button>\n\t\t<button class=\"background default\"\n\t\t\ttabindex=\"0\"\n\t\t\t:class=\"{ 'icon-loading': loading === 'default', active: background === 'default' }\"\n\t\t\t@click=\"setDefault\">\n\t\t\t{{ t('theming', 'Default image') }}\n\t\t</button>\n\t\t<button class=\"background color\"\n\t\t\t:class=\"{ active: background.startsWith('#') }\"\n\t\t\ttabindex=\"0\"\n\t\t\t@click=\"pickColor\">\n\t\t\t{{ t('theming', 'Plain background') }}\n\t\t</button>\n\t\t<button v-for=\"shippedBackground in shippedBackgrounds\"\n\t\t\t:key=\"shippedBackground.name\"\n\t\t\tv-tooltip=\"shippedBackground.details.attribution\"\n\t\t\t:class=\"{ 'icon-loading': loading === shippedBackground.name, active: background === shippedBackground.name }\"\n\t\t\ttabindex=\"0\"\n\t\t\tclass=\"background\"\n\t\t\t:style=\"{ 'background-image': 'url(' + shippedBackground.preview + ')' }\"\n\t\t\t@click=\"setShipped(shippedBackground.name)\" />\n\t</div>\n</template>\n\n<script>\nimport axios from '@nextcloud/axios'\nimport Tooltip from '@nextcloud/vue/dist/Directives/Tooltip'\nimport { generateUrl } from '@nextcloud/router'\nimport { loadState } from '@nextcloud/initial-state'\nimport { getBackgroundUrl } from '../helpers/getBackgroundUrl.js'\nimport { prefixWithBaseUrl } from '../helpers/prefixWithBaseUrl.js'\n\nconst shippedBackgroundList = loadState('theming', 'shippedBackgrounds')\n\nexport default {\n\tname: 'BackgroundSettings',\n\tdirectives: {\n\t\tTooltip,\n\t},\n\tprops: {\n\t\tbackground: {\n\t\t\ttype: String,\n\t\t\tdefault: 'default',\n\t\t},\n\t\tthemingDefaultBackground: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t},\n\tdata() {\n\t\treturn {\n\t\t\tbackgroundImage: generateUrl('/apps/theming/background') + '?v=' + Date.now(),\n\t\t\tloading: false,\n\t\t}\n\t},\n\tcomputed: {\n\t\tshippedBackgrounds() {\n\t\t\treturn Object.keys(shippedBackgroundList).map(fileName => {\n\t\t\t\treturn {\n\t\t\t\t\tname: fileName,\n\t\t\t\t\turl: prefixWithBaseUrl(fileName),\n\t\t\t\t\tpreview: prefixWithBaseUrl('preview/' + fileName),\n\t\t\t\t\tdetails: shippedBackgroundList[fileName],\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\t},\n\tmethods: {\n\t\tasync update(data) {\n\t\t\tconst background = data.type === 'custom' || data.type === 'default' ? data.type : data.value\n\t\t\tthis.backgroundImage = getBackgroundUrl(background, data.version, this.themingDefaultBackground)\n\t\t\tif (data.type === 'color' || (data.type === 'default' && this.themingDefaultBackground === 'backgroundColor')) {\n\t\t\t\tthis.$emit('update:background', data)\n\t\t\t\tthis.loading = false\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst image = new Image()\n\t\t\timage.onload = () => {\n\t\t\t\tthis.$emit('update:background', data)\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t\timage.src = this.backgroundImage\n\t\t},\n\t\tasync setDefault() {\n\t\t\tthis.loading = 'default'\n\t\t\tconst result = await axios.post(generateUrl('/apps/theming/background/default'))\n\t\t\tthis.update(result.data)\n\t\t},\n\t\tasync setShipped(shipped) {\n\t\t\tthis.loading = shipped\n\t\t\tconst result = await axios.post(generateUrl('/apps/theming/background/shipped'), { value: shipped })\n\t\t\tthis.update(result.data)\n\t\t},\n\t\tasync setFile(path) {\n\t\t\tthis.loading = 'custom'\n\t\t\tconst result = await axios.post(generateUrl('/apps/theming/background/custom'), { value: path })\n\t\t\tthis.update(result.data)\n\t\t},\n\t\tasync pickColor() {\n\t\t\tthis.loading = 'color'\n\t\t\tconst color = OCA && OCA.Theming ? OCA.Theming.color : '#0082c9'\n\t\t\tconst result = await axios.post(generateUrl('/apps/theming/background/color'), { value: color })\n\t\t\tthis.update(result.data)\n\t\t},\n\t\tpickFile() {\n\t\t\twindow.OC.dialogs.filepicker(t('theming', 'Insert from {productName}', { productName: OC.theme.name }), (path, type) => {\n\t\t\t\tif (type === OC.dialogs.FILEPICKER_TYPE_CHOOSE) {\n\t\t\t\t\tthis.setFile(path)\n\t\t\t\t}\n\t\t\t}, false, ['image/png', 'image/gif', 'image/jpeg', 'image/svg'], true, OC.dialogs.FILEPICKER_TYPE_CHOOSE)\n\t\t},\n\t},\n}\n</script>\n\n<style scoped lang=\"scss\">\n.background-selector {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tjustify-content: center;\n\n\t.background {\n\t\twidth: 176px;\n\t\theight: 96px;\n\t\tmargin: 8px;\n\t\tbackground-size: cover;\n\t\tbackground-position: center center;\n\t\ttext-align: center;\n\t\tborder-radius: var(--border-radius-large);\n\t\tborder: 2px solid var(--color-main-background);\n\t\toverflow: hidden;\n\n\t\t&.current {\n\t\t\tbackground-image: var(--color-background-dark);\n\t\t}\n\n\t\t&.filepicker, &.default, &.color {\n\t\t\tborder-color: var(--color-border);\n\t\t}\n\n\t\t&.color {\n\t\t\tbackground-color: var(--color-primary);\n\t\t\tcolor: var(--color-primary-text);\n\t\t}\n\n\t\t&.active,\n\t\t&:hover,\n\t\t&:focus {\n\t\t\tborder: 2px solid var(--color-primary);\n\t\t}\n\n\t\t&.active:not(.icon-loading):after {\n\t\t\tbackground-image: var(--icon-checkmark-white);\n\t\t\tbackground-repeat: no-repeat;\n\t\t\tbackground-position: center;\n\t\t\tbackground-size: 44px;\n\t\t\tcontent: '';\n\t\t\tdisplay: block;\n\t\t\theight: 100%;\n\t\t}\n\t}\n}\n</style>\n","import mod from \"-!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./BackgroundSettings.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./BackgroundSettings.vue?vue&type=script&lang=js&\"","\n import API from \"!../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/sass-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./BackgroundSettings.vue?vue&type=style&index=0&id=5ccad868&scoped=true&lang=scss&\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/sass-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./BackgroundSettings.vue?vue&type=style&index=0&id=5ccad868&scoped=true&lang=scss&\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./BackgroundSettings.vue?vue&type=template&id=5ccad868&scoped=true&\"\nimport script from \"./BackgroundSettings.vue?vue&type=script&lang=js&\"\nexport * from \"./BackgroundSettings.vue?vue&type=script&lang=js&\"\nimport style0 from \"./BackgroundSettings.vue?vue&type=style&index=0&id=5ccad868&scoped=true&lang=scss&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"5ccad868\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"background-selector\"},[_c('button',{staticClass:\"background filepicker\",class:{ active: _vm.background === 'custom' },attrs:{\"tabindex\":\"0\"},on:{\"click\":_vm.pickFile}},[_vm._v(\"\\n\\t\\t\"+_vm._s(_vm.t('theming', 'Pick from Files'))+\"\\n\\t\")]),_vm._v(\" \"),_c('button',{staticClass:\"background default\",class:{ 'icon-loading': _vm.loading === 'default', active: _vm.background === 'default' },attrs:{\"tabindex\":\"0\"},on:{\"click\":_vm.setDefault}},[_vm._v(\"\\n\\t\\t\"+_vm._s(_vm.t('theming', 'Default image'))+\"\\n\\t\")]),_vm._v(\" \"),_c('button',{staticClass:\"background color\",class:{ active: _vm.background.startsWith('#') },attrs:{\"tabindex\":\"0\"},on:{\"click\":_vm.pickColor}},[_vm._v(\"\\n\\t\\t\"+_vm._s(_vm.t('theming', 'Plain background'))+\"\\n\\t\")]),_vm._v(\" \"),_vm._l((_vm.shippedBackgrounds),function(shippedBackground){return _c('button',{directives:[{name:\"tooltip\",rawName:\"v-tooltip\",value:(shippedBackground.details.attribution),expression:\"shippedBackground.details.attribution\"}],key:shippedBackground.name,staticClass:\"background\",class:{ 'icon-loading': _vm.loading === shippedBackground.name, active: _vm.background === shippedBackground.name },style:({ 'background-image': 'url(' + shippedBackground.preview + ')' }),attrs:{\"tabindex\":\"0\"},on:{\"click\":function($event){return _vm.setShipped(shippedBackground.name)}}})})],2)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./ItemPreview.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./ItemPreview.vue?vue&type=script&lang=js&\"","<template>\n\t<div :class=\"'theming__preview--' + theme.id\" class=\"theming__preview\">\n\t\t<div class=\"theming__preview-image\" :style=\"{ backgroundImage: 'url(' + img + ')' }\" @click=\"onToggle\" />\n\t\t<div class=\"theming__preview-description\">\n\t\t\t<h3>{{ theme.title }}</h3>\n\t\t\t<p>{{ theme.description }}</p>\n\t\t\t<span v-if=\"enforced\" class=\"theming__preview-warning\" role=\"note\">\n\t\t\t\t{{ t('theming', 'Theme selection is enforced') }}\n\t\t\t</span>\n\t\t\t<NcCheckboxRadioSwitch class=\"theming__preview-toggle\"\n\t\t\t\t:checked.sync=\"checked\"\n\t\t\t\t:disabled=\"enforced\"\n\t\t\t\t:name=\"name\"\n\t\t\t\t:type=\"switchType\">\n\t\t\t\t{{ theme.enableLabel }}\n\t\t\t</NcCheckboxRadioSwitch>\n\t\t</div>\n\t</div>\n</template>\n\n<script>\nimport { generateFilePath } from '@nextcloud/router'\nimport NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch'\n\nexport default {\n\tname: 'ItemPreview',\n\tcomponents: {\n\t\tNcCheckboxRadioSwitch,\n\t},\n\tprops: {\n\t\tenforced: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\tselected: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\ttheme: {\n\t\t\ttype: Object,\n\t\t\trequired: true,\n\t\t},\n\t\ttype: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t\tunique: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\tcomputed: {\n\t\tswitchType() {\n\t\t\treturn this.unique ? 'switch' : 'radio'\n\t\t},\n\n\t\tname() {\n\t\t\treturn !this.unique ? this.type : null\n\t\t},\n\n\t\timg() {\n\t\t\treturn generateFilePath('theming', 'img', this.theme.id + '.jpg')\n\t\t},\n\n\t\tchecked: {\n\t\t\tget() {\n\t\t\t\treturn this.selected\n\t\t\t},\n\t\t\tset(checked) {\n\t\t\t\tconsole.debug('Changed theme', this.theme.id, checked)\n\n\t\t\t\t// If this is a radio, we can only enable\n\t\t\t\tif (!this.unique) {\n\t\t\t\t\tthis.$emit('change', { enabled: true, id: this.theme.id })\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// If this is a switch, we can disable the theme\n\t\t\t\tthis.$emit('change', { enabled: checked === true, id: this.theme.id })\n\t\t\t},\n\t\t},\n\t},\n\n\tmethods: {\n\t\tonToggle() {\n\t\t\tif (this.switchType === 'radio') {\n\t\t\t\tthis.checked = true\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Invert state\n\t\t\tthis.checked = !this.checked\n\t\t},\n\t},\n}\n</script>\n<style lang=\"scss\" scoped>\n.theming__preview {\n\t// We make previews on 16/10 screens\n\t--ratio: 16;\n\n\tposition: relative;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\tmax-width: 800px;\n\n\t&,\n\t* {\n\t\tuser-select: none;\n\t}\n\n\t&-image {\n\t\tflex-basis: calc(16px * var(--ratio));\n\t\tflex-shrink: 0;\n\t\theight: calc(10px * var(--ratio));\n\t\tmargin-right: var(--gap);\n\t\tcursor: pointer;\n\t\tborder-radius: var(--border-radius);\n\t\tbackground-repeat: no-repeat;\n\t\tbackground-position: top left;\n\t\tbackground-size: cover;\n\t}\n\n\t&-description {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\n\t\tlabel {\n\t\t\tpadding: 12px 0;\n\t\t}\n\t}\n\n\t&--default {\n\t\tgrid-column: span 2;\n\t}\n\n\t&-warning {\n\t\tcolor: var(--color-warning);\n\t}\n}\n\n@media (max-width: (1024px / 1.5)) {\n\t.theming__preview {\n\t\tflex-direction: column;\n\n\t\t&-image {\n\t\t\tmargin: 0;\n\t\t}\n\t}\n}\n\n</style>\n","\n import API from \"!../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/sass-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./ItemPreview.vue?vue&type=style&index=0&id=37ca8ab2&lang=scss&scoped=true&\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/sass-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./ItemPreview.vue?vue&type=style&index=0&id=37ca8ab2&lang=scss&scoped=true&\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./ItemPreview.vue?vue&type=template&id=37ca8ab2&scoped=true&\"\nimport script from \"./ItemPreview.vue?vue&type=script&lang=js&\"\nexport * from \"./ItemPreview.vue?vue&type=script&lang=js&\"\nimport style0 from \"./ItemPreview.vue?vue&type=style&index=0&id=37ca8ab2&lang=scss&scoped=true&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"37ca8ab2\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"theming__preview\",class:'theming__preview--' + _vm.theme.id},[_c('div',{staticClass:\"theming__preview-image\",style:({ backgroundImage: 'url(' + _vm.img + ')' }),on:{\"click\":_vm.onToggle}}),_vm._v(\" \"),_c('div',{staticClass:\"theming__preview-description\"},[_c('h3',[_vm._v(_vm._s(_vm.theme.title))]),_vm._v(\" \"),_c('p',[_vm._v(_vm._s(_vm.theme.description))]),_vm._v(\" \"),(_vm.enforced)?_c('span',{staticClass:\"theming__preview-warning\",attrs:{\"role\":\"note\"}},[_vm._v(\"\\n\\t\\t\\t\"+_vm._s(_vm.t('theming', 'Theme selection is enforced'))+\"\\n\\t\\t\")]):_vm._e(),_vm._v(\" \"),_c('NcCheckboxRadioSwitch',{staticClass:\"theming__preview-toggle\",attrs:{\"checked\":_vm.checked,\"disabled\":_vm.enforced,\"name\":_vm.name,\"type\":_vm.switchType},on:{\"update:checked\":function($event){_vm.checked=$event}}},[_vm._v(\"\\n\\t\\t\\t\"+_vm._s(_vm.theme.enableLabel)+\"\\n\\t\\t\")])],1)])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","<!--\n - @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>\n - @copyright Copyright (c) 2022 Greta Doci <gretadoci@gmail.com>\n -\n - @author Christopher Ng <chrng8@gmail.com>\n -\n - @license AGPL-3.0-or-later\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n-->\n\n<template>\n\t<section>\n\t\t<NcSettingsSection :title=\"t('theming', 'Appearance and accessibility')\"\n\t\t\t:limit-width=\"false\"\n\t\t\tclass=\"theming\">\n\t\t\t<p v-html=\"description\" />\n\t\t\t<p v-html=\"descriptionDetail\" />\n\n\t\t\t<div class=\"theming__preview-list\">\n\t\t\t\t<ItemPreview v-for=\"theme in themes\"\n\t\t\t\t\t:key=\"theme.id\"\n\t\t\t\t\t:enforced=\"theme.id === enforceTheme\"\n\t\t\t\t\t:selected=\"selectedTheme.id === theme.id\"\n\t\t\t\t\t:theme=\"theme\"\n\t\t\t\t\t:unique=\"themes.length === 1\"\n\t\t\t\t\ttype=\"theme\"\n\t\t\t\t\t@change=\"changeTheme\" />\n\t\t\t</div>\n\n\t\t\t<div class=\"theming__preview-list\">\n\t\t\t\t<ItemPreview v-for=\"theme in fonts\"\n\t\t\t\t\t:key=\"theme.id\"\n\t\t\t\t\t:selected=\"theme.enabled\"\n\t\t\t\t\t:theme=\"theme\"\n\t\t\t\t\t:unique=\"fonts.length === 1\"\n\t\t\t\t\ttype=\"font\"\n\t\t\t\t\t@change=\"changeFont\" />\n\t\t\t</div>\n\t\t</NcSettingsSection>\n\n\t\t<NcSettingsSection :title=\"t('theming', 'Keyboard shortcuts')\">\n\t\t\t<p>{{ t('theming', 'In some cases keyboard shortcuts can interfer with accessibility tools. In order to allow focusing on your tool correctly you can disable all keyboard shortcuts here. This will also disable all available shortcuts in apps.') }}</p>\n\t\t\t<NcCheckboxRadioSwitch class=\"theming__preview-toggle\"\n\t\t\t\t:checked.sync=\"shortcutsDisabled\"\n\t\t\t\tname=\"shortcuts_disabled\"\n\t\t\t\ttype=\"switch\"\n\t\t\t\t@change=\"changeShortcutsDisabled\">\n\t\t\t\t{{ t('theming', 'Disable all keyboard shortcuts') }}\n\t\t\t</NcCheckboxRadioSwitch>\n\t\t</NcSettingsSection>\n\n\t\t<NcSettingsSection :title=\"t('theming', 'Background')\"\n\t\t\tclass=\"background\">\n\t\t\t<p>{{ t('theming', 'Set a custom background') }}</p>\n\t\t\t<BackgroundSettings class=\"background__grid\"\n\t\t\t\t:background=\"background\"\n\t\t\t\t:theming-default-background=\"themingDefaultBackground\"\n\t\t\t\t@update:background=\"updateBackground\" />\n\t\t</NcSettingsSection>\n\t</section>\n</template>\n\n<script>\nimport { generateOcsUrl } from '@nextcloud/router'\nimport { loadState } from '@nextcloud/initial-state'\nimport axios from '@nextcloud/axios'\nimport NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch'\nimport NcSettingsSection from '@nextcloud/vue/dist/Components/NcSettingsSection'\n\nimport BackgroundSettings from './components/BackgroundSettings.vue'\nimport ItemPreview from './components/ItemPreview.vue'\n\nconst availableThemes = loadState('theming', 'themes', [])\nconst enforceTheme = loadState('theming', 'enforceTheme', '')\nconst shortcutsDisabled = loadState('theming', 'shortcutsDisabled', false)\n\nconst background = loadState('theming', 'background')\nconst backgroundVersion = loadState('theming', 'backgroundVersion')\nconst themingDefaultBackground = loadState('theming', 'themingDefaultBackground')\nconst shippedBackgroundList = loadState('theming', 'shippedBackgrounds')\n\nconsole.debug('Available themes', availableThemes)\n\nexport default {\n\tname: 'UserThemes',\n\tcomponents: {\n\t\tItemPreview,\n\t\tNcCheckboxRadioSwitch,\n\t\tNcSettingsSection,\n\t\tBackgroundSettings,\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tavailableThemes,\n\t\t\tenforceTheme,\n\t\t\tshortcutsDisabled,\n\t\t\tbackground,\n\t\t\tbackgroundVersion,\n\t\t\tthemingDefaultBackground,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\tthemes() {\n\t\t\treturn this.availableThemes.filter(theme => theme.type === 1)\n\t\t},\n\t\tfonts() {\n\t\t\treturn this.availableThemes.filter(theme => theme.type === 2)\n\t\t},\n\n\t\t// Selected theme, fallback on first (default) if none\n\t\tselectedTheme() {\n\t\t\treturn this.themes.find(theme => theme.enabled === true) || this.themes[0]\n\t\t},\n\n\t\tdescription() {\n\t\t\t// using the `t` replace method escape html, we have to do it manually :/\n\t\t\treturn t(\n\t\t\t\t'theming',\n\t\t\t\t'Universal access is very important to us. We follow web standards and check to make everything usable also without mouse, and assistive software such as screenreaders. We aim to be compliant with the {guidelines}Web Content Accessibility Guidelines{linkend} 2.1 on AA level, with the high contrast theme even on AAA level.'\n\t\t\t)\n\t\t\t\t.replace('{guidelines}', this.guidelinesLink)\n\t\t\t\t.replace('{linkend}', '</a>')\n\t\t},\n\t\tguidelinesLink() {\n\t\t\treturn '<a target=\"_blank\" href=\"https://www.w3.org/WAI/standards-guidelines/wcag/\" rel=\"noreferrer nofollow\">'\n\t\t},\n\t\tdescriptionDetail() {\n\t\t\treturn t(\n\t\t\t\t'theming',\n\t\t\t\t'If you find any issues, do not hesitate to report them on {issuetracker}our issue tracker{linkend}. And if you want to get involved, come join {designteam}our design team{linkend}!'\n\t\t\t)\n\t\t\t\t.replace('{issuetracker}', this.issuetrackerLink)\n\t\t\t\t.replace('{designteam}', this.designteamLink)\n\t\t\t\t.replace(/\\{linkend\\}/g, '</a>')\n\t\t},\n\t\tissuetrackerLink() {\n\t\t\treturn '<a target=\"_blank\" href=\"https://github.com/nextcloud/server/issues/\" rel=\"noreferrer nofollow\">'\n\t\t},\n\t\tdesignteamLink() {\n\t\t\treturn '<a target=\"_blank\" href=\"https://nextcloud.com/design\" rel=\"noreferrer nofollow\">'\n\t\t},\n\t},\n\n\tmounted() {\n\t\tthis.updateGlobalStyles()\n\t},\n\n\twatch: {\n\t\tshortcutsDisabled(newState) {\n\t\t\tthis.changeShortcutsDisabled(newState)\n\t\t},\n\t},\n\n\tmethods: {\n\t\tupdateBackground(data) {\n\t\t\tthis.background = (data.type === 'custom' || data.type === 'default') ? data.type : data.value\n\t\t\tthis.backgroundVersion = data.version\n\t\t\tthis.updateGlobalStyles()\n\t\t\tthis.$emit('update:background')\n\t\t},\n\t\tupdateGlobalStyles() {\n\t\t\t// Override primary-invert-if-bright and color-primary-text if background is set\n\t\t\tconst isBackgroundBright = shippedBackgroundList[this.background]?.theming === 'dark'\n\t\t\tif (isBackgroundBright) {\n\t\t\t\tdocument.querySelector('#header').style.setProperty('--primary-invert-if-bright', 'invert(100%)')\n\t\t\t\tdocument.querySelector('#header').style.setProperty('--color-primary-text', '#000000')\n\t\t\t\t// document.body.removeAttribute('data-theme-dark')\n\t\t\t\t// document.body.setAttribute('data-theme-light', 'true')\n\t\t\t} else {\n\t\t\t\tdocument.querySelector('#header').style.setProperty('--primary-invert-if-bright', 'no')\n\t\t\t\tdocument.querySelector('#header').style.setProperty('--color-primary-text', '#ffffff')\n\t\t\t\t// document.body.removeAttribute('data-theme-light')\n\t\t\t\t// document.body.setAttribute('data-theme-dark', 'true')\n\t\t\t}\n\t\t},\n\t\tchangeTheme({ enabled, id }) {\n\t\t\t// Reset selected and select new one\n\t\t\tthis.themes.forEach(theme => {\n\t\t\t\tif (theme.id === id && enabled) {\n\t\t\t\t\ttheme.enabled = true\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\ttheme.enabled = false\n\t\t\t})\n\n\t\t\tthis.updateBodyAttributes()\n\t\t\tthis.selectItem(enabled, id)\n\t\t},\n\t\tchangeFont({ enabled, id }) {\n\t\t\t// Reset selected and select new one\n\t\t\tthis.fonts.forEach(font => {\n\t\t\t\tif (font.id === id && enabled) {\n\t\t\t\t\tfont.enabled = true\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tfont.enabled = false\n\t\t\t})\n\n\t\t\tthis.updateBodyAttributes()\n\t\t\tthis.selectItem(enabled, id)\n\t\t},\n\n\t\tasync changeShortcutsDisabled(newState) {\n\t\t\tif (newState) {\n\t\t\t\tawait axios({\n\t\t\t\t\turl: generateOcsUrl('apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', {\n\t\t\t\t\t\tappId: 'theming',\n\t\t\t\t\t\tconfigKey: 'shortcuts_disabled',\n\t\t\t\t\t}),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tconfigValue: 'yes',\n\t\t\t\t\t},\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tawait axios({\n\t\t\t\t\turl: generateOcsUrl('apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', {\n\t\t\t\t\t\tappId: 'theming',\n\t\t\t\t\t\tconfigKey: 'shortcuts_disabled',\n\t\t\t\t\t}),\n\t\t\t\t\tmethod: 'DELETE',\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\n\t\tupdateBodyAttributes() {\n\t\t\tconst enabledThemesIDs = this.themes.filter(theme => theme.enabled === true).map(theme => theme.id)\n\t\t\tconst enabledFontsIDs = this.fonts.filter(font => font.enabled === true).map(font => font.id)\n\n\t\t\tthis.themes.forEach(theme => {\n\t\t\t\tdocument.body.toggleAttribute(`data-theme-${theme.id}`, theme.enabled)\n\t\t\t})\n\t\t\tthis.fonts.forEach(font => {\n\t\t\t\tdocument.body.toggleAttribute(`data-theme-${font.id}`, font.enabled)\n\t\t\t})\n\n\t\t\tdocument.body.setAttribute('data-themes', [...enabledThemesIDs, ...enabledFontsIDs].join(','))\n\t\t},\n\n\t\t/**\n\t\t * Commit a change and force reload css\n\t\t * Fetching the file again will trigger the server update\n\t\t *\n\t\t * @param {boolean} enabled the theme state\n\t\t * @param {string} themeId the theme ID to change\n\t\t */\n\t\tasync selectItem(enabled, themeId) {\n\t\t\ttry {\n\t\t\t\tif (enabled) {\n\t\t\t\t\tawait axios({\n\t\t\t\t\t\turl: generateOcsUrl('apps/theming/api/v1/theme/{themeId}/enable', { themeId }),\n\t\t\t\t\t\tmethod: 'PUT',\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tawait axios({\n\t\t\t\t\t\turl: generateOcsUrl('apps/theming/api/v1/theme/{themeId}', { themeId }),\n\t\t\t\t\t\tmethod: 'DELETE',\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(err, err.response)\n\t\t\t\tOC.Notification.showTemporary(t('theming', err.response.data.ocs.meta.message + '. Unable to apply the setting.'))\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.theming {\n\t// Limit width of settings sections for readability\n\tp {\n\t\tmax-width: 800px;\n\t}\n\n\t// Proper highlight for links and focus feedback\n\t&::v-deep a {\n\t\tfont-weight: bold;\n\n\t\t&:hover,\n\t\t&:focus {\n\t\t\ttext-decoration: underline;\n\t\t}\n\t}\n\n\t&__preview-list {\n\t\t--gap: 30px;\n\n\t\tdisplay: grid;\n\t\tmargin-top: var(--gap);\n\t\tcolumn-gap: var(--gap);\n\t\trow-gap: var(--gap);\n\t\tgrid-template-columns: 1fr 1fr;\n\t}\n}\n\n.background {\n\t&__grid {\n\t\tmargin-top: 30px;\n\t}\n}\n\n@media (max-width: 1440px) {\n\t.theming__preview-list {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t}\n}\n</style>\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./UserThemes.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./UserThemes.vue?vue&type=script&lang=js&\"","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/sass-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./UserThemes.vue?vue&type=style&index=0&id=a788b9b8&lang=scss&scoped=true&\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/sass-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./UserThemes.vue?vue&type=style&index=0&id=a788b9b8&lang=scss&scoped=true&\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./UserThemes.vue?vue&type=template&id=a788b9b8&scoped=true&\"\nimport script from \"./UserThemes.vue?vue&type=script&lang=js&\"\nexport * from \"./UserThemes.vue?vue&type=script&lang=js&\"\nimport style0 from \"./UserThemes.vue?vue&type=style&index=0&id=a788b9b8&lang=scss&scoped=true&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"a788b9b8\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('section',[_c('NcSettingsSection',{staticClass:\"theming\",attrs:{\"title\":_vm.t('theming', 'Appearance and accessibility'),\"limit-width\":false}},[_c('p',{domProps:{\"innerHTML\":_vm._s(_vm.description)}}),_vm._v(\" \"),_c('p',{domProps:{\"innerHTML\":_vm._s(_vm.descriptionDetail)}}),_vm._v(\" \"),_c('div',{staticClass:\"theming__preview-list\"},_vm._l((_vm.themes),function(theme){return _c('ItemPreview',{key:theme.id,attrs:{\"enforced\":theme.id === _vm.enforceTheme,\"selected\":_vm.selectedTheme.id === theme.id,\"theme\":theme,\"unique\":_vm.themes.length === 1,\"type\":\"theme\"},on:{\"change\":_vm.changeTheme}})}),1),_vm._v(\" \"),_c('div',{staticClass:\"theming__preview-list\"},_vm._l((_vm.fonts),function(theme){return _c('ItemPreview',{key:theme.id,attrs:{\"selected\":theme.enabled,\"theme\":theme,\"unique\":_vm.fonts.length === 1,\"type\":\"font\"},on:{\"change\":_vm.changeFont}})}),1)]),_vm._v(\" \"),_c('NcSettingsSection',{attrs:{\"title\":_vm.t('theming', 'Keyboard shortcuts')}},[_c('p',[_vm._v(_vm._s(_vm.t('theming', 'In some cases keyboard shortcuts can interfer with accessibility tools. In order to allow focusing on your tool correctly you can disable all keyboard shortcuts here. This will also disable all available shortcuts in apps.')))]),_vm._v(\" \"),_c('NcCheckboxRadioSwitch',{staticClass:\"theming__preview-toggle\",attrs:{\"checked\":_vm.shortcutsDisabled,\"name\":\"shortcuts_disabled\",\"type\":\"switch\"},on:{\"update:checked\":function($event){_vm.shortcutsDisabled=$event},\"change\":_vm.changeShortcutsDisabled}},[_vm._v(\"\\n\\t\\t\\t\"+_vm._s(_vm.t('theming', 'Disable all keyboard shortcuts'))+\"\\n\\t\\t\")])],1),_vm._v(\" \"),_c('NcSettingsSection',{staticClass:\"background\",attrs:{\"title\":_vm.t('theming', 'Background')}},[_c('p',[_vm._v(_vm._s(_vm.t('theming', 'Set a custom background')))]),_vm._v(\" \"),_c('BackgroundSettings',{staticClass:\"background__grid\",attrs:{\"background\":_vm.background,\"theming-default-background\":_vm.themingDefaultBackground},on:{\"update:background\":_vm.updateBackground}})],1)],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","/**\n * @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @author John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport Vue from 'vue'\nimport App from './UserThemes.vue'\n\n// bind to window\nVue.prototype.OC = OC\nVue.prototype.t = t\n\nconst View = Vue.extend(App)\nconst theming = new View()\ntheming.$mount('#theming')\n\ntheming.$on('update:background', () => {\n\t// Refresh server-side generated theming CSS\n\t[...document.head.querySelectorAll('link.theme')].forEach(theme => {\n\t\tconst url = new URL(theme.href)\n\t\turl.searchParams.set('v', Date.now())\n\t\tconst newTheme = theme.cloneNode()\n\t\tnewTheme.href = url.toString()\n\t\tnewTheme.onload = () => theme.remove()\n\t\tdocument.head.append(newTheme)\n\t})\n})\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".theming p[data-v-a788b9b8]{max-width:800px}.theming[data-v-a788b9b8] a{font-weight:bold}.theming[data-v-a788b9b8] a:hover,.theming[data-v-a788b9b8] a:focus{text-decoration:underline}.theming__preview-list[data-v-a788b9b8]{--gap: 30px;display:grid;margin-top:var(--gap);column-gap:var(--gap);row-gap:var(--gap);grid-template-columns:1fr 1fr}.background__grid[data-v-a788b9b8]{margin-top:30px}@media(max-width: 1440px){.theming__preview-list[data-v-a788b9b8]{display:flex;flex-direction:column}}\", \"\",{\"version\":3,\"sources\":[\"webpack://./apps/theming/src/UserThemes.vue\"],\"names\":[],\"mappings\":\"AA+RC,4BACC,eAAA,CAID,4BACC,gBAAA,CAEA,oEAEC,yBAAA,CAIF,wCACC,WAAA,CAEA,YAAA,CACA,qBAAA,CACA,qBAAA,CACA,kBAAA,CACA,6BAAA,CAKD,mCACC,eAAA,CAIF,0BACC,wCACC,YAAA,CACA,qBAAA,CAAA\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n.theming {\\n\\t// Limit width of settings sections for readability\\n\\tp {\\n\\t\\tmax-width: 800px;\\n\\t}\\n\\n\\t// Proper highlight for links and focus feedback\\n\\t&::v-deep a {\\n\\t\\tfont-weight: bold;\\n\\n\\t\\t&:hover,\\n\\t\\t&:focus {\\n\\t\\t\\ttext-decoration: underline;\\n\\t\\t}\\n\\t}\\n\\n\\t&__preview-list {\\n\\t\\t--gap: 30px;\\n\\n\\t\\tdisplay: grid;\\n\\t\\tmargin-top: var(--gap);\\n\\t\\tcolumn-gap: var(--gap);\\n\\t\\trow-gap: var(--gap);\\n\\t\\tgrid-template-columns: 1fr 1fr;\\n\\t}\\n}\\n\\n.background {\\n\\t&__grid {\\n\\t\\tmargin-top: 30px;\\n\\t}\\n}\\n\\n@media (max-width: 1440px) {\\n\\t.theming__preview-list {\\n\\t\\tdisplay: flex;\\n\\t\\tflex-direction: column;\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".background-selector[data-v-5ccad868]{display:flex;flex-wrap:wrap;justify-content:center}.background-selector .background[data-v-5ccad868]{width:176px;height:96px;margin:8px;background-size:cover;background-position:center center;text-align:center;border-radius:var(--border-radius-large);border:2px solid var(--color-main-background);overflow:hidden}.background-selector .background.current[data-v-5ccad868]{background-image:var(--color-background-dark)}.background-selector .background.filepicker[data-v-5ccad868],.background-selector .background.default[data-v-5ccad868],.background-selector .background.color[data-v-5ccad868]{border-color:var(--color-border)}.background-selector .background.color[data-v-5ccad868]{background-color:var(--color-primary);color:var(--color-primary-text)}.background-selector .background.active[data-v-5ccad868],.background-selector .background[data-v-5ccad868]:hover,.background-selector .background[data-v-5ccad868]:focus{border:2px solid var(--color-primary)}.background-selector .background.active[data-v-5ccad868]:not(.icon-loading):after{background-image:var(--icon-checkmark-white);background-repeat:no-repeat;background-position:center;background-size:44px;content:\\\"\\\";display:block;height:100%}\", \"\",{\"version\":3,\"sources\":[\"webpack://./apps/theming/src/components/BackgroundSettings.vue\"],\"names\":[],\"mappings\":\"AAoJA,sCACC,YAAA,CACA,cAAA,CACA,sBAAA,CAEA,kDACC,WAAA,CACA,WAAA,CACA,UAAA,CACA,qBAAA,CACA,iCAAA,CACA,iBAAA,CACA,wCAAA,CACA,6CAAA,CACA,eAAA,CAEA,0DACC,6CAAA,CAGD,+KACC,gCAAA,CAGD,wDACC,qCAAA,CACA,+BAAA,CAGD,yKAGC,qCAAA,CAGD,kFACC,4CAAA,CACA,2BAAA,CACA,0BAAA,CACA,oBAAA,CACA,UAAA,CACA,aAAA,CACA,WAAA\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n.background-selector {\\n\\tdisplay: flex;\\n\\tflex-wrap: wrap;\\n\\tjustify-content: center;\\n\\n\\t.background {\\n\\t\\twidth: 176px;\\n\\t\\theight: 96px;\\n\\t\\tmargin: 8px;\\n\\t\\tbackground-size: cover;\\n\\t\\tbackground-position: center center;\\n\\t\\ttext-align: center;\\n\\t\\tborder-radius: var(--border-radius-large);\\n\\t\\tborder: 2px solid var(--color-main-background);\\n\\t\\toverflow: hidden;\\n\\n\\t\\t&.current {\\n\\t\\t\\tbackground-image: var(--color-background-dark);\\n\\t\\t}\\n\\n\\t\\t&.filepicker, &.default, &.color {\\n\\t\\t\\tborder-color: var(--color-border);\\n\\t\\t}\\n\\n\\t\\t&.color {\\n\\t\\t\\tbackground-color: var(--color-primary);\\n\\t\\t\\tcolor: var(--color-primary-text);\\n\\t\\t}\\n\\n\\t\\t&.active,\\n\\t\\t&:hover,\\n\\t\\t&:focus {\\n\\t\\t\\tborder: 2px solid var(--color-primary);\\n\\t\\t}\\n\\n\\t\\t&.active:not(.icon-loading):after {\\n\\t\\t\\tbackground-image: var(--icon-checkmark-white);\\n\\t\\t\\tbackground-repeat: no-repeat;\\n\\t\\t\\tbackground-position: center;\\n\\t\\t\\tbackground-size: 44px;\\n\\t\\t\\tcontent: '';\\n\\t\\t\\tdisplay: block;\\n\\t\\t\\theight: 100%;\\n\\t\\t}\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".theming__preview[data-v-37ca8ab2]{--ratio: 16;position:relative;display:flex;justify-content:flex-start;max-width:800px}.theming__preview[data-v-37ca8ab2],.theming__preview *[data-v-37ca8ab2]{user-select:none}.theming__preview-image[data-v-37ca8ab2]{flex-basis:calc(16px*var(--ratio));flex-shrink:0;height:calc(10px*var(--ratio));margin-right:var(--gap);cursor:pointer;border-radius:var(--border-radius);background-repeat:no-repeat;background-position:top left;background-size:cover}.theming__preview-description[data-v-37ca8ab2]{display:flex;flex-direction:column}.theming__preview-description label[data-v-37ca8ab2]{padding:12px 0}.theming__preview--default[data-v-37ca8ab2]{grid-column:span 2}.theming__preview-warning[data-v-37ca8ab2]{color:var(--color-warning)}@media(max-width: 682.6666666667px){.theming__preview[data-v-37ca8ab2]{flex-direction:column}.theming__preview-image[data-v-37ca8ab2]{margin:0}}\", \"\",{\"version\":3,\"sources\":[\"webpack://./apps/theming/src/components/ItemPreview.vue\"],\"names\":[],\"mappings\":\"AAiGA,mCAEC,WAAA,CAEA,iBAAA,CACA,YAAA,CACA,0BAAA,CACA,eAAA,CAEA,wEAEC,gBAAA,CAGD,yCACC,kCAAA,CACA,aAAA,CACA,8BAAA,CACA,uBAAA,CACA,cAAA,CACA,kCAAA,CACA,2BAAA,CACA,4BAAA,CACA,qBAAA,CAGD,+CACC,YAAA,CACA,qBAAA,CAEA,qDACC,cAAA,CAIF,4CACC,kBAAA,CAGD,2CACC,0BAAA,CAIF,oCACC,mCACC,qBAAA,CAEA,yCACC,QAAA,CAAA\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n.theming__preview {\\n\\t// We make previews on 16/10 screens\\n\\t--ratio: 16;\\n\\n\\tposition: relative;\\n\\tdisplay: flex;\\n\\tjustify-content: flex-start;\\n\\tmax-width: 800px;\\n\\n\\t&,\\n\\t* {\\n\\t\\tuser-select: none;\\n\\t}\\n\\n\\t&-image {\\n\\t\\tflex-basis: calc(16px * var(--ratio));\\n\\t\\tflex-shrink: 0;\\n\\t\\theight: calc(10px * var(--ratio));\\n\\t\\tmargin-right: var(--gap);\\n\\t\\tcursor: pointer;\\n\\t\\tborder-radius: var(--border-radius);\\n\\t\\tbackground-repeat: no-repeat;\\n\\t\\tbackground-position: top left;\\n\\t\\tbackground-size: cover;\\n\\t}\\n\\n\\t&-description {\\n\\t\\tdisplay: flex;\\n\\t\\tflex-direction: column;\\n\\n\\t\\tlabel {\\n\\t\\t\\tpadding: 12px 0;\\n\\t\\t}\\n\\t}\\n\\n\\t&--default {\\n\\t\\tgrid-column: span 2;\\n\\t}\\n\\n\\t&-warning {\\n\\t\\tcolor: var(--color-warning);\\n\\t}\\n}\\n\\n@media (max-width: (1024px / 1.5)) {\\n\\t.theming__preview {\\n\\t\\tflex-direction: column;\\n\\n\\t\\t&-image {\\n\\t\\t\\tmargin: 0;\\n\\t\\t}\\n\\t}\\n}\\n\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","__webpack_require__.amdD = function () {\n\tthrow new Error('define cannot be used indirect');\n};","__webpack_require__.amdO = {};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nmd = function(module) {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","__webpack_require__.j = 6755;","__webpack_require__.b = document.baseURI || self.location.href;\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t6755: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunknextcloud\"] = self[\"webpackChunknextcloud\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","__webpack_require__.nc = undefined;","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [7874], function() { return __webpack_require__(94818); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","prefixWithBaseUrl","url","generateFilePath","getBackgroundUrl","background","time","themingDefaultBackground","enabledThemes","window","OCA","Theming","isDarkTheme","length","matchMedia","matches","join","indexOf","generateUrl","cacheBuster","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","_vm","this","_h","$createElement","_c","_self","staticClass","class","active","attrs","on","pickFile","_v","_s","t","loading","setDefault","startsWith","pickColor","_l","shippedBackground","directives","name","rawName","value","details","expression","key","style","preview","$event","setShipped","theme","id","backgroundImage","img","onToggle","title","description","_e","checked","enforced","switchType","enableLabel","console","debug","availableThemes","domProps","descriptionDetail","enforceTheme","selectedTheme","themes","changeTheme","enabled","fonts","changeFont","shortcutsDisabled","changeShortcutsDisabled","updateBackground","Vue","OC","theming","App","$mount","$on","document","head","querySelectorAll","forEach","URL","href","searchParams","set","Date","now","newTheme","cloneNode","toString","onload","remove","append","___CSS_LOADER_EXPORT___","push","module","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","loaded","__webpack_modules__","call","m","amdD","Error","amdO","O","result","chunkIds","fn","priority","notFulfilled","Infinity","i","fulfilled","j","Object","keys","every","splice","r","n","getter","__esModule","d","a","definition","o","defineProperty","enumerable","get","g","globalThis","Function","e","obj","prop","prototype","hasOwnProperty","Symbol","toStringTag","nmd","paths","children","b","baseURI","self","location","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","data","moreModules","runtime","some","chunkLoadingGlobal","bind","nc","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file
+{"version":3,"file":"theming-theming-settings.js?v=478aa74ec2979a9203af","mappings":"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","sources":["webpack:///nextcloud/webpack/runtime/chunk loaded","webpack:///nextcloud/apps/theming/src/helpers/prefixWithBaseUrl.js","webpack:///nextcloud/apps/theming/src/helpers/getBackgroundUrl.js","webpack:///nextcloud/apps/theming/src/components/BackgroundSettings.vue","webpack:///nextcloud/apps/theming/src/components/BackgroundSettings.vue?vue&type=script&lang=js&","webpack://nextcloud/./apps/theming/src/components/BackgroundSettings.vue?b3fe","webpack://nextcloud/./apps/theming/src/components/BackgroundSettings.vue?65db","webpack:///nextcloud/apps/theming/src/components/BackgroundSettings.vue?vue&type=template&id=48e565ba&scoped=true&","webpack:///nextcloud/apps/theming/src/components/ItemPreview.vue?vue&type=script&lang=js&","webpack:///nextcloud/apps/theming/src/components/ItemPreview.vue","webpack://nextcloud/./apps/theming/src/components/ItemPreview.vue?f1c6","webpack://nextcloud/./apps/theming/src/components/ItemPreview.vue?8797","webpack:///nextcloud/apps/theming/src/components/ItemPreview.vue?vue&type=template&id=37ca8ab2&scoped=true&","webpack:///nextcloud/apps/theming/src/UserThemes.vue","webpack:///nextcloud/apps/theming/src/UserThemes.vue?vue&type=script&lang=js&","webpack://nextcloud/./apps/theming/src/UserThemes.vue?52b2","webpack://nextcloud/./apps/theming/src/UserThemes.vue?7eb2","webpack:///nextcloud/apps/theming/src/UserThemes.vue?vue&type=template&id=a788b9b8&scoped=true&","webpack:///nextcloud/apps/theming/src/settings.js","webpack:///nextcloud/apps/theming/src/UserThemes.vue?vue&type=style&index=0&id=a788b9b8&lang=scss&scoped=true&","webpack:///nextcloud/apps/theming/src/components/BackgroundSettings.vue?vue&type=style&index=0&id=48e565ba&scoped=true&lang=scss&","webpack:///nextcloud/apps/theming/src/components/ItemPreview.vue?vue&type=style&index=0&id=37ca8ab2&lang=scss&scoped=true&","webpack:///nextcloud/webpack/bootstrap","webpack:///nextcloud/webpack/runtime/amd define","webpack:///nextcloud/webpack/runtime/amd options","webpack:///nextcloud/webpack/runtime/compat get default export","webpack:///nextcloud/webpack/runtime/define property getters","webpack:///nextcloud/webpack/runtime/global","webpack:///nextcloud/webpack/runtime/hasOwnProperty shorthand","webpack:///nextcloud/webpack/runtime/make namespace object","webpack:///nextcloud/webpack/runtime/node module decorator","webpack:///nextcloud/webpack/runtime/runtimeId","webpack:///nextcloud/webpack/runtime/jsonp chunk loading","webpack:///nextcloud/webpack/runtime/nonce","webpack:///nextcloud/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = function(result, chunkIds, fn, priority) {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","/**\n * @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>\n *\n * @author Julius Härtl <jus@bitgrid.net>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { generateFilePath } from '@nextcloud/router'\n\nexport const prefixWithBaseUrl = (url) => generateFilePath('theming', '', 'img/background/') + url\n","/**\n * @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>\n *\n * @author Avior <florian.bouillon@delta-wings.net>\n * @author Julien Veyssier <eneiluj@posteo.net>\n * @author Julius Härtl <jus@bitgrid.net>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { generateUrl } from '@nextcloud/router'\nimport { prefixWithBaseUrl } from './prefixWithBaseUrl.js'\n\nexport const getBackgroundUrl = (background, time = 0, themingDefaultBackground = '') => {\n\tconst enabledThemes = window.OCA?.Theming?.enabledThemes || []\n\tconst isDarkTheme = (enabledThemes.length === 0 || enabledThemes[0] === 'default')\n\t\t? window.matchMedia('(prefers-color-scheme: dark)').matches\n\t\t: enabledThemes.join('').indexOf('dark') !== -1\n\n\tif (background === 'default') {\n\t\tif (themingDefaultBackground && themingDefaultBackground !== 'backgroundColor') {\n\t\t\treturn generateUrl('/apps/theming/image/background') + '?v=' + window.OCA.Theming.cacheBuster\n\t\t}\n\n\t\tif (isDarkTheme) {\n\t\t\treturn prefixWithBaseUrl('eduardo-neves-pedra-azul.jpg')\n\t\t}\n\n\t\treturn prefixWithBaseUrl('kamil-porembinski-clouds.jpg')\n\t} else if (background === 'custom') {\n\t\treturn generateUrl('/apps/theming/background') + '?v=' + time\n\t}\n\n\treturn prefixWithBaseUrl(background)\n}\n","<!--\n - @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>\n - @copyright Copyright (c) 2022 Greta Doci <gretadoci@gmail.com>\n -\n - @author Julius Härtl <jus@bitgrid.net>\n - @author Greta Doci <gretadoci@gmail.com>\n - @author Christopher Ng <chrng8@gmail.com>\n -\n - @license GNU AGPL version 3 or any later version\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n\n<template>\n\t<div class=\"background-selector\">\n\t\t<button class=\"background filepicker\"\n\t\t\t:class=\"{ active: background === 'custom' }\"\n\t\t\ttabindex=\"0\"\n\t\t\t@click=\"pickFile\">\n\t\t\t{{ t('theming', 'Pick from Files') }}\n\t\t</button>\n\t\t<button class=\"background default\"\n\t\t\ttabindex=\"0\"\n\t\t\t:class=\"{ 'icon-loading': loading === 'default', active: background === 'default' }\"\n\t\t\t@click=\"setDefault\">\n\t\t\t{{ t('theming', 'Default image') }}\n\t\t</button>\n\t\t<button class=\"background color\"\n\t\t\t:class=\"{ active: background.startsWith('#') }\"\n\t\t\ttabindex=\"0\"\n\t\t\t@click=\"pickColor\">\n\t\t\t{{ t('theming', 'Plain background') }}\n\t\t</button>\n\t\t<button v-for=\"shippedBackground in shippedBackgrounds\"\n\t\t\t:key=\"shippedBackground.name\"\n\t\t\tv-tooltip=\"shippedBackground.details.attribution\"\n\t\t\t:class=\"{ 'icon-loading': loading === shippedBackground.name, active: background === shippedBackground.name }\"\n\t\t\ttabindex=\"0\"\n\t\t\tclass=\"background\"\n\t\t\t:style=\"{ 'background-image': 'url(' + shippedBackground.preview + ')' }\"\n\t\t\t@click=\"setShipped(shippedBackground.name)\" />\n\t</div>\n</template>\n\n<script>\nimport axios from '@nextcloud/axios'\nimport Tooltip from '@nextcloud/vue/dist/Directives/Tooltip'\nimport { generateUrl } from '@nextcloud/router'\nimport { loadState } from '@nextcloud/initial-state'\nimport { getBackgroundUrl } from '../helpers/getBackgroundUrl.js'\nimport { prefixWithBaseUrl } from '../helpers/prefixWithBaseUrl.js'\n\nconst shippedBackgroundList = loadState('theming', 'shippedBackgrounds')\n\nexport default {\n\tname: 'BackgroundSettings',\n\tdirectives: {\n\t\tTooltip,\n\t},\n\tprops: {\n\t\tbackground: {\n\t\t\ttype: String,\n\t\t\tdefault: 'default',\n\t\t},\n\t\tthemingDefaultBackground: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t},\n\tdata() {\n\t\treturn {\n\t\t\tbackgroundImage: generateUrl('/apps/theming/background') + '?v=' + Date.now(),\n\t\t\tloading: false,\n\t\t}\n\t},\n\tcomputed: {\n\t\tshippedBackgrounds() {\n\t\t\treturn Object.keys(shippedBackgroundList).map(fileName => {\n\t\t\t\treturn {\n\t\t\t\t\tname: fileName,\n\t\t\t\t\turl: prefixWithBaseUrl(fileName),\n\t\t\t\t\tpreview: prefixWithBaseUrl('preview/' + fileName),\n\t\t\t\t\tdetails: shippedBackgroundList[fileName],\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\t},\n\tmethods: {\n\t\tasync update(data) {\n\t\t\tconst background = data.type === 'custom' || data.type === 'default' ? data.type : data.value\n\t\t\tthis.backgroundImage = getBackgroundUrl(background, data.version, this.themingDefaultBackground)\n\t\t\tif (data.type === 'color' || (data.type === 'default' && this.themingDefaultBackground === 'backgroundColor')) {\n\t\t\t\tthis.$emit('update:background', data)\n\t\t\t\tthis.loading = false\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst image = new Image()\n\t\t\timage.onload = () => {\n\t\t\t\tthis.$emit('update:background', data)\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t\timage.src = this.backgroundImage\n\t\t},\n\t\tasync setDefault() {\n\t\t\tthis.loading = 'default'\n\t\t\tconst result = await axios.post(generateUrl('/apps/theming/background/default'))\n\t\t\tthis.update(result.data)\n\t\t},\n\t\tasync setShipped(shipped) {\n\t\t\tthis.loading = shipped\n\t\t\tconst result = await axios.post(generateUrl('/apps/theming/background/shipped'), { value: shipped })\n\t\t\tthis.update(result.data)\n\t\t},\n\t\tasync setFile(path) {\n\t\t\tthis.loading = 'custom'\n\t\t\tconst result = await axios.post(generateUrl('/apps/theming/background/custom'), { value: path })\n\t\t\tthis.update(result.data)\n\t\t},\n\t\tasync pickColor() {\n\t\t\tthis.loading = 'color'\n\t\t\tconst color = OCA && OCA.Theming ? OCA.Theming.color : '#0082c9'\n\t\t\tconst result = await axios.post(generateUrl('/apps/theming/background/color'), { value: color })\n\t\t\tthis.update(result.data)\n\t\t},\n\t\tpickFile() {\n\t\t\twindow.OC.dialogs.filepicker(t('theming', 'Insert from {productName}', { productName: OC.theme.name }), (path, type) => {\n\t\t\t\tif (type === OC.dialogs.FILEPICKER_TYPE_CHOOSE) {\n\t\t\t\t\tthis.setFile(path)\n\t\t\t\t}\n\t\t\t}, false, ['image/png', 'image/gif', 'image/jpeg', 'image/svg'], true, OC.dialogs.FILEPICKER_TYPE_CHOOSE)\n\t\t},\n\t},\n}\n</script>\n\n<style scoped lang=\"scss\">\n.background-selector {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tjustify-content: center;\n\n\t.background {\n\t\twidth: 176px;\n\t\theight: 96px;\n\t\tmargin: 8px;\n\t\tbackground-size: cover;\n\t\tbackground-position: center center;\n\t\ttext-align: center;\n\t\tborder-radius: var(--border-radius-large);\n\t\tborder: 2px solid var(--color-main-background);\n\t\toverflow: hidden;\n\n\t\t&.current {\n\t\t\tbackground-image: var(--color-background-dark);\n\t\t}\n\n\t\t&.filepicker, &.default, &.color {\n\t\t\tborder-color: var(--color-border);\n\t\t}\n\n\t\t&.color {\n\t\t\tbackground-color: var(--color-main-background-not-plain, var(--color-primary));\n\t\t\tcolor: var(--color-primary-text);\n\t\t}\n\n\t\t&.active,\n\t\t&:hover,\n\t\t&:focus {\n\t\t\tborder: 2px solid var(--color-primary);\n\t\t}\n\n\t\t&.active:not(.icon-loading):after {\n\t\t\tbackground-image: var(--icon-checkmark-white);\n\t\t\tbackground-repeat: no-repeat;\n\t\t\tbackground-position: center;\n\t\t\tbackground-size: 44px;\n\t\t\tcontent: '';\n\t\t\tdisplay: block;\n\t\t\theight: 100%;\n\t\t}\n\t}\n}\n</style>\n","import mod from \"-!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./BackgroundSettings.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./BackgroundSettings.vue?vue&type=script&lang=js&\"","\n import API from \"!../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/sass-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./BackgroundSettings.vue?vue&type=style&index=0&id=48e565ba&scoped=true&lang=scss&\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/sass-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./BackgroundSettings.vue?vue&type=style&index=0&id=48e565ba&scoped=true&lang=scss&\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./BackgroundSettings.vue?vue&type=template&id=48e565ba&scoped=true&\"\nimport script from \"./BackgroundSettings.vue?vue&type=script&lang=js&\"\nexport * from \"./BackgroundSettings.vue?vue&type=script&lang=js&\"\nimport style0 from \"./BackgroundSettings.vue?vue&type=style&index=0&id=48e565ba&scoped=true&lang=scss&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"48e565ba\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"background-selector\"},[_c('button',{staticClass:\"background filepicker\",class:{ active: _vm.background === 'custom' },attrs:{\"tabindex\":\"0\"},on:{\"click\":_vm.pickFile}},[_vm._v(\"\\n\\t\\t\"+_vm._s(_vm.t('theming', 'Pick from Files'))+\"\\n\\t\")]),_vm._v(\" \"),_c('button',{staticClass:\"background default\",class:{ 'icon-loading': _vm.loading === 'default', active: _vm.background === 'default' },attrs:{\"tabindex\":\"0\"},on:{\"click\":_vm.setDefault}},[_vm._v(\"\\n\\t\\t\"+_vm._s(_vm.t('theming', 'Default image'))+\"\\n\\t\")]),_vm._v(\" \"),_c('button',{staticClass:\"background color\",class:{ active: _vm.background.startsWith('#') },attrs:{\"tabindex\":\"0\"},on:{\"click\":_vm.pickColor}},[_vm._v(\"\\n\\t\\t\"+_vm._s(_vm.t('theming', 'Plain background'))+\"\\n\\t\")]),_vm._v(\" \"),_vm._l((_vm.shippedBackgrounds),function(shippedBackground){return _c('button',{directives:[{name:\"tooltip\",rawName:\"v-tooltip\",value:(shippedBackground.details.attribution),expression:\"shippedBackground.details.attribution\"}],key:shippedBackground.name,staticClass:\"background\",class:{ 'icon-loading': _vm.loading === shippedBackground.name, active: _vm.background === shippedBackground.name },style:({ 'background-image': 'url(' + shippedBackground.preview + ')' }),attrs:{\"tabindex\":\"0\"},on:{\"click\":function($event){return _vm.setShipped(shippedBackground.name)}}})})],2)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import mod from \"-!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./ItemPreview.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./ItemPreview.vue?vue&type=script&lang=js&\"","<template>\n\t<div :class=\"'theming__preview--' + theme.id\" class=\"theming__preview\">\n\t\t<div class=\"theming__preview-image\" :style=\"{ backgroundImage: 'url(' + img + ')' }\" @click=\"onToggle\" />\n\t\t<div class=\"theming__preview-description\">\n\t\t\t<h3>{{ theme.title }}</h3>\n\t\t\t<p>{{ theme.description }}</p>\n\t\t\t<span v-if=\"enforced\" class=\"theming__preview-warning\" role=\"note\">\n\t\t\t\t{{ t('theming', 'Theme selection is enforced') }}\n\t\t\t</span>\n\t\t\t<NcCheckboxRadioSwitch class=\"theming__preview-toggle\"\n\t\t\t\t:checked.sync=\"checked\"\n\t\t\t\t:disabled=\"enforced\"\n\t\t\t\t:name=\"name\"\n\t\t\t\t:type=\"switchType\">\n\t\t\t\t{{ theme.enableLabel }}\n\t\t\t</NcCheckboxRadioSwitch>\n\t\t</div>\n\t</div>\n</template>\n\n<script>\nimport { generateFilePath } from '@nextcloud/router'\nimport NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch'\n\nexport default {\n\tname: 'ItemPreview',\n\tcomponents: {\n\t\tNcCheckboxRadioSwitch,\n\t},\n\tprops: {\n\t\tenforced: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\tselected: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\ttheme: {\n\t\t\ttype: Object,\n\t\t\trequired: true,\n\t\t},\n\t\ttype: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t\tunique: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\tcomputed: {\n\t\tswitchType() {\n\t\t\treturn this.unique ? 'switch' : 'radio'\n\t\t},\n\n\t\tname() {\n\t\t\treturn !this.unique ? this.type : null\n\t\t},\n\n\t\timg() {\n\t\t\treturn generateFilePath('theming', 'img', this.theme.id + '.jpg')\n\t\t},\n\n\t\tchecked: {\n\t\t\tget() {\n\t\t\t\treturn this.selected\n\t\t\t},\n\t\t\tset(checked) {\n\t\t\t\tconsole.debug('Changed theme', this.theme.id, checked)\n\n\t\t\t\t// If this is a radio, we can only enable\n\t\t\t\tif (!this.unique) {\n\t\t\t\t\tthis.$emit('change', { enabled: true, id: this.theme.id })\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// If this is a switch, we can disable the theme\n\t\t\t\tthis.$emit('change', { enabled: checked === true, id: this.theme.id })\n\t\t\t},\n\t\t},\n\t},\n\n\tmethods: {\n\t\tonToggle() {\n\t\t\tif (this.switchType === 'radio') {\n\t\t\t\tthis.checked = true\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Invert state\n\t\t\tthis.checked = !this.checked\n\t\t},\n\t},\n}\n</script>\n<style lang=\"scss\" scoped>\n.theming__preview {\n\t// We make previews on 16/10 screens\n\t--ratio: 16;\n\n\tposition: relative;\n\tdisplay: flex;\n\tjustify-content: flex-start;\n\tmax-width: 800px;\n\n\t&,\n\t* {\n\t\tuser-select: none;\n\t}\n\n\t&-image {\n\t\tflex-basis: calc(16px * var(--ratio));\n\t\tflex-shrink: 0;\n\t\theight: calc(10px * var(--ratio));\n\t\tmargin-right: var(--gap);\n\t\tcursor: pointer;\n\t\tborder-radius: var(--border-radius);\n\t\tbackground-repeat: no-repeat;\n\t\tbackground-position: top left;\n\t\tbackground-size: cover;\n\t}\n\n\t&-description {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\n\t\tlabel {\n\t\t\tpadding: 12px 0;\n\t\t}\n\t}\n\n\t&--default {\n\t\tgrid-column: span 2;\n\t}\n\n\t&-warning {\n\t\tcolor: var(--color-warning);\n\t}\n}\n\n@media (max-width: (1024px / 1.5)) {\n\t.theming__preview {\n\t\tflex-direction: column;\n\n\t\t&-image {\n\t\t\tmargin: 0;\n\t\t}\n\t}\n}\n\n</style>\n","\n import API from \"!../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/sass-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./ItemPreview.vue?vue&type=style&index=0&id=37ca8ab2&lang=scss&scoped=true&\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/sass-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./ItemPreview.vue?vue&type=style&index=0&id=37ca8ab2&lang=scss&scoped=true&\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./ItemPreview.vue?vue&type=template&id=37ca8ab2&scoped=true&\"\nimport script from \"./ItemPreview.vue?vue&type=script&lang=js&\"\nexport * from \"./ItemPreview.vue?vue&type=script&lang=js&\"\nimport style0 from \"./ItemPreview.vue?vue&type=style&index=0&id=37ca8ab2&lang=scss&scoped=true&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"37ca8ab2\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"theming__preview\",class:'theming__preview--' + _vm.theme.id},[_c('div',{staticClass:\"theming__preview-image\",style:({ backgroundImage: 'url(' + _vm.img + ')' }),on:{\"click\":_vm.onToggle}}),_vm._v(\" \"),_c('div',{staticClass:\"theming__preview-description\"},[_c('h3',[_vm._v(_vm._s(_vm.theme.title))]),_vm._v(\" \"),_c('p',[_vm._v(_vm._s(_vm.theme.description))]),_vm._v(\" \"),(_vm.enforced)?_c('span',{staticClass:\"theming__preview-warning\",attrs:{\"role\":\"note\"}},[_vm._v(\"\\n\\t\\t\\t\"+_vm._s(_vm.t('theming', 'Theme selection is enforced'))+\"\\n\\t\\t\")]):_vm._e(),_vm._v(\" \"),_c('NcCheckboxRadioSwitch',{staticClass:\"theming__preview-toggle\",attrs:{\"checked\":_vm.checked,\"disabled\":_vm.enforced,\"name\":_vm.name,\"type\":_vm.switchType},on:{\"update:checked\":function($event){_vm.checked=$event}}},[_vm._v(\"\\n\\t\\t\\t\"+_vm._s(_vm.theme.enableLabel)+\"\\n\\t\\t\")])],1)])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","<!--\n - @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>\n - @copyright Copyright (c) 2022 Greta Doci <gretadoci@gmail.com>\n -\n - @author Christopher Ng <chrng8@gmail.com>\n -\n - @license AGPL-3.0-or-later\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n-->\n\n<template>\n\t<section>\n\t\t<NcSettingsSection :title=\"t('theming', 'Appearance and accessibility')\"\n\t\t\t:limit-width=\"false\"\n\t\t\tclass=\"theming\">\n\t\t\t<p v-html=\"description\" />\n\t\t\t<p v-html=\"descriptionDetail\" />\n\n\t\t\t<div class=\"theming__preview-list\">\n\t\t\t\t<ItemPreview v-for=\"theme in themes\"\n\t\t\t\t\t:key=\"theme.id\"\n\t\t\t\t\t:enforced=\"theme.id === enforceTheme\"\n\t\t\t\t\t:selected=\"selectedTheme.id === theme.id\"\n\t\t\t\t\t:theme=\"theme\"\n\t\t\t\t\t:unique=\"themes.length === 1\"\n\t\t\t\t\ttype=\"theme\"\n\t\t\t\t\t@change=\"changeTheme\" />\n\t\t\t</div>\n\n\t\t\t<div class=\"theming__preview-list\">\n\t\t\t\t<ItemPreview v-for=\"theme in fonts\"\n\t\t\t\t\t:key=\"theme.id\"\n\t\t\t\t\t:selected=\"theme.enabled\"\n\t\t\t\t\t:theme=\"theme\"\n\t\t\t\t\t:unique=\"fonts.length === 1\"\n\t\t\t\t\ttype=\"font\"\n\t\t\t\t\t@change=\"changeFont\" />\n\t\t\t</div>\n\t\t</NcSettingsSection>\n\n\t\t<NcSettingsSection :title=\"t('theming', 'Keyboard shortcuts')\">\n\t\t\t<p>{{ t('theming', 'In some cases keyboard shortcuts can interfer with accessibility tools. In order to allow focusing on your tool correctly you can disable all keyboard shortcuts here. This will also disable all available shortcuts in apps.') }}</p>\n\t\t\t<NcCheckboxRadioSwitch class=\"theming__preview-toggle\"\n\t\t\t\t:checked.sync=\"shortcutsDisabled\"\n\t\t\t\tname=\"shortcuts_disabled\"\n\t\t\t\ttype=\"switch\"\n\t\t\t\t@change=\"changeShortcutsDisabled\">\n\t\t\t\t{{ t('theming', 'Disable all keyboard shortcuts') }}\n\t\t\t</NcCheckboxRadioSwitch>\n\t\t</NcSettingsSection>\n\n\t\t<NcSettingsSection :title=\"t('theming', 'Background')\"\n\t\t\tclass=\"background\">\n\t\t\t<p>{{ t('theming', 'Set a custom background') }}</p>\n\t\t\t<BackgroundSettings class=\"background__grid\"\n\t\t\t\t:background=\"background\"\n\t\t\t\t:theming-default-background=\"themingDefaultBackground\"\n\t\t\t\t@update:background=\"updateBackground\" />\n\t\t</NcSettingsSection>\n\t</section>\n</template>\n\n<script>\nimport { generateOcsUrl } from '@nextcloud/router'\nimport { loadState } from '@nextcloud/initial-state'\nimport axios from '@nextcloud/axios'\nimport NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch'\nimport NcSettingsSection from '@nextcloud/vue/dist/Components/NcSettingsSection'\n\nimport BackgroundSettings from './components/BackgroundSettings.vue'\nimport ItemPreview from './components/ItemPreview.vue'\n\nconst availableThemes = loadState('theming', 'themes', [])\nconst enforceTheme = loadState('theming', 'enforceTheme', '')\nconst shortcutsDisabled = loadState('theming', 'shortcutsDisabled', false)\n\nconst background = loadState('theming', 'background')\nconst backgroundVersion = loadState('theming', 'backgroundVersion')\nconst themingDefaultBackground = loadState('theming', 'themingDefaultBackground')\nconst shippedBackgroundList = loadState('theming', 'shippedBackgrounds')\n\nconsole.debug('Available themes', availableThemes)\n\nexport default {\n\tname: 'UserThemes',\n\tcomponents: {\n\t\tItemPreview,\n\t\tNcCheckboxRadioSwitch,\n\t\tNcSettingsSection,\n\t\tBackgroundSettings,\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tavailableThemes,\n\t\t\tenforceTheme,\n\t\t\tshortcutsDisabled,\n\t\t\tbackground,\n\t\t\tbackgroundVersion,\n\t\t\tthemingDefaultBackground,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\tthemes() {\n\t\t\treturn this.availableThemes.filter(theme => theme.type === 1)\n\t\t},\n\t\tfonts() {\n\t\t\treturn this.availableThemes.filter(theme => theme.type === 2)\n\t\t},\n\n\t\t// Selected theme, fallback on first (default) if none\n\t\tselectedTheme() {\n\t\t\treturn this.themes.find(theme => theme.enabled === true) || this.themes[0]\n\t\t},\n\n\t\tdescription() {\n\t\t\t// using the `t` replace method escape html, we have to do it manually :/\n\t\t\treturn t(\n\t\t\t\t'theming',\n\t\t\t\t'Universal access is very important to us. We follow web standards and check to make everything usable also without mouse, and assistive software such as screenreaders. We aim to be compliant with the {guidelines}Web Content Accessibility Guidelines{linkend} 2.1 on AA level, with the high contrast theme even on AAA level.'\n\t\t\t)\n\t\t\t\t.replace('{guidelines}', this.guidelinesLink)\n\t\t\t\t.replace('{linkend}', '</a>')\n\t\t},\n\t\tguidelinesLink() {\n\t\t\treturn '<a target=\"_blank\" href=\"https://www.w3.org/WAI/standards-guidelines/wcag/\" rel=\"noreferrer nofollow\">'\n\t\t},\n\t\tdescriptionDetail() {\n\t\t\treturn t(\n\t\t\t\t'theming',\n\t\t\t\t'If you find any issues, do not hesitate to report them on {issuetracker}our issue tracker{linkend}. And if you want to get involved, come join {designteam}our design team{linkend}!'\n\t\t\t)\n\t\t\t\t.replace('{issuetracker}', this.issuetrackerLink)\n\t\t\t\t.replace('{designteam}', this.designteamLink)\n\t\t\t\t.replace(/\\{linkend\\}/g, '</a>')\n\t\t},\n\t\tissuetrackerLink() {\n\t\t\treturn '<a target=\"_blank\" href=\"https://github.com/nextcloud/server/issues/\" rel=\"noreferrer nofollow\">'\n\t\t},\n\t\tdesignteamLink() {\n\t\t\treturn '<a target=\"_blank\" href=\"https://nextcloud.com/design\" rel=\"noreferrer nofollow\">'\n\t\t},\n\t},\n\n\tmounted() {\n\t\tthis.updateGlobalStyles()\n\t},\n\n\twatch: {\n\t\tshortcutsDisabled(newState) {\n\t\t\tthis.changeShortcutsDisabled(newState)\n\t\t},\n\t},\n\n\tmethods: {\n\t\tupdateBackground(data) {\n\t\t\tthis.background = (data.type === 'custom' || data.type === 'default') ? data.type : data.value\n\t\t\tthis.backgroundVersion = data.version\n\t\t\tthis.updateGlobalStyles()\n\t\t\tthis.$emit('update:background')\n\t\t},\n\t\tupdateGlobalStyles() {\n\t\t\t// Override primary-invert-if-bright and color-primary-text if background is set\n\t\t\tconst isBackgroundBright = shippedBackgroundList[this.background]?.theming === 'dark'\n\t\t\tif (isBackgroundBright) {\n\t\t\t\tdocument.querySelector('#header').style.setProperty('--primary-invert-if-bright', 'invert(100%)')\n\t\t\t\tdocument.querySelector('#header').style.setProperty('--color-primary-text', '#000000')\n\t\t\t\t// document.body.removeAttribute('data-theme-dark')\n\t\t\t\t// document.body.setAttribute('data-theme-light', 'true')\n\t\t\t} else {\n\t\t\t\tdocument.querySelector('#header').style.setProperty('--primary-invert-if-bright', 'no')\n\t\t\t\tdocument.querySelector('#header').style.setProperty('--color-primary-text', '#ffffff')\n\t\t\t\t// document.body.removeAttribute('data-theme-light')\n\t\t\t\t// document.body.setAttribute('data-theme-dark', 'true')\n\t\t\t}\n\t\t},\n\t\tchangeTheme({ enabled, id }) {\n\t\t\t// Reset selected and select new one\n\t\t\tthis.themes.forEach(theme => {\n\t\t\t\tif (theme.id === id && enabled) {\n\t\t\t\t\ttheme.enabled = true\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\ttheme.enabled = false\n\t\t\t})\n\n\t\t\tthis.updateBodyAttributes()\n\t\t\tthis.selectItem(enabled, id)\n\t\t},\n\t\tchangeFont({ enabled, id }) {\n\t\t\t// Reset selected and select new one\n\t\t\tthis.fonts.forEach(font => {\n\t\t\t\tif (font.id === id && enabled) {\n\t\t\t\t\tfont.enabled = true\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tfont.enabled = false\n\t\t\t})\n\n\t\t\tthis.updateBodyAttributes()\n\t\t\tthis.selectItem(enabled, id)\n\t\t},\n\n\t\tasync changeShortcutsDisabled(newState) {\n\t\t\tif (newState) {\n\t\t\t\tawait axios({\n\t\t\t\t\turl: generateOcsUrl('apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', {\n\t\t\t\t\t\tappId: 'theming',\n\t\t\t\t\t\tconfigKey: 'shortcuts_disabled',\n\t\t\t\t\t}),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tconfigValue: 'yes',\n\t\t\t\t\t},\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tawait axios({\n\t\t\t\t\turl: generateOcsUrl('apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', {\n\t\t\t\t\t\tappId: 'theming',\n\t\t\t\t\t\tconfigKey: 'shortcuts_disabled',\n\t\t\t\t\t}),\n\t\t\t\t\tmethod: 'DELETE',\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\n\t\tupdateBodyAttributes() {\n\t\t\tconst enabledThemesIDs = this.themes.filter(theme => theme.enabled === true).map(theme => theme.id)\n\t\t\tconst enabledFontsIDs = this.fonts.filter(font => font.enabled === true).map(font => font.id)\n\n\t\t\tthis.themes.forEach(theme => {\n\t\t\t\tdocument.body.toggleAttribute(`data-theme-${theme.id}`, theme.enabled)\n\t\t\t})\n\t\t\tthis.fonts.forEach(font => {\n\t\t\t\tdocument.body.toggleAttribute(`data-theme-${font.id}`, font.enabled)\n\t\t\t})\n\n\t\t\tdocument.body.setAttribute('data-themes', [...enabledThemesIDs, ...enabledFontsIDs].join(','))\n\t\t},\n\n\t\t/**\n\t\t * Commit a change and force reload css\n\t\t * Fetching the file again will trigger the server update\n\t\t *\n\t\t * @param {boolean} enabled the theme state\n\t\t * @param {string} themeId the theme ID to change\n\t\t */\n\t\tasync selectItem(enabled, themeId) {\n\t\t\ttry {\n\t\t\t\tif (enabled) {\n\t\t\t\t\tawait axios({\n\t\t\t\t\t\turl: generateOcsUrl('apps/theming/api/v1/theme/{themeId}/enable', { themeId }),\n\t\t\t\t\t\tmethod: 'PUT',\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tawait axios({\n\t\t\t\t\t\turl: generateOcsUrl('apps/theming/api/v1/theme/{themeId}', { themeId }),\n\t\t\t\t\t\tmethod: 'DELETE',\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(err, err.response)\n\t\t\t\tOC.Notification.showTemporary(t('theming', err.response.data.ocs.meta.message + '. Unable to apply the setting.'))\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.theming {\n\t// Limit width of settings sections for readability\n\tp {\n\t\tmax-width: 800px;\n\t}\n\n\t// Proper highlight for links and focus feedback\n\t&::v-deep a {\n\t\tfont-weight: bold;\n\n\t\t&:hover,\n\t\t&:focus {\n\t\t\ttext-decoration: underline;\n\t\t}\n\t}\n\n\t&__preview-list {\n\t\t--gap: 30px;\n\n\t\tdisplay: grid;\n\t\tmargin-top: var(--gap);\n\t\tcolumn-gap: var(--gap);\n\t\trow-gap: var(--gap);\n\t\tgrid-template-columns: 1fr 1fr;\n\t}\n}\n\n.background {\n\t&__grid {\n\t\tmargin-top: 30px;\n\t}\n}\n\n@media (max-width: 1440px) {\n\t.theming__preview-list {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t}\n}\n</style>\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./UserThemes.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./UserThemes.vue?vue&type=script&lang=js&\"","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/sass-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./UserThemes.vue?vue&type=style&index=0&id=a788b9b8&lang=scss&scoped=true&\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/sass-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./UserThemes.vue?vue&type=style&index=0&id=a788b9b8&lang=scss&scoped=true&\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./UserThemes.vue?vue&type=template&id=a788b9b8&scoped=true&\"\nimport script from \"./UserThemes.vue?vue&type=script&lang=js&\"\nexport * from \"./UserThemes.vue?vue&type=script&lang=js&\"\nimport style0 from \"./UserThemes.vue?vue&type=style&index=0&id=a788b9b8&lang=scss&scoped=true&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"a788b9b8\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('section',[_c('NcSettingsSection',{staticClass:\"theming\",attrs:{\"title\":_vm.t('theming', 'Appearance and accessibility'),\"limit-width\":false}},[_c('p',{domProps:{\"innerHTML\":_vm._s(_vm.description)}}),_vm._v(\" \"),_c('p',{domProps:{\"innerHTML\":_vm._s(_vm.descriptionDetail)}}),_vm._v(\" \"),_c('div',{staticClass:\"theming__preview-list\"},_vm._l((_vm.themes),function(theme){return _c('ItemPreview',{key:theme.id,attrs:{\"enforced\":theme.id === _vm.enforceTheme,\"selected\":_vm.selectedTheme.id === theme.id,\"theme\":theme,\"unique\":_vm.themes.length === 1,\"type\":\"theme\"},on:{\"change\":_vm.changeTheme}})}),1),_vm._v(\" \"),_c('div',{staticClass:\"theming__preview-list\"},_vm._l((_vm.fonts),function(theme){return _c('ItemPreview',{key:theme.id,attrs:{\"selected\":theme.enabled,\"theme\":theme,\"unique\":_vm.fonts.length === 1,\"type\":\"font\"},on:{\"change\":_vm.changeFont}})}),1)]),_vm._v(\" \"),_c('NcSettingsSection',{attrs:{\"title\":_vm.t('theming', 'Keyboard shortcuts')}},[_c('p',[_vm._v(_vm._s(_vm.t('theming', 'In some cases keyboard shortcuts can interfer with accessibility tools. In order to allow focusing on your tool correctly you can disable all keyboard shortcuts here. This will also disable all available shortcuts in apps.')))]),_vm._v(\" \"),_c('NcCheckboxRadioSwitch',{staticClass:\"theming__preview-toggle\",attrs:{\"checked\":_vm.shortcutsDisabled,\"name\":\"shortcuts_disabled\",\"type\":\"switch\"},on:{\"update:checked\":function($event){_vm.shortcutsDisabled=$event},\"change\":_vm.changeShortcutsDisabled}},[_vm._v(\"\\n\\t\\t\\t\"+_vm._s(_vm.t('theming', 'Disable all keyboard shortcuts'))+\"\\n\\t\\t\")])],1),_vm._v(\" \"),_c('NcSettingsSection',{staticClass:\"background\",attrs:{\"title\":_vm.t('theming', 'Background')}},[_c('p',[_vm._v(_vm._s(_vm.t('theming', 'Set a custom background')))]),_vm._v(\" \"),_c('BackgroundSettings',{staticClass:\"background__grid\",attrs:{\"background\":_vm.background,\"theming-default-background\":_vm.themingDefaultBackground},on:{\"update:background\":_vm.updateBackground}})],1)],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","/**\n * @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @author John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport Vue from 'vue'\nimport App from './UserThemes.vue'\n\n// bind to window\nVue.prototype.OC = OC\nVue.prototype.t = t\n\nconst View = Vue.extend(App)\nconst theming = new View()\ntheming.$mount('#theming')\n\ntheming.$on('update:background', () => {\n\t// Refresh server-side generated theming CSS\n\t[...document.head.querySelectorAll('link.theme')].forEach(theme => {\n\t\tconst url = new URL(theme.href)\n\t\turl.searchParams.set('v', Date.now())\n\t\tconst newTheme = theme.cloneNode()\n\t\tnewTheme.href = url.toString()\n\t\tnewTheme.onload = () => theme.remove()\n\t\tdocument.head.append(newTheme)\n\t})\n})\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".theming p[data-v-a788b9b8]{max-width:800px}.theming[data-v-a788b9b8] a{font-weight:bold}.theming[data-v-a788b9b8] a:hover,.theming[data-v-a788b9b8] a:focus{text-decoration:underline}.theming__preview-list[data-v-a788b9b8]{--gap: 30px;display:grid;margin-top:var(--gap);column-gap:var(--gap);row-gap:var(--gap);grid-template-columns:1fr 1fr}.background__grid[data-v-a788b9b8]{margin-top:30px}@media(max-width: 1440px){.theming__preview-list[data-v-a788b9b8]{display:flex;flex-direction:column}}\", \"\",{\"version\":3,\"sources\":[\"webpack://./apps/theming/src/UserThemes.vue\"],\"names\":[],\"mappings\":\"AA+RC,4BACC,eAAA,CAID,4BACC,gBAAA,CAEA,oEAEC,yBAAA,CAIF,wCACC,WAAA,CAEA,YAAA,CACA,qBAAA,CACA,qBAAA,CACA,kBAAA,CACA,6BAAA,CAKD,mCACC,eAAA,CAIF,0BACC,wCACC,YAAA,CACA,qBAAA,CAAA\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n.theming {\\n\\t// Limit width of settings sections for readability\\n\\tp {\\n\\t\\tmax-width: 800px;\\n\\t}\\n\\n\\t// Proper highlight for links and focus feedback\\n\\t&::v-deep a {\\n\\t\\tfont-weight: bold;\\n\\n\\t\\t&:hover,\\n\\t\\t&:focus {\\n\\t\\t\\ttext-decoration: underline;\\n\\t\\t}\\n\\t}\\n\\n\\t&__preview-list {\\n\\t\\t--gap: 30px;\\n\\n\\t\\tdisplay: grid;\\n\\t\\tmargin-top: var(--gap);\\n\\t\\tcolumn-gap: var(--gap);\\n\\t\\trow-gap: var(--gap);\\n\\t\\tgrid-template-columns: 1fr 1fr;\\n\\t}\\n}\\n\\n.background {\\n\\t&__grid {\\n\\t\\tmargin-top: 30px;\\n\\t}\\n}\\n\\n@media (max-width: 1440px) {\\n\\t.theming__preview-list {\\n\\t\\tdisplay: flex;\\n\\t\\tflex-direction: column;\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".background-selector[data-v-48e565ba]{display:flex;flex-wrap:wrap;justify-content:center}.background-selector .background[data-v-48e565ba]{width:176px;height:96px;margin:8px;background-size:cover;background-position:center center;text-align:center;border-radius:var(--border-radius-large);border:2px solid var(--color-main-background);overflow:hidden}.background-selector .background.current[data-v-48e565ba]{background-image:var(--color-background-dark)}.background-selector .background.filepicker[data-v-48e565ba],.background-selector .background.default[data-v-48e565ba],.background-selector .background.color[data-v-48e565ba]{border-color:var(--color-border)}.background-selector .background.color[data-v-48e565ba]{background-color:var(--color-main-background-not-plain, var(--color-primary));color:var(--color-primary-text)}.background-selector .background.active[data-v-48e565ba],.background-selector .background[data-v-48e565ba]:hover,.background-selector .background[data-v-48e565ba]:focus{border:2px solid var(--color-primary)}.background-selector .background.active[data-v-48e565ba]:not(.icon-loading):after{background-image:var(--icon-checkmark-white);background-repeat:no-repeat;background-position:center;background-size:44px;content:\\\"\\\";display:block;height:100%}\", \"\",{\"version\":3,\"sources\":[\"webpack://./apps/theming/src/components/BackgroundSettings.vue\"],\"names\":[],\"mappings\":\"AAoJA,sCACC,YAAA,CACA,cAAA,CACA,sBAAA,CAEA,kDACC,WAAA,CACA,WAAA,CACA,UAAA,CACA,qBAAA,CACA,iCAAA,CACA,iBAAA,CACA,wCAAA,CACA,6CAAA,CACA,eAAA,CAEA,0DACC,6CAAA,CAGD,+KACC,gCAAA,CAGD,wDACC,6EAAA,CACA,+BAAA,CAGD,yKAGC,qCAAA,CAGD,kFACC,4CAAA,CACA,2BAAA,CACA,0BAAA,CACA,oBAAA,CACA,UAAA,CACA,aAAA,CACA,WAAA\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n.background-selector {\\n\\tdisplay: flex;\\n\\tflex-wrap: wrap;\\n\\tjustify-content: center;\\n\\n\\t.background {\\n\\t\\twidth: 176px;\\n\\t\\theight: 96px;\\n\\t\\tmargin: 8px;\\n\\t\\tbackground-size: cover;\\n\\t\\tbackground-position: center center;\\n\\t\\ttext-align: center;\\n\\t\\tborder-radius: var(--border-radius-large);\\n\\t\\tborder: 2px solid var(--color-main-background);\\n\\t\\toverflow: hidden;\\n\\n\\t\\t&.current {\\n\\t\\t\\tbackground-image: var(--color-background-dark);\\n\\t\\t}\\n\\n\\t\\t&.filepicker, &.default, &.color {\\n\\t\\t\\tborder-color: var(--color-border);\\n\\t\\t}\\n\\n\\t\\t&.color {\\n\\t\\t\\tbackground-color: var(--color-main-background-not-plain, var(--color-primary));\\n\\t\\t\\tcolor: var(--color-primary-text);\\n\\t\\t}\\n\\n\\t\\t&.active,\\n\\t\\t&:hover,\\n\\t\\t&:focus {\\n\\t\\t\\tborder: 2px solid var(--color-primary);\\n\\t\\t}\\n\\n\\t\\t&.active:not(.icon-loading):after {\\n\\t\\t\\tbackground-image: var(--icon-checkmark-white);\\n\\t\\t\\tbackground-repeat: no-repeat;\\n\\t\\t\\tbackground-position: center;\\n\\t\\t\\tbackground-size: 44px;\\n\\t\\t\\tcontent: '';\\n\\t\\t\\tdisplay: block;\\n\\t\\t\\theight: 100%;\\n\\t\\t}\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".theming__preview[data-v-37ca8ab2]{--ratio: 16;position:relative;display:flex;justify-content:flex-start;max-width:800px}.theming__preview[data-v-37ca8ab2],.theming__preview *[data-v-37ca8ab2]{user-select:none}.theming__preview-image[data-v-37ca8ab2]{flex-basis:calc(16px*var(--ratio));flex-shrink:0;height:calc(10px*var(--ratio));margin-right:var(--gap);cursor:pointer;border-radius:var(--border-radius);background-repeat:no-repeat;background-position:top left;background-size:cover}.theming__preview-description[data-v-37ca8ab2]{display:flex;flex-direction:column}.theming__preview-description label[data-v-37ca8ab2]{padding:12px 0}.theming__preview--default[data-v-37ca8ab2]{grid-column:span 2}.theming__preview-warning[data-v-37ca8ab2]{color:var(--color-warning)}@media(max-width: 682.6666666667px){.theming__preview[data-v-37ca8ab2]{flex-direction:column}.theming__preview-image[data-v-37ca8ab2]{margin:0}}\", \"\",{\"version\":3,\"sources\":[\"webpack://./apps/theming/src/components/ItemPreview.vue\"],\"names\":[],\"mappings\":\"AAiGA,mCAEC,WAAA,CAEA,iBAAA,CACA,YAAA,CACA,0BAAA,CACA,eAAA,CAEA,wEAEC,gBAAA,CAGD,yCACC,kCAAA,CACA,aAAA,CACA,8BAAA,CACA,uBAAA,CACA,cAAA,CACA,kCAAA,CACA,2BAAA,CACA,4BAAA,CACA,qBAAA,CAGD,+CACC,YAAA,CACA,qBAAA,CAEA,qDACC,cAAA,CAIF,4CACC,kBAAA,CAGD,2CACC,0BAAA,CAIF,oCACC,mCACC,qBAAA,CAEA,yCACC,QAAA,CAAA\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n.theming__preview {\\n\\t// We make previews on 16/10 screens\\n\\t--ratio: 16;\\n\\n\\tposition: relative;\\n\\tdisplay: flex;\\n\\tjustify-content: flex-start;\\n\\tmax-width: 800px;\\n\\n\\t&,\\n\\t* {\\n\\t\\tuser-select: none;\\n\\t}\\n\\n\\t&-image {\\n\\t\\tflex-basis: calc(16px * var(--ratio));\\n\\t\\tflex-shrink: 0;\\n\\t\\theight: calc(10px * var(--ratio));\\n\\t\\tmargin-right: var(--gap);\\n\\t\\tcursor: pointer;\\n\\t\\tborder-radius: var(--border-radius);\\n\\t\\tbackground-repeat: no-repeat;\\n\\t\\tbackground-position: top left;\\n\\t\\tbackground-size: cover;\\n\\t}\\n\\n\\t&-description {\\n\\t\\tdisplay: flex;\\n\\t\\tflex-direction: column;\\n\\n\\t\\tlabel {\\n\\t\\t\\tpadding: 12px 0;\\n\\t\\t}\\n\\t}\\n\\n\\t&--default {\\n\\t\\tgrid-column: span 2;\\n\\t}\\n\\n\\t&-warning {\\n\\t\\tcolor: var(--color-warning);\\n\\t}\\n}\\n\\n@media (max-width: (1024px / 1.5)) {\\n\\t.theming__preview {\\n\\t\\tflex-direction: column;\\n\\n\\t\\t&-image {\\n\\t\\t\\tmargin: 0;\\n\\t\\t}\\n\\t}\\n}\\n\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","__webpack_require__.amdD = function () {\n\tthrow new Error('define cannot be used indirect');\n};","__webpack_require__.amdO = {};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nmd = function(module) {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","__webpack_require__.j = 6755;","__webpack_require__.b = document.baseURI || self.location.href;\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t6755: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunknextcloud\"] = self[\"webpackChunknextcloud\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","__webpack_require__.nc = undefined;","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [7874], function() { return __webpack_require__(58078); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","prefixWithBaseUrl","url","generateFilePath","getBackgroundUrl","background","time","themingDefaultBackground","enabledThemes","window","OCA","Theming","isDarkTheme","length","matchMedia","matches","join","indexOf","generateUrl","cacheBuster","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","_vm","this","_h","$createElement","_c","_self","staticClass","class","active","attrs","on","pickFile","_v","_s","t","loading","setDefault","startsWith","pickColor","_l","shippedBackground","directives","name","rawName","value","details","expression","key","style","preview","$event","setShipped","theme","id","backgroundImage","img","onToggle","title","description","_e","checked","enforced","switchType","enableLabel","console","debug","availableThemes","domProps","descriptionDetail","enforceTheme","selectedTheme","themes","changeTheme","enabled","fonts","changeFont","shortcutsDisabled","changeShortcutsDisabled","updateBackground","Vue","OC","theming","App","$mount","$on","document","head","querySelectorAll","forEach","URL","href","searchParams","set","Date","now","newTheme","cloneNode","toString","onload","remove","append","___CSS_LOADER_EXPORT___","push","module","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","loaded","__webpack_modules__","call","m","amdD","Error","amdO","O","result","chunkIds","fn","priority","notFulfilled","Infinity","i","fulfilled","j","Object","keys","every","splice","r","n","getter","__esModule","d","a","definition","o","defineProperty","enumerable","get","g","globalThis","Function","e","obj","prop","prototype","hasOwnProperty","Symbol","toStringTag","nmd","paths","children","b","baseURI","self","location","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","data","moreModules","runtime","some","chunkLoadingGlobal","bind","nc","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file
diff --git a/lib/private/Collaboration/Collaborators/MailPlugin.php b/lib/private/Collaboration/Collaborators/MailPlugin.php
index 8c2efce6f0d..d34d9fb0087 100644
--- a/lib/private/Collaboration/Collaborators/MailPlugin.php
+++ b/lib/private/Collaboration/Collaborators/MailPlugin.php
@@ -165,8 +165,8 @@ class MailPlugin implements ISearchPlugin {
if (!$this->isCurrentUser($cloud) && !$searchResult->hasResult($userType, $cloud->getUser())) {
$singleResult = [[
'label' => $displayName,
- 'uuid' => $contact['UID'],
- 'name' => $contact['FN'],
+ 'uuid' => $contact['UID'] ?? $emailAddress,
+ 'name' => $contact['FN'] ?? $displayName,
'value' => [
'shareType' => IShare::TYPE_USER,
'shareWith' => $cloud->getUser(),
@@ -205,8 +205,8 @@ class MailPlugin implements ISearchPlugin {
if ($addToWide && !$this->isCurrentUser($cloud) && !$searchResult->hasResult($userType, $cloud->getUser())) {
$userResults['wide'][] = [
'label' => $displayName,
- 'uuid' => $contact['UID'],
- 'name' => $contact['FN'],
+ 'uuid' => $contact['UID'] ?? $emailAddress,
+ 'name' => $contact['FN'] ?? $displayName,
'value' => [
'shareType' => IShare::TYPE_USER,
'shareWith' => $cloud->getUser(),
@@ -226,8 +226,8 @@ class MailPlugin implements ISearchPlugin {
}
$result['exact'][] = [
'label' => $displayName,
- 'uuid' => $contact['UID'],
- 'name' => $contact['FN'],
+ 'uuid' => $contact['UID'] ?? $emailAddress,
+ 'name' => $contact['FN'] ?? $displayName,
'type' => $emailAddressType ?? '',
'value' => [
'shareType' => IShare::TYPE_EMAIL,
@@ -237,8 +237,8 @@ class MailPlugin implements ISearchPlugin {
} else {
$result['wide'][] = [
'label' => $displayName,
- 'uuid' => $contact['UID'],
- 'name' => $contact['FN'],
+ 'uuid' => $contact['UID'] ?? $emailAddress,
+ 'name' => $contact['FN'] ?? $displayName,
'type' => $emailAddressType ?? '',
'value' => [
'shareType' => IShare::TYPE_EMAIL,
diff --git a/lib/private/Contacts/ContactsMenu/ContactsStore.php b/lib/private/Contacts/ContactsMenu/ContactsStore.php
index dd4bd973fa9..a0a14cd9cbd 100644
--- a/lib/private/Contacts/ContactsMenu/ContactsStore.php
+++ b/lib/private/Contacts/ContactsMenu/ContactsStore.php
@@ -284,8 +284,11 @@ class ContactsStore implements IContactsStore {
private function contactArrayToEntry(array $contact): Entry {
$entry = new Entry();
- if (isset($contact['id'])) {
- $entry->setId($contact['id']);
+ if (isset($contact['UID'])) {
+ $uid = $contact['UID'];
+ $entry->setId($uid);
+ $avatar = $this->urlGenerator->linkToRouteAbsolute('core.avatar.getAvatar', ['userId' => $uid, 'size' => 64]);
+ $entry->setAvatar($avatar);
}
if (isset($contact['FN'])) {
diff --git a/lib/private/Files/Cache/Propagator.php b/lib/private/Files/Cache/Propagator.php
index 2909e998bf9..4bf88a60843 100644
--- a/lib/private/Files/Cache/Propagator.php
+++ b/lib/private/Files/Cache/Propagator.php
@@ -24,16 +24,19 @@
namespace OC\Files\Cache;
+use Doctrine\DBAL\Exception\RetryableException;
use OC\Files\Storage\Wrapper\Encryption;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Cache\IPropagator;
use OCP\Files\Storage\IReliableEtagStorage;
use OCP\IDBConnection;
+use Psr\Log\LoggerInterface;
/**
* Propagate etags and mtimes within the storage
*/
class Propagator implements IPropagator {
+ public const MAX_RETRIES = 3;
private $inBatch = false;
private $batch = [];
@@ -100,35 +103,44 @@ class Propagator implements IPropagator {
$builder->set('etag', $builder->createNamedParameter($etag, IQueryBuilder::PARAM_STR));
}
- $builder->execute();
-
if ($sizeDifference !== 0) {
- // we need to do size separably so we can ignore entries with uncalculated size
- $builder = $this->connection->getQueryBuilder();
- $builder->update('filecache')
- ->set('size', $builder->func()->greatest(
- $builder->func()->add('size', $builder->createNamedParameter($sizeDifference)),
- $builder->createNamedParameter(-1, IQueryBuilder::PARAM_INT)
- ))
- ->where($builder->expr()->eq('storage', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
- ->andWhere($builder->expr()->in('path_hash', $hashParams))
- ->andWhere($builder->expr()->gt('size', $builder->expr()->literal(-1, IQueryBuilder::PARAM_INT)));
+ $hasCalculatedSize = $builder->expr()->gt('size', $builder->expr()->literal(-1, IQUeryBuilder::PARAM_INT));
+ $sizeColumn = $builder->getColumnName('size');
+ $newSize = $builder->func()->greatest(
+ $builder->func()->add('size', $builder->createNamedParameter($sizeDifference)),
+ $builder->createNamedParameter(-1, IQueryBuilder::PARAM_INT)
+ );
+
+ // Only update if row had a previously calculated size
+ $builder->set('size', $builder->createFunction("CASE WHEN $hasCalculatedSize THEN $newSize ELSE $sizeColumn END"));
if ($this->storage->instanceOfStorage(Encryption::class)) {
// in case of encryption being enabled after some files are already uploaded, some entries will have an unencrypted_size of 0 and a non-zero size
- $eq = $builder->expr()->eq('unencrypted_size', $builder->expr()->literal(0, IQueryBuilder::PARAM_INT));
+ $hasUnencryptedSize = $builder->expr()->neq('unencrypted_size', $builder->expr()->literal(0, IQueryBuilder::PARAM_INT));
$sizeColumn = $builder->getColumnName('size');
$unencryptedSizeColumn = $builder->getColumnName('unencrypted_size');
- $builder->set('unencrypted_size', $builder->func()->greatest(
+ $newUnencryptedSize = $builder->func()->greatest(
$builder->func()->add(
- $builder->createFunction("CASE WHEN $eq THEN $unencryptedSizeColumn ELSE $sizeColumn END"),
+ $builder->createFunction("CASE WHEN $hasUnencryptedSize THEN $unencryptedSizeColumn ELSE $sizeColumn END"),
$builder->createNamedParameter($sizeDifference)
),
$builder->createNamedParameter(-1, IQueryBuilder::PARAM_INT)
- ));
+ );
+
+ // Only update if row had a previously calculated size
+ $builder->set('unencrypted_size', $builder->createFunction("CASE WHEN $hasCalculatedSize THEN $newUnencryptedSize ELSE $unencryptedSizeColumn END"));
}
+ }
- $builder->execute();
+ for ($i = 0; $i < self::MAX_RETRIES; $i++) {
+ try {
+ $builder->executeStatement();
+ break;
+ } catch (RetryableException $e) {
+ /** @var LoggerInterface $loggerInterface */
+ $loggerInterface = \OCP\Server::get(LoggerInterface::class);
+ $loggerInterface->warning('Retrying propagation query after retryable exception.', [ 'exception' => $e ]);
+ }
}
}
diff --git a/lib/private/Files/Storage/Local.php b/lib/private/Files/Storage/Local.php
index 2a7e30cada6..62a04292e23 100644
--- a/lib/private/Files/Storage/Local.php
+++ b/lib/private/Files/Storage/Local.php
@@ -166,6 +166,9 @@ class Local extends \OC\Files\Storage\Common {
public function stat($path) {
$fullPath = $this->getSourcePath($path);
clearstatcache(true, $fullPath);
+ if (!file_exists($fullPath)) {
+ return false;
+ }
$statResult = @stat($fullPath);
if (PHP_INT_SIZE === 4 && $statResult && !$this->is_dir($path)) {
$filesize = $this->filesize($path);
@@ -388,11 +391,15 @@ class Local extends \OC\Files\Storage\Common {
}
public function fopen($path, $mode) {
+ $sourcePath = $this->getSourcePath($path);
+ if (!file_exists($sourcePath) && $mode === 'r') {
+ return false;
+ }
$oldMask = umask($this->defUMask);
if (($mode === 'w' || $mode === 'w+') && $this->unlinkOnTruncate) {
$this->unlink($path);
}
- $result = fopen($this->getSourcePath($path), $mode);
+ $result = @fopen($sourcePath, $mode);
umask($oldMask);
return $result;
}
diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php
index e5394e72ffe..c78517d09ef 100644
--- a/lib/private/Files/View.php
+++ b/lib/private/Files/View.php
@@ -1001,7 +1001,17 @@ class View {
$this->logger->info('Trying to open a file with a mode other than "r" or "w" can cause severe performance issues with some backends', ['app' => 'core']);
}
- return $this->basicOperation('fopen', $path, $hooks, $mode);
+ $handle = $this->basicOperation('fopen', $path, $hooks, $mode);
+ if (!is_resource($handle) && $mode === 'r') {
+ // trying to read a file that isn't on disk, check if the cache is out of sync and rescan if needed
+ $mount = $this->getMount($path);
+ $internalPath = $mount->getInternalPath($this->getAbsolutePath($path));
+ $storage = $mount->getStorage();
+ if ($storage->getCache()->inCache($internalPath) && !$storage->file_exists($path)) {
+ $this->writeUpdate($storage, $internalPath);
+ }
+ }
+ return $handle;
}
/**
diff --git a/lib/private/OCS/CoreCapabilities.php b/lib/private/OCS/CoreCapabilities.php
index ab06b04cc91..578152ff108 100644
--- a/lib/private/OCS/CoreCapabilities.php
+++ b/lib/private/OCS/CoreCapabilities.php
@@ -24,6 +24,7 @@ namespace OC\OCS;
use OCP\Capabilities\ICapability;
use OCP\IConfig;
+use OCP\IURLGenerator;
/**
* Class Capabilities
@@ -52,7 +53,9 @@ class CoreCapabilities implements ICapability {
'core' => [
'pollinterval' => $this->config->getSystemValue('pollinterval', 60),
'webdav-root' => $this->config->getSystemValue('webdav-root', 'remote.php/webdav'),
- ]
+ 'reference-api' => true,
+ 'reference-regex' => IURLGenerator::URL_REGEX_NO_MODIFIERS,
+ ],
];
}
}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index e7f4019e00b..a94e0d568b0 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -1222,6 +1222,7 @@ class Server extends ServerContainer implements IServerContainer {
return new ThemingDefaults(
$c->get(\OCP\IConfig::class),
$c->getL10N('theming'),
+ $c->get(IUserSession::class),
$c->get(IURLGenerator::class),
$c->get(ICacheFactory::class),
new Util($c->get(\OCP\IConfig::class), $this->get(IAppManager::class), $c->getAppDataDir('theming')),
diff --git a/lib/public/Collaboration/Reference/IReference.php b/lib/public/Collaboration/Reference/IReference.php
index 0155ae86dd8..31608b52cc5 100644
--- a/lib/public/Collaboration/Reference/IReference.php
+++ b/lib/public/Collaboration/Reference/IReference.php
@@ -98,7 +98,7 @@ interface IReference extends JsonSerializable {
/**
* @since 25.0.0
*/
- public function getUrl(): ?string;
+ public function getUrl(): string;
/**
* Set the reference specific rich object representation
diff --git a/lib/public/Collaboration/Reference/Reference.php b/lib/public/Collaboration/Reference/Reference.php
index 07da3399a1e..6b92a0fae52 100644
--- a/lib/public/Collaboration/Reference/Reference.php
+++ b/lib/public/Collaboration/Reference/Reference.php
@@ -149,8 +149,8 @@ class Reference implements IReference {
* @inheritdoc
* @since 25.0.0
*/
- public function getUrl(): ?string {
- return $this->url;
+ public function getUrl(): string {
+ return $this->url ?? $this->reference;
}
/**
diff --git a/lib/public/IURLGenerator.php b/lib/public/IURLGenerator.php
index be0edf61025..b6d78876478 100644
--- a/lib/public/IURLGenerator.php
+++ b/lib/public/IURLGenerator.php
@@ -43,7 +43,16 @@ interface IURLGenerator {
*
* @since 25.0.0
*/
- public const URL_REGEX = '/(\s|\n|^)(https?:\/\/)((?:[-A-Z0-9+_]+\.)+[-A-Z]+(?:\/[-A-Z0-9+&@#%?=~_|!:,.;()]*)*)(\s|\n|$)/mi';
+ public const URL_REGEX = '/' . self::URL_REGEX_NO_MODIFIERS . '/mi';
+
+ /**
+ * Regex for matching http(s) urls (without modifiers for client compatibility)
+ *
+ * This is a copy of the frontend regex in core/src/OCP/comments.js, make sure to adjust both when changing
+ *
+ * @since 25.0.0
+ */
+ public const URL_REGEX_NO_MODIFIERS = '(\s|\n|^)(https?:\/\/)((?:[-A-Z0-9+_]+\.)+[-A-Z]+(?:\/[-A-Z0-9+&@#%?=~_|!:,.;()]*)*)(\s|\n|$)';
/**
* Returns the URL for a route
diff --git a/ocs/v1.php b/ocs/v1.php
index 9f6a05ac42f..3fba48b13c8 100644
--- a/ocs/v1.php
+++ b/ocs/v1.php
@@ -35,6 +35,7 @@ if (\OCP\Util::needUpgrade()
// since the behavior of apps or remotes are unpredictable during
// an upgrade, return a 503 directly
http_response_code(503);
+ header('X-Nextcloud-Maintenance-Mode: 1');
$response = new \OC\OCS\Result(null, 503, 'Service unavailable');
OC_API::respond($response, OC_API::requestedFormat());
exit;
diff --git a/tests/acceptance/features/app-theming.feature b/tests/acceptance/features/app-theming.feature
index 1da12679d04..6f11a61455f 100644
--- a/tests/acceptance/features/app-theming.feature
+++ b/tests/acceptance/features/app-theming.feature
@@ -9,10 +9,12 @@ Feature: app-theming
# The "eventually" part is not really needed here, as the colour is not
# being animated at this point, but there is no need to create a specific
# step just for this.
- And I see that the primary color is eventually "#0082C9"
+ And I see that the primary color is eventually "#00639a"
+ And I see that the non-plain background color variable is eventually "#0082c9"
When I set the "Color" parameter in the Theming app to "#C9C9C9"
Then I see that the parameters in the Theming app are eventually saved
And I see that the primary color is eventually "#C9C9C9"
+ And I see that the non-plain background color variable is eventually "#C9C9C9"
Scenario: resetting the color updates the primary color
Given I am logged in as the admin
@@ -22,6 +24,8 @@ Feature: app-theming
And I set the "Color" parameter in the Theming app to "#C9C9C9"
And I see that the parameters in the Theming app are eventually saved
And I see that the primary color is eventually "#C9C9C9"
+ And I see that the non-plain background color variable is eventually "#C9C9C9"
When I reset the "Color" parameter in the Theming app to its default value
Then I see that the parameters in the Theming app are eventually saved
- And I see that the primary color is eventually "#0082C9"
+ And I see that the primary color is eventually "#00639a"
+ And I see that the non-plain background color variable is eventually "#0082c9"
diff --git a/tests/acceptance/features/bootstrap/ThemingAppContext.php b/tests/acceptance/features/bootstrap/ThemingAppContext.php
index de5da5950d2..adf04eaca00 100644
--- a/tests/acceptance/features/bootstrap/ThemingAppContext.php
+++ b/tests/acceptance/features/bootstrap/ThemingAppContext.php
@@ -142,6 +142,23 @@ class ThemingAppContext implements Context, ActorAwareInterface {
}
/**
+ * @Then I see that the non-plain background color variable is eventually :color
+ */
+ public function iSeeThatTheNonPlainBackgroundColorVariableIsEventually($color) {
+ $colorVariableMatchesCallback = function () use ($color) {
+ $colorVariable = $this->actor->getSession()->evaluateScript("return getComputedStyle(document.documentElement).getPropertyValue('--color-main-background-not-plain').trim();");
+ $colorVariable = $this->getRGBArray($colorVariable);
+ $color = $this->getRGBArray($color);
+
+ return $colorVariable == $color;
+ };
+
+ if (!Utils::waitFor($colorVariableMatchesCallback, $timeout = 10 * $this->actor->getFindTimeoutMultiplier(), $timeoutStep = 1)) {
+ Assert::fail("The non-plain background color variable is not $color yet after $timeout seconds");
+ }
+ }
+
+ /**
* @Then I see that the parameters in the Theming app are eventually saved
*/
public function iSeeThatTheParametersInTheThemingAppAreEventuallySaved() {
diff --git a/tests/lib/Contacts/ContactsMenu/ContactsStoreTest.php b/tests/lib/Contacts/ContactsMenu/ContactsStoreTest.php
index aa609aedbb9..dfdd67fbb23 100644
--- a/tests/lib/Contacts/ContactsMenu/ContactsStoreTest.php
+++ b/tests/lib/Contacts/ContactsMenu/ContactsStoreTest.php
@@ -140,6 +140,10 @@ class ContactsStoreTest extends TestCase {
public function testGetContactsWithoutBinaryImage() {
/** @var IUser|MockObject $user */
$user = $this->createMock(IUser::class);
+ $this->urlGenerator->expects($this->any())
+ ->method('linkToRouteAbsolute')
+ ->with('core.avatar.getAvatar', $this->anything())
+ ->willReturn('https://urlToNcAvatar.test');
$this->contactsManager->expects($this->once())
->method('search')
->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
@@ -163,7 +167,7 @@ class ContactsStoreTest extends TestCase {
$entries = $this->contactsStore->getContacts($user, '');
$this->assertCount(2, $entries);
- $this->assertNull($entries[1]->getAvatar());
+ $this->assertSame('https://urlToNcAvatar.test', $entries[1]->getAvatar());
}
public function testGetContactsWithoutAvatarURI() {
diff --git a/tests/lib/Files/ViewTest.php b/tests/lib/Files/ViewTest.php
index 86101d79a1e..2189e7c09f4 100644
--- a/tests/lib/Files/ViewTest.php
+++ b/tests/lib/Files/ViewTest.php
@@ -2709,4 +2709,23 @@ class ViewTest extends \Test\TestCase {
$this->assertEquals(25, $info->getUploadTime());
$this->assertEquals(0, $info->getCreationTime());
}
+
+ public function testFopenGone() {
+ $storage = new Temporary([]);
+ $scanner = $storage->getScanner();
+ $storage->file_put_contents('foo.txt', 'bar');
+ $scanner->scan('');
+ $cache = $storage->getCache();
+
+ Filesystem::mount($storage, [], '/test/');
+ $view = new View('/test');
+
+ $storage->unlink('foo.txt');
+
+ $this->assertTrue($cache->inCache('foo.txt'));
+
+ $this->assertFalse($view->fopen('foo.txt', 'r'));
+
+ $this->assertFalse($cache->inCache('foo.txt'));
+ }
}