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" > - +
+ => { 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`] = ` -