diff --git a/src/App.vue b/src/App.vue
index 6728627..c6d080c 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -19,34 +19,36 @@ import Navbar from './features/nav/components/Navbar.vue';
import Footer from './features/footer/components/Footer.vue';
import { updatePageTitle } from './router';
-import { useColorScheme } from './features/colorScheme/composables/useColorScheme';
-import { ref, provide, watch, watchEffect } from 'vue';
+import { useSettings } from './features/settings/composables/useSettings.js';
+import { computed, watch, watchEffect } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
-const { getColorScheme, updateColorScheme } = useColorScheme();
-const colorScheme = ref(null);
-provide('colorScheme', colorScheme);
-watch(colorScheme, (newValue) => {
- updateColorScheme(newValue);
+const { getSetting } = useSettings();
+const colorScheme = computed(() => getSetting(['appearance', 'colorScheme']));
+
+const updateColorScheme = function updateColorScheme (newColorScheme) {
document.body.style.setProperty(colorScheme, {
auto: 'normal',
dark: 'dark',
light: 'light'
});
- if (newValue === 'dark') {
+ if (newColorScheme === 'dark') {
document.body.classList.add('dark');
} else {
document.body.classList.remove('dark');
}
- if (newValue === 'auto') {
+ if (newColorScheme === 'auto') {
document.body.classList.add('color-scheme-auto');
} else {
document.body.classList.remove('color-scheme-auto');
}
+}
+watch(colorScheme, (newColorScheme) => {
+ updateColorScheme(newColorScheme);
});
-colorScheme.value = getColorScheme();
+updateColorScheme(colorScheme.value);
watchEffect(() => updatePageTitle(route));
diff --git a/src/features/colorScheme/components/ColorSchemeButton.vue b/src/features/colorScheme/components/ColorSchemeButton.vue
index 4f4c228..ed56e9d 100644
--- a/src/features/colorScheme/components/ColorSchemeButton.vue
+++ b/src/features/colorScheme/components/ColorSchemeButton.vue
@@ -17,12 +17,14 @@ limitations under the License.
-
- {{ t('loading') }}
-
-
+
diff --git a/src/features/settings/views/__tests__/SettingsView.test.js b/src/features/settings/views/__tests__/SettingsView.test.js
index e8584ce..446f3a1 100644
--- a/src/features/settings/views/__tests__/SettingsView.test.js
+++ b/src/features/settings/views/__tests__/SettingsView.test.js
@@ -16,8 +16,8 @@ limitations under the License.
import SettingsView from '../SettingsView.vue';
import { mountComponent } from '@/test-utils/mountComponent.js';
-import { flushPromises } from '@vue/test-utils';
import { beforeEach, describe, expect, test, vi } from 'vitest';
+import { nextTick } from 'vue';
const settingsHoisted = vi.hoisted(() => [
{
@@ -197,10 +197,8 @@ const settings = settingsHoisted.values();
const originalCurrentSection = 's0';
let currentSection = originalCurrentSection;
-vi.mock('../../utils/settingsParser', () => ({
- loadSettingsConfig: vi.fn().mockResolvedValue({
- contents: settingsHoisted
- })
+vi.mock('../../settings.json', () => ({
+ default: { contents: settingsHoisted }
}));
vi.mock('vue-router', async (importOriginal) => {
@@ -235,9 +233,7 @@ describe('SettingsView', () => {
describe('sidebar', () => {
test('shows all top-level sections', async () => {
const wrapper = getWrapper();
-
- await flushPromises();
- await wrapper.vm.$nextTick();
+ await nextTick();
const sidebarItems = wrapper.findAll('.sidebar-sections-list > li');
settings.forEach((setting, index) => {
@@ -254,47 +250,27 @@ describe('SettingsView', () => {
describe('main', () => {
describe('correct element', () => {
- test('shows that it is loading', () => {
- const wrapper = getWrapper();
-
- const mainContentLoading = wrapper.find('.main-content--loading');
- const mainContentLoaded = wrapper.find('.main-content--loaded');
- const mainContentNoSection = wrapper.find('.main-content--no-section');
-
- expect(mainContentLoading.exists()).toBe(true);
- expect(mainContentLoaded.exists()).toBe(false);
- expect(mainContentNoSection.exists()).toBe(false);
- });
-
test('shows that no section is selected', async () => {
currentSection = '';
const wrapper = getWrapper();
+ await nextTick();
- await flushPromises();
- await wrapper.vm.$nextTick();
-
- const mainContentLoading = wrapper.find('.main-content--loading');
- const mainContentLoaded = wrapper.find('.main-content--loaded');
+ const mainContent = wrapper.find('.settings-main-content');
const mainContentNoSection = wrapper.find('.main-content--no-section');
- expect(mainContentLoading.exists()).toBe(false);
- expect(mainContentLoaded.exists()).toBe(false);
+ expect(mainContent.exists()).toBe(false);
expect(mainContentNoSection.exists()).toBe(true);
});
test('shows main content', async () => {
const wrapper = getWrapper();
+ await nextTick();
- await flushPromises();
- await wrapper.vm.$nextTick();
-
- const mainContentLoading = wrapper.find('.main-content--loading');
- const mainContentLoaded = wrapper.find('.main-content--loaded');
+ const mainContent = wrapper.find('.settings-main-content');
const mainContentNoSection = wrapper.find('.main-content--no-section');
- expect(mainContentLoading.exists()).toBe(false);
- expect(mainContentLoaded.exists()).toBe(true);
+ expect(mainContent.exists()).toBe(true);
expect(mainContentNoSection.exists()).toBe(false);
});
});
diff --git a/src/locales/de.json b/src/locales/de.json
index 1b82c31..93f7593 100644
--- a/src/locales/de.json
+++ b/src/locales/de.json
@@ -60,6 +60,21 @@
"option": {
"ariaLabel": "Wählt die Option {option} aus"
}
+ },
+ "settings": {
+ "appearance": {
+ "title": "Erscheinungsbild",
+ "contents": {
+ "colorScheme": {
+ "title": "Farbschema",
+ "options": {
+ "auto": "An Systemfarbschema anpassen",
+ "light": "Hell",
+ "dark": "Dunkel"
+ }
+ }
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/src/locales/en.json b/src/locales/en.json
index c47a8c1..4c4c8a1 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -60,6 +60,21 @@
"option": {
"ariaLabel": "Selects option {option}"
}
+ },
+ "settings": {
+ "appearance": {
+ "title": "Appearance",
+ "contents": {
+ "colorScheme": {
+ "title": "Color Scheme",
+ "options": {
+ "auto": "Adapt to system color scheme",
+ "light": "Light",
+ "dark": "Dark"
+ }
+ }
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
index 90efd54..d7efce6 100644
--- a/src/main.js
+++ b/src/main.js
@@ -30,6 +30,9 @@ import rawFonts from './styles/fonts.json';
import './styles/common.css';
import './styles/variables/colors.css';
+import settings from './features/settings/settings.json';
+import { validateSettingsConfig } from './features/settings/utils/settingsValidator';
+
(async () => {
const fonts = rawFonts.map((font) => new FontFace(
font.family ?? '',
@@ -54,6 +57,8 @@ import './styles/variables/colors.css';
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);
+
+ validateSettingsConfig(settings);
createApp(App)
.use(router)