Skip to content

Commit

Permalink
ThemeSwitcher refactoring followup (#10342)
Browse files Browse the repository at this point in the history
* ThemeSwitcher refactoring followup

* Update changelog, update import, fix tests

* Add auto theme option (localStorage still wrong)

* Fix auto theme

* Fix auto theme mode

* Update snapshots
  • Loading branch information
lookacat authored Jan 18, 2024
1 parent 1f9946e commit 4839153
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 65 deletions.
1 change: 1 addition & 0 deletions changelog/unreleased/enhancement-move-theme-switcher
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ Enhancement: Move ThemeSwitcher into Account Settings
We've moved the ThemeSwitcher to the account settings page.

https://github.com/owncloud/web/pull/10334
https://github.com/owncloud/web/pull/10342
https://github.com/owncloud/web/issues/10181
37 changes: 26 additions & 11 deletions packages/web-pkg/src/composables/piniaStores/theme.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import merge from 'deepmerge'
import { defineStore } from 'pinia'
import { ref, unref } from 'vue'
import { computed, ref, unref } from 'vue'
import { useLocalStorage, usePreferredDark } from '@vueuse/core'
import { z } from 'zod'
import { applyCustomProp } from 'design-system/src/'
Expand Down Expand Up @@ -82,7 +82,6 @@ export type WebThemeConfigType = z.infer<typeof WebThemeConfig>
const themeStorageKey = 'oc_currentThemeName'

export const useThemeStore = defineStore('theme', () => {
const currentThemeName = useLocalStorage(themeStorageKey, null) // null as default to make fallback possible
const currentLocalStorageThemeName = useLocalStorage(themeStorageKey, null)

const isDark = usePreferredDark()
Expand All @@ -93,20 +92,34 @@ export const useThemeStore = defineStore('theme', () => {

const initializeThemes = (themeConfig: WebThemeConfigType) => {
availableThemes.value = themeConfig.themes.map((theme) => merge(themeConfig.defaults, theme))
setThemeFromStorageOrSystem()
}

if (unref(currentThemeName) === null) {
currentThemeName.value = unref(availableThemes).find((t) => t.isDark === unref(isDark)).name
}

const setThemeFromStorageOrSystem = () => {
const firstLightTheme = unref(availableThemes).find((theme) => !theme.isDark)
const firstDarkTheme = unref(availableThemes).find((theme) => theme.isDark)
setAndApplyTheme(
unref(availableThemes).find((t) => t.name === unref(currentThemeName)) ||
availableThemes.value[0]
unref(availableThemes).find((t) => t.name === unref(currentLocalStorageThemeName)) ||
(unref(isDark) ? firstDarkTheme : firstLightTheme) ||
unref(availableThemes)[0],
false
)
}

const setAndApplyTheme = (theme: WebThemeType) => {
const setAutoSystemTheme = () => {
currentLocalStorageThemeName.value = null
setThemeFromStorageOrSystem()
}

const isCurrentThemeAutoSystem = computed(() => {
return currentLocalStorageThemeName.value === null
})

const setAndApplyTheme = (theme: WebThemeType, updateStorage = true) => {
currentTheme.value = theme
currentLocalStorageThemeName.value = unref(currentTheme).name
if (updateStorage) {
currentLocalStorageThemeName.value = unref(currentTheme).name
}

const customizableDesignTokens = [
{ name: 'breakpoints', prefix: 'breakpoint' },
Expand All @@ -132,6 +145,8 @@ export const useThemeStore = defineStore('theme', () => {
availableThemes,
currentTheme,
initializeThemes,
setAndApplyTheme
setAndApplyTheme,
setAutoSystemTheme,
isCurrentThemeAutoSystem
}
})
56 changes: 56 additions & 0 deletions packages/web-runtime/src/components/ThemeSwitcher.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<template>
<div>
<oc-select
:model-value="currentThemeOrAuto"
:clearable="false"
:options="availableThemesAndAuto"
option-label="name"
@update:model-value="updateTheme"
/>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, ref, unref } from 'vue'
import { useMessages, useThemeStore, WebThemeType } from '@ownclouders/web-pkg'
import { storeToRefs } from 'pinia'
import { useGettext } from 'vue3-gettext'
export default defineComponent({
setup() {
const themeStore = useThemeStore()
const { showMessage } = useMessages()
const { $gettext } = useGettext()
const autoTheme = computed(() => ({ name: $gettext('Auto (same as system)') }))
const { availableThemes, currentTheme } = storeToRefs(themeStore)
const currentThemeSelection = ref(null)
const { setAndApplyTheme, setAutoSystemTheme, isCurrentThemeAutoSystem } = themeStore
const updateTheme = (newTheme: WebThemeType) => {
currentThemeSelection.value = newTheme
showMessage({ title: $gettext('Preference saved.') })
if (newTheme == unref(autoTheme)) {
return setAutoSystemTheme()
}
setAndApplyTheme(newTheme)
}
const currentThemeOrAuto = computed(() => {
if (unref(currentThemeSelection)) {
return unref(currentThemeSelection)
}
if (unref(isCurrentThemeAutoSystem)) {
return unref(autoTheme)
}
return unref(currentTheme)
})
const availableThemesAndAuto = computed(() => [unref(autoTheme), ...unref(availableThemes)])
return {
availableThemesAndAuto,
currentThemeOrAuto,
updateTheme
}
}
})
</script>
43 changes: 0 additions & 43 deletions packages/web-runtime/src/components/Topbar/ThemeSwitcher.vue

This file was deleted.

11 changes: 3 additions & 8 deletions packages/web-runtime/src/pages/account.vue
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
<div class="account-page-info-theme oc-mb oc-width-1-2@s">
<dt class="oc-text-normal oc-text-muted" v-text="$gettext('Theme')" />
<dd data-testid="theme" class="oc-width-1-3">
<theme-switcher @update="onUpdateTheme" />
<theme-switcher />
</dd>
</div>
<div v-if="showNotifications" class="account-page-notification oc-mb oc-width-1-2@s">
Expand Down Expand Up @@ -163,7 +163,7 @@ import { AppLoadingSpinner } from '@ownclouders/web-pkg'
import { SSEAdapter } from '@ownclouders/web-client/src/sse'
import { supportedLanguages } from '../defaults/languages'
import { User } from '@ownclouders/web-client/src/generated'
import ThemeSwitcher from 'web-runtime/src/components/Topbar/ThemeSwitcher.vue'
import ThemeSwitcher from 'web-runtime/src/components/ThemeSwitcher.vue'
export default defineComponent({
name: 'AccountPage',
Expand Down Expand Up @@ -404,10 +404,6 @@ export default defineComponent({
}
}
const onUpdateTheme = () => {
showMessage({ title: $gettext('Preference saved.') })
}
onMounted(async () => {
await loadAccountBundleTask.perform()
await loadValuesListTask.perform()
Expand Down Expand Up @@ -457,8 +453,7 @@ export default defineComponent({
loadAccountBundleTask,
loadGraphUserTask,
loadValuesListTask,
showEditPasswordModal,
onUpdateTheme
showEditPasswordModal
}
},
computed: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { WebThemeType, useThemeStore } from '@ownclouders/web-pkg'
import { mock } from 'jest-mock-extended'
import ThemeSwitcher from 'web-runtime/src/components/Topbar/ThemeSwitcher.vue'
import ThemeSwitcher from 'web-runtime/src/components/ThemeSwitcher.vue'
import defaultTheme from 'web-runtime/themes/owncloud/theme.json'
import { defaultPlugins, defaultStubs, mount } from 'web-test-helpers'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

exports[`ThemeSwitcher component restores dark theme if dark theme is saved in localstorage 1`] = `
<div>
<oc-select-stub clearable="false" model-value="[object Object]" option-label="name" options="[object Object],[object Object]"></oc-select-stub>
<oc-select-stub clearable="false" model-value="[object Object]" option-label="name" options="[object Object],[object Object],[object Object]"></oc-select-stub>
</div>
`;

exports[`ThemeSwitcher component restores light theme if light theme is saved in localstorage 1`] = `
<div>
<oc-select-stub clearable="false" model-value="[object Object]" option-label="name" options="[object Object],[object Object]"></oc-select-stub>
<oc-select-stub clearable="false" model-value="[object Object]" option-label="name" options="[object Object],[object Object],[object Object]"></oc-select-stub>
</div>
`;

0 comments on commit 4839153

Please sign in to comment.