Skip to content

Commit

Permalink
WIP: Initial theme switching concept
Browse files Browse the repository at this point in the history
  • Loading branch information
pascalwengerter committed Jan 13, 2022
1 parent 594afda commit c30d211
Show file tree
Hide file tree
Showing 25 changed files with 270 additions and 61 deletions.
5 changes: 5 additions & 0 deletions changelog/unreleased/enhancement-darkmode-themeswitcher
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion packages/web-app-files/src/views/FilesDrop.vue
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
</div>
</div>
<div class="oc-text-center">
<p v-text="configuration.theme.general.slogan" />
<p v-text="configuration.currentTheme.general.slogan" />
</div>
</div>
</template>
Expand Down
2 changes: 1 addition & 1 deletion packages/web-app-files/src/views/LocationPicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
},
Expand Down
4 changes: 2 additions & 2 deletions packages/web-app-files/src/views/PrivateLink.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
6 changes: 3 additions & 3 deletions packages/web-app-files/src/views/PublicLink.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
</div>
<div class="oc-login-card-footer">
<p>
{{ configuration.theme.general.slogan }}
{{ configuration.currentTheme.general.slogan }}
</p>
</div>
</div>
Expand Down Expand Up @@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion packages/web-app-files/tests/unit/views/views.setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const getStore = function ({
},
getters: {
configuration: () => ({
theme: {
currentTheme: {
loginPage: {
backgroundImg: loginBackgroundImg
},
Expand Down
8 changes: 4 additions & 4 deletions packages/web-runtime/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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 + ')'
}"
>
<oc-spinner size="xlarge" :aria-label="$gettext('Loading')" />
Expand Down Expand Up @@ -125,7 +125,7 @@ export default {
},
favicon() {
return this.configuration.theme.logo.favicon
return this.configuration.currentTheme.logo.favicon
},
sidebarNavItems() {
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion packages/web-runtime/src/components/FeedbackLink.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
:href="href"
target="_blank"
appearance="raw"
variation="inverse"
:aria-label="ariaLabel"
aria-describedby="oc-feedback-link-description"
>
<oc-icon name="feedback" variation="inverse" />
<oc-icon name="feedback" />
</oc-button>
<p id="oc-feedback-link-description" class="oc-invisible-sr" v-text="description" />
</div>
Expand Down
6 changes: 2 additions & 4 deletions packages/web-runtime/src/components/SidebarNav/SidebarNav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
:class="['oc-visible@l', { 'oc-app-navigation-collapsed': navigation.closed }]"
>
<oc-button
variation="inverse"
appearance="raw"
:class="toggleSidebarButtonClass"
class="toggle-sidebar-button oc-py-s"
Expand Down Expand Up @@ -74,10 +73,9 @@ export default {

<style lang="scss">
#web-nav-sidebar {
background-color: #2d2d2d;
background-color: var(--oc-color-background-default);
border-top-left-radius: 15px;
border-bottom-left-radius: 15px;
color: var(--oc-color-text-inverse);
display: flex;
flex-direction: column;
position: sticky;
Expand All @@ -89,7 +87,7 @@ export default {
transition: all 0.2s ease-out;
&:hover {
border-top-left-radius: 15px;
background: #383838;
background: var(--oc-color-swatch-brand-hover);
}
}
.toggle-sidebar-button-expanded {
Expand Down
25 changes: 16 additions & 9 deletions packages/web-runtime/src/components/SidebarNav/SidebarNavItem.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
<template>
<li class="oc-sidebar-nav-item oc-pb-xs oc-px-s" :aria-current="active ? 'page' : null">
<router-link
<oc-button
v-oc-tooltip="toolTip"
:class="['oc-sidebar-nav-item-link', { active: active }]"
type="router-link"
:appearance="itemAppearance"
class="oc-sidebar-nav-item-link"
:to="target"
>
<oc-icon :name="icon" :fill-type="fillType" variation="inverse" aria-hidden="true" />
<oc-icon :name="icon" :fill-type="fillType" aria-hidden="true" />
<span class="oc-ml-m text" :class="{ 'text-invisible': collapsed }" v-text="name" />
</router-link>
</oc-button>
</li>
</template>
<script>
Expand Down Expand Up @@ -45,21 +47,26 @@ export default {
computed: {
toolTip() {
return this.collapsed ? this.$gettext(`Navigate to ${this.name} page`) : ''
},
itemAppearance() {
return this.active ? 'filled' : 'raw'
}
}
}
</script>

<style lang="scss">
.oc-sidebar-nav-item-link {
align-items: center;
color: var(--oc-color-border);
display: flex;
align-items: center !important;
display: flex !important;
font-weight: 400;
padding: var(--oc-space-small) var(--oc-space-small);
padding: var(--oc-space-small) var(--oc-space-small) !important;
justify-content: normal !important;
border-radius: 5px;
white-space: nowrap;
user-select: none;
gap: 0;
text-align: left !important;
.text {
opacity: 1;
Expand All @@ -71,7 +78,7 @@ export default {
}
&.active {
background: linear-gradient(90deg, #0869de 0%, #4e85c8 100%);
// background: linear-gradient(90deg, #0869de 0%, #4e85c8 100%);
cursor: default;
}
&:hover {
Expand Down
57 changes: 57 additions & 0 deletions packages/web-runtime/src/components/ThemeSwitcher.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<template>
<oc-button appearance="raw" variation="inverse" @click="changeTheme">
<span v-text="switchText" />
<oc-icon :name="switchIcon" fill-type="line" />
</oc-button>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default {
data() {
return {
mode: 'light'
}
},
computed: {
...mapGetters(['configuration']),
switchIcon() {
return this.mode === 'light' ? 'sun' : 'moon-clear'
},
switchText() {
return this.mode === 'light' ? this.$gettext('Light mode') : this.$gettext('Dark mode')
}
},
mounted() {
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
this.changeTheme()
}
},
methods: {
...mapActions(['loadTheme']),
changeTheme() {
if (this.mode === 'light') {
this.loadTheme({ theme: this.configuration.themes['default-dark'] })
this.applyChangedTheme()
this.mode = 'dark'
} else {
this.loadTheme({ theme: this.configuration.themes.default })
this.applyChangedTheme()
this.mode = 'light'
}
},
applyChangedTheme() {
for (const param in this.configuration.currentTheme.designTokens.colorPalette) {
document
.querySelector(':root')
.style.setProperty(
'--oc-' + 'color-' + param,
this.configuration.currentTheme.designTokens.colorPalette[param]
)
}
}
}
}
</script>
11 changes: 9 additions & 2 deletions packages/web-runtime/src/components/TopBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<portal-target name="app.runtime.header" multiple></portal-target>
</div>
<div class="topbar-gap oc-flex oc-flex-middle oc-flex-between">
<theme-switcher v-if="darkThemeAvailable" />
<feedback-link v-if="isFeedbackLinkEnabled" />
<notifications v-if="isNotificationBellEnabled" />
<user-menu
Expand All @@ -33,12 +34,14 @@ import ApplicationsMenu from './ApplicationsMenu.vue'
import UserMenu from './UserMenu.vue'
import Notifications from './Notifications.vue'
import FeedbackLink from './FeedbackLink.vue'
import ThemeSwitcher from './ThemeSwitcher.vue'
export default {
components: {
ApplicationsMenu,
FeedbackLink,
Notifications,
ApplicationsMenu,
ThemeSwitcher,
UserMenu
},
props: {
Expand Down Expand Up @@ -66,12 +69,16 @@ export default {
computed: {
...mapGetters(['configuration', 'user']),
darkThemeAvailable() {
return this.configuration.themes.default && this.configuration.themes['default-dark']
},
sidebarLogoAlt() {
return this.$gettext('Navigate to all files page')
},
logoImage() {
return this.configuration.theme.logo.sidebar
return this.configuration.currentTheme.logo.sidebar
},
isFeedbackLinkEnabled() {
Expand Down
1 change: 1 addition & 0 deletions packages/web-runtime/src/container/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ export const announceTheme = async ({
runtimeConfiguration?: RuntimeConfiguration
}): Promise<void> => {
const { theme } = await loadTheme(runtimeConfiguration?.theme)
await store.dispatch('loadThemes', { theme })
await store.dispatch('loadTheme', { theme: theme.default })

vue.use(designSystem, {
Expand Down
1 change: 1 addition & 0 deletions packages/web-runtime/src/helpers/theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
22 changes: 11 additions & 11 deletions packages/web-runtime/src/pages/accessDenied.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
Loading

0 comments on commit c30d211

Please sign in to comment.