Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions web/components/ThemeSwitcher.ce.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<script lang="ts" setup>
/**
* Add to webgui via DefaultPageLayout.php
* Find the footer and the PHP that builds it. Search for `annotate('Footer');` for the start of the footer.
*
* At the of the footer end replace this PHP
* ```
* echo "</span></div>";
* ```
* with the following PHP
* ```
* echo "</span>"; //
* echo "<unraid-theme-switcher current='$theme' themes='".htmlspecialchars(json_encode(['azure', 'gray', 'black', 'white']), ENT_QUOTES, 'UTF-8')."'></unraid-theme-switcher>";
* echo "</div>";
* ```
*
* @todo unraid-theme-switcher usage should pull theme files to determine what themes are available instead of being hardcoded.
*/
import { ref, computed } from 'vue';
import { storeToRefs } from 'pinia';
import { WebguiUpdate } from '~/composables/services/webgui';
import { useServerStore } from '~/store/server';

const props = defineProps<{
current: string;
themes?: string | string[]; // when string it'll be JSON encoded array that's been run thru htmlspecialchars in PHP
}>();

const computedThemes = computed(() => {
if (props.themes) {
return typeof props.themes === 'string' ? JSON.parse(props.themes) : props.themes;
}
return ['azure', 'black', 'gray', 'white'];
});

const { csrf } = storeToRefs(useServerStore());
const devModeEnabled = import.meta.env.VITE_ALLOW_CONSOLE_LOGS;
const submitting = ref<boolean>(false);

const handleThemeChange = (event: Event) => {
const newTheme = (event.target as HTMLSelectElement).value;

if (newTheme === props.current) {
console.debug('[ThemeSwitcher.setTheme] Theme is already set');
return;
}

console.debug('[ThemeSwitcher.setTheme] Submitting form');
submitting.value = true;

try {
WebguiUpdate
.formUrl({
csrf_token: csrf.value,
'#file': 'dynamix/dynamix.cfg',
'#section': 'display',
theme: newTheme,
})
.post()
.res(() => {
console.log('[ThemeSwitcher.setTheme] Theme updated, reloading…');
// without this timeout, the page refresh happens before emhttp has a chance to update the theme
setTimeout(() => {
window.location.reload();
}, 1000);
});
} catch (error) {
console.error('[ThemeSwitcher.setTheme] Failed to update theme', error);
throw new Error('[ThemeSwitcher.setTheme] Failed to update theme');
}
};
</script>

<template>
<select
v-if="devModeEnabled"
:disabled="submitting"
:value="props.current"
class="text-xs relative float-left mr-2 text-white bg-black"
@change="handleThemeChange"
>
<option
v-for="theme in computedThemes"
:key="theme"
:value="theme"
>
{{ theme }}
</option>
</select>
</template>

<style lang="postcss">
/* Import unraid-ui globals first */
@import '@unraid/ui/styles';
@import '~/assets/main.css';
</style>
4 changes: 4 additions & 0 deletions web/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ export default defineNuxtConfig({
name: 'UnraidLogViewer',
path: '@/components/Logs/LogViewer.ce',
},
{
name: 'UnraidThemeSwitcher',
path: '@/components/ThemeSwitcher.ce',
},
],
},
],
Expand Down
Loading