diff --git a/changelog/unreleased/enhancement-darkmode-themeswitcher b/changelog/unreleased/enhancement-darkmode-themeswitcher
new file mode 100644
index 00000000000..da1ef24b6b2
--- /dev/null
+++ b/changelog/unreleased/enhancement-darkmode-themeswitcher
@@ -0,0 +1,5 @@
+Enhancement: Darkmode theme switcher
+
+We've added a theme switcher and now initialize the user interface theme based on the user's browser preferences.
+
+https://github.com/owncloud/web/pull/6240
diff --git a/packages/web-app-files/src/views/FilesDrop.vue b/packages/web-app-files/src/views/FilesDrop.vue
index a19e28c218b..a3ca7f85cfc 100644
--- a/packages/web-app-files/src/views/FilesDrop.vue
+++ b/packages/web-app-files/src/views/FilesDrop.vue
@@ -68,7 +68,7 @@
diff --git a/packages/web-app-files/src/views/LocationPicker.vue b/packages/web-app-files/src/views/LocationPicker.vue
index b00a7ad6163..99b1171c05e 100644
--- a/packages/web-app-files/src/views/LocationPicker.vue
+++ b/packages/web-app-files/src/views/LocationPicker.vue
@@ -104,7 +104,7 @@ import { createLocationPublic, createLocationSpaces } from '../router'
export default {
metaInfo() {
- const title = `${this.title} - ${this.configuration.theme.general.name}`
+ const title = `${this.title} - ${this.configuration.currentTheme.general.name}`
return { title }
},
diff --git a/packages/web-app-files/src/views/PrivateLink.vue b/packages/web-app-files/src/views/PrivateLink.vue
index f9bea21c71a..46b83cd2261 100644
--- a/packages/web-app-files/src/views/PrivateLink.vue
+++ b/packages/web-app-files/src/views/PrivateLink.vue
@@ -41,11 +41,11 @@ export default {
},
backgroundImg() {
- return this.configuration.theme.loginPage.backgroundImg
+ return this.configuration.currentTheme.loginPage.backgroundImg
},
logoImg() {
- return this.configuration.theme.logo.login
+ return this.configuration.currentTheme.logo.login
}
},
mounted() {
diff --git a/packages/web-app-files/src/views/PublicLink.vue b/packages/web-app-files/src/views/PublicLink.vue
index ae1f935c9b2..fe1aed6cc21 100644
--- a/packages/web-app-files/src/views/PublicLink.vue
+++ b/packages/web-app-files/src/views/PublicLink.vue
@@ -45,7 +45,7 @@
@@ -83,11 +83,11 @@ export default {
},
backgroundImg() {
- return this.configuration.theme.loginPage.backgroundImg
+ return this.configuration.currentTheme.loginPage.backgroundImg
},
logoImg() {
- return this.configuration.theme.logo.login
+ return this.configuration.currentTheme.logo.login
}
},
mounted() {
diff --git a/packages/web-app-files/tests/unit/views/views.setup.js b/packages/web-app-files/tests/unit/views/views.setup.js
index cab642dca91..bb2d2a4442f 100644
--- a/packages/web-app-files/tests/unit/views/views.setup.js
+++ b/packages/web-app-files/tests/unit/views/views.setup.js
@@ -68,7 +68,7 @@ export const getStore = function ({
},
getters: {
configuration: () => ({
- theme: {
+ currentTheme: {
loginPage: {
backgroundImg: loginBackgroundImg
},
diff --git a/packages/web-runtime/src/App.vue b/packages/web-runtime/src/App.vue
index 3656b43aa39..ccfbf5103b2 100644
--- a/packages/web-runtime/src/App.vue
+++ b/packages/web-runtime/src/App.vue
@@ -8,7 +8,7 @@
v-if="user.isAuthenticated && !user.userReady"
class="loading-overlay oc-flex oc-flex-middle oc-flex-center"
:style="{
- backgroundImage: 'url(' + configuration.theme.loginPage.backgroundImg + ')'
+ backgroundImage: 'url(' + configuration.currentTheme.loginPage.backgroundImg + ')'
}"
>
@@ -125,7 +125,7 @@ export default {
},
favicon() {
- return this.configuration.theme.logo.favicon
+ return this.configuration.currentTheme.logo.favicon
},
sidebarNavItems() {
@@ -280,7 +280,7 @@ export default {
const titleSegments = [routeTitle]
if (includeGeneralName) {
- titleSegments.push(this.configuration.theme.general.name)
+ titleSegments.push(this.configuration.currentTheme.general.name)
}
if (route.params.item) {
@@ -306,7 +306,7 @@ body {
}
#web {
- background-color: #202020;
+ background-color: var(--oc-color-swatch-brand-default);
height: 100vh;
max-height: 100vh;
overflow-y: hidden;
diff --git a/packages/web-runtime/src/components/FeedbackLink.vue b/packages/web-runtime/src/components/FeedbackLink.vue
index 175a7cf6688..ca30b7e5df2 100644
--- a/packages/web-runtime/src/components/FeedbackLink.vue
+++ b/packages/web-runtime/src/components/FeedbackLink.vue
@@ -6,10 +6,11 @@
:href="href"
target="_blank"
appearance="raw"
+ variation="inverse"
:aria-label="ariaLabel"
aria-describedby="oc-feedback-link-description"
>
-
+
diff --git a/packages/web-runtime/src/components/SidebarNav/SidebarNav.vue b/packages/web-runtime/src/components/SidebarNav/SidebarNav.vue
index 9e701f9b3ed..9d6b0f39c62 100644
--- a/packages/web-runtime/src/components/SidebarNav/SidebarNav.vue
+++ b/packages/web-runtime/src/components/SidebarNav/SidebarNav.vue
@@ -4,7 +4,6 @@
:class="['oc-visible@l', { 'oc-app-navigation-collapsed': navigation.closed }]"
>
diff --git a/packages/web-runtime/src/components/TopBar.vue b/packages/web-runtime/src/components/TopBar.vue
index 348cd2b014f..d90d697270d 100644
--- a/packages/web-runtime/src/components/TopBar.vue
+++ b/packages/web-runtime/src/components/TopBar.vue
@@ -14,6 +14,7 @@
+
=> {
const { theme } = await loadTheme(runtimeConfiguration?.theme)
+ await store.dispatch('loadThemes', { theme })
await store.dispatch('loadTheme', { theme: theme.default })
vue.use(designSystem, {
diff --git a/packages/web-runtime/src/helpers/theme.js b/packages/web-runtime/src/helpers/theme.js
index 20bc0bde52e..b459bbff57e 100644
--- a/packages/web-runtime/src/helpers/theme.js
+++ b/packages/web-runtime/src/helpers/theme.js
@@ -17,6 +17,7 @@ export const loadTheme = async (location = '') => {
return defaults
}
const theme = await response.json()
+ console.log('theme', theme)
return { theme }
} catch (e) {
console.error(
diff --git a/packages/web-runtime/src/pages/accessDenied.vue b/packages/web-runtime/src/pages/accessDenied.vue
index c3fa50293e1..1c839b6d631 100644
--- a/packages/web-runtime/src/pages/accessDenied.vue
+++ b/packages/web-runtime/src/pages/accessDenied.vue
@@ -39,38 +39,38 @@ export default {
},
helpDeskText() {
if (
- this.configuration.theme.general.helpDeskText &&
- this.configuration.theme.general.helpDeskText.en
+ this.configuration.currentTheme.general.helpDeskText &&
+ this.configuration.currentTheme.general.helpDeskText.en
) {
const lang = this.$language.current
- if (this.configuration.theme.general.helpDeskText[lang]) {
- return this.configuration.theme.general.helpDeskText[lang]
+ if (this.configuration.currentTheme.general.helpDeskText[lang]) {
+ return this.configuration.currentTheme.general.helpDeskText[lang]
}
- return this.configuration.theme.general.helpDeskText.en
+ return this.configuration.currentTheme.general.helpDeskText.en
}
return this.$gettext(
'Please contact your administrator if you think this message shows up in error.'
)
},
helpDeskLink() {
- if (this.configuration.theme.general.helpDeskLink) {
- return this.configuration.theme.general.helpDeskLink
+ if (this.configuration.currentTheme.general.helpDeskLink) {
+ return this.configuration.currentTheme.general.helpDeskLink
}
return ''
},
helpDeskLinkText() {
- if (this.configuration.theme.general.helpDeskLinkText) {
- return this.configuration.theme.general.helpDeskLinkText
+ if (this.configuration.currentTheme.general.helpDeskLinkText) {
+ return this.configuration.currentTheme.general.helpDeskLinkText
}
return ''
},
logoImg() {
- return this.configuration.theme.logo.login
+ return this.configuration.currentTheme.logo.login
},
backgroundImg() {
- return this.configuration.theme.loginPage.backgroundImg
+ return this.configuration.currentTheme.loginPage.backgroundImg
}
},
methods: {
diff --git a/packages/web-runtime/src/pages/login.vue b/packages/web-runtime/src/pages/login.vue
index d6bbe4e7927..078df0783c5 100644
--- a/packages/web-runtime/src/pages/login.vue
+++ b/packages/web-runtime/src/pages/login.vue
@@ -29,7 +29,7 @@
@@ -54,20 +54,20 @@ export default {
},
$_productName() {
- return this.configuration.theme.general.name
+ return this.configuration.currentTheme.general.name
},
logoImg() {
- return this.configuration.theme.logo.login
+ return this.configuration.currentTheme.logo.login
},
backgroundImg() {
- return this.configuration.theme.loginPage.backgroundImg
+ return this.configuration.currentTheme.loginPage.backgroundImg
}
},
created() {
- if (this.configuration.theme.loginPage.autoRedirect) {
+ if (this.configuration.currentTheme.loginPage.autoRedirect) {
this.login()
} else {
this.initialized = true
diff --git a/packages/web-runtime/src/pages/missingOrInvalidConfig.vue b/packages/web-runtime/src/pages/missingOrInvalidConfig.vue
index 1aa013f999d..8cdc13bf685 100644
--- a/packages/web-runtime/src/pages/missingOrInvalidConfig.vue
+++ b/packages/web-runtime/src/pages/missingOrInvalidConfig.vue
@@ -32,15 +32,15 @@ export default {
...mapGetters(['configuration']),
backgroundImg() {
- return this.configuration.theme.loginPage.backgroundImg
+ return this.configuration.currentTheme.loginPage.backgroundImg
},
logoImg() {
- return this.configuration.theme.logo.login
+ return this.configuration.currentTheme.logo.login
},
favicon() {
- return this.configuration.theme.logo.favicon
+ return this.configuration.currentTheme.logo.favicon
}
},
diff --git a/packages/web-runtime/src/pages/oidcCallback.vue b/packages/web-runtime/src/pages/oidcCallback.vue
index 99b75ab1f61..43345430192 100644
--- a/packages/web-runtime/src/pages/oidcCallback.vue
+++ b/packages/web-runtime/src/pages/oidcCallback.vue
@@ -15,7 +15,7 @@
Please wait, you are being redirected.
@@ -39,11 +39,11 @@ export default {
},
backgroundImg() {
- return this.configuration.theme.loginPage.backgroundImg
+ return this.configuration.currentTheme.loginPage.backgroundImg
},
logoImg() {
- return this.configuration.theme.logo.login
+ return this.configuration.currentTheme.logo.login
}
},
diff --git a/packages/web-runtime/src/store/config.js b/packages/web-runtime/src/store/config.js
index e2a74b8d34f..72e2044ffe0 100644
--- a/packages/web-runtime/src/store/config.js
+++ b/packages/web-runtime/src/store/config.js
@@ -1,5 +1,4 @@
import isEmpty from 'lodash-es/isEmpty'
-import merge from 'lodash-es/merge'
const state = {
state: null,
@@ -15,7 +14,8 @@ const state = {
openIdConnect: {
authority: ''
},
- theme: {
+ themes: [],
+ currentTheme: {
general: {
name: '',
slogan: '',
@@ -32,6 +32,9 @@ const state = {
loginPage: {
autoRedirect: true,
backgroundImg: ''
+ },
+ designTokens: {
+ colorPalette: {}
}
},
options: {
@@ -62,6 +65,9 @@ const actions = {
},
loadTheme(context, { theme }) {
context.commit('LOAD_THEME', theme)
+ },
+ loadThemes(context, { theme }) {
+ context.commit('LOAD_THEMES', theme)
}
}
@@ -82,7 +88,10 @@ const mutations = {
}
},
LOAD_THEME(state, theme) {
- state.theme = merge({}, state.theme, theme)
+ state.currentTheme = theme
+ },
+ LOAD_THEMES(state, theme) {
+ state.themes = theme
}
}
@@ -109,7 +118,7 @@ const getters = {
return parsed
},
theme: (state) => {
- return state.theme
+ return state.currentTheme
}
}
diff --git a/packages/web-runtime/tests/unit/components/SidebarNav/__snapshots__/SidebarNav.spec.js.snap b/packages/web-runtime/tests/unit/components/SidebarNav/__snapshots__/SidebarNav.spec.js.snap
index 33679e8992c..4e96ba1353f 100644
--- a/packages/web-runtime/tests/unit/components/SidebarNav/__snapshots__/SidebarNav.spec.js.snap
+++ b/packages/web-runtime/tests/unit/components/SidebarNav/__snapshots__/SidebarNav.spec.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`OcSidebarNav renders navItems into a list 1`] = `
-