From 50348a1cc6c115187c23ba4428debfda4eb81b9a Mon Sep 17 00:00:00 2001 From: Tai Sakuma Date: Thu, 1 Aug 2024 14:33:26 -0400 Subject: [PATCH 1/6] Update `useProvideConfig()` to accept to a ref or getter of `null` --- src/utils/config/index.ts | 5 +++-- src/utils/config/provide-config.ts | 35 ++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/utils/config/index.ts b/src/utils/config/index.ts index c4ee90f..5be54db 100644 --- a/src/utils/config/index.ts +++ b/src/utils/config/index.ts @@ -19,8 +19,9 @@ export const useConfig = () => useConfigT(); * Provide the config to the child components. * In the child components, use `useConfig` to get the config. */ -export const useProvideConfig = (config: MaybeRefOrGetter) => - useProvideConfigT(config); +export const useProvideConfig = ( + config: Exclude, null> +) => useProvideConfigT(config); /** * Read the config from the config file. diff --git a/src/utils/config/provide-config.ts b/src/utils/config/provide-config.ts index 7a2b987..f0e6bff 100644 --- a/src/utils/config/provide-config.ts +++ b/src/utils/config/provide-config.ts @@ -2,15 +2,36 @@ import { ref, provide, watchEffect, toValue } from "vue"; import type { MaybeRefOrGetter, InjectionKey, Ref } from "vue"; import { injectionKey } from "./key"; - /** - * Provide the config of type `T` to the child components. - * In the child components, use `useConfig` to get the config. + * Provides a configuration of type `T` to child components. + * + * This function creates a reactive reference to the config and provides it + * to child components using Vue's provide/inject system. + * + * @template T The type of the configuration object + * @param The configuration, which can be: + * - A value of type T + * - A Ref + * - A getter function returning T or null + * + * @remarks + * In child components, use `useConfig` to retrieve this provided config. + * The config will only be provided once it has a non-null value. + * Subsequent updates to the config (including to undefined) will be reflected + * in the provided reference, but will not trigger a new provide. */ -export function useProvideConfigT(config: MaybeRefOrGetter) { - const configRef = ref(toValue(config)) as Ref; +export function useProvideConfigT( + config: Exclude, null> +) { + const configRef = ref() as Ref; + let provided = false; + watchEffect(() => { - configRef.value = toValue(config); + const value = toValue(config); + if (value === null) return; + configRef.value = value; + if (provided) return; + provide(injectionKey as InjectionKey>, configRef); + provided = true; }); - provide(injectionKey as InjectionKey>, configRef); } From 51e11eb0f633098cf70994a977e556c3db077bed Mon Sep 17 00:00:00 2001 From: Tai Sakuma Date: Thu, 1 Aug 2024 14:45:12 -0400 Subject: [PATCH 2/6] Clean code in `ProvideConfig.vue` --- src/utils/config/ProvideConfig.vue | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/src/utils/config/ProvideConfig.vue b/src/utils/config/ProvideConfig.vue index 48305d3..4059268 100644 --- a/src/utils/config/ProvideConfig.vue +++ b/src/utils/config/ProvideConfig.vue @@ -15,28 +15,8 @@ /** * Load config asynchronously and provide it to the child components. */ -import { ref, watchEffect, nextTick } from "vue"; -import type { ComputedRef } from "vue"; import { useLoadConfig } from "@/utils/config"; -import { useProvideConfig, Config } from "@/utils/config"; - -const error = ref(); - -const { error: loadError, config } = await useLoadConfig(); -watchEffect(() => { - error.value = loadError.value; -}); - -if (!config.value) throw new Error("Config is null"); -useProvideConfig(config as ComputedRef); - -// For test reactivity of loading. -// await new Promise((resolve) => setTimeout(resolve, 1000)); - -// For test reactivity of error. -// error.value = new Error("Test"); -// nextTick(async () => { -// await new Promise((resolve) => setTimeout(resolve, 1000)); -// error.value = undefined; -// }); +import { useProvideConfig } from "@/utils/config"; +const { error, config } = await useLoadConfig(); +useProvideConfig(config); From 9da8810cfeaddc7e64142a781571e51dd16a3d4f Mon Sep 17 00:00:00 2001 From: Tai Sakuma Date: Thu, 1 Aug 2024 14:51:11 -0400 Subject: [PATCH 3/6] Make `sourceColorHex` the option of `useColorTheme()` --- src/utils/color-theme/color-theme.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/utils/color-theme/color-theme.ts b/src/utils/color-theme/color-theme.ts index 9e7c8ed..b0c360c 100644 --- a/src/utils/color-theme/color-theme.ts +++ b/src/utils/color-theme/color-theme.ts @@ -1,4 +1,5 @@ import { ref } from "vue"; +import type { MaybeRef } from "vue"; import { useDynamicColors } from "@/utils/dynamic-color"; import { @@ -7,14 +8,11 @@ import { } from "./monaco-editor"; import { useDynamicColorsOnVuetify, useDarkModeOnVuetify } from "./vuetify"; -function useSourceColor() { - const sourceColor = ref("#607D8B"); // blue grey - // const sourceColor = ref("#E91E63"); // pink - return { sourceColor }; -} +const DEFAULT_SOURCE_COLOR_HEX = "#607D8B"; // blue grey +// const DEFAULT_SOURCE_COLOR_HEX = "#E91E63"; // pink -export function useColorTheme() { - const { sourceColor: sourceColorHex } = useSourceColor(); +export function useColorTheme(sourceColorHex?: MaybeRef) { + sourceColorHex = ref(sourceColorHex ?? DEFAULT_SOURCE_COLOR_HEX); const optionsLight = { sourceColorHex, dark: false }; const optionsDark = { sourceColorHex, dark: true }; From 4195d996747c1fbc22a906a51ecc4bdc65b8a13b Mon Sep 17 00:00:00 2001 From: Tai Sakuma Date: Thu, 1 Aug 2024 14:56:18 -0400 Subject: [PATCH 4/6] Add `seedColor` to config --- docker/config.json | 3 ++- public/config.json | 3 ++- src/utils/config/config.ts | 5 +++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docker/config.json b/docker/config.json index 71c2296..06ac627 100644 --- a/docker/config.json +++ b/docker/config.json @@ -1,4 +1,5 @@ { "apiName": "localhost", - "apiHttp": "http://localhost:8000" + "apiHttp": "http://localhost:8000", + "seedColor": "#607D8B" } diff --git a/public/config.json b/public/config.json index 71c2296..06ac627 100644 --- a/public/config.json +++ b/public/config.json @@ -1,4 +1,5 @@ { "apiName": "localhost", - "apiHttp": "http://localhost:8000" + "apiHttp": "http://localhost:8000", + "seedColor": "#607D8B" } diff --git a/src/utils/config/config.ts b/src/utils/config/config.ts index 8ce5469..bc661da 100644 --- a/src/utils/config/config.ts +++ b/src/utils/config/config.ts @@ -2,6 +2,7 @@ export interface Config { appName: string; apiName: string; apiHttp: string; + seedColor: string; } export const defaultConfig = { @@ -18,4 +19,8 @@ export function validateConfig(config: Config) { if (typeof config.apiHttp !== "string") throw Error("apiHttp is not string"); if (config?.apiHttp === "") throw Error("apiHttp is empty"); + + if (typeof config.seedColor !== "string") throw Error("seedColor is not string"); + if (!/^#([0-9A-F]{3}|[0-9A-F]{6}|[0-9A-F]{8})$/i.test(config.seedColor)) + throw Error(`seedColor is not a valid hex color: ${config.seedColor}`); } From ff86441ca4909d4ea24db5ac1958b6d5f09b06cd Mon Sep 17 00:00:00 2001 From: Tai Sakuma Date: Thu, 1 Aug 2024 14:57:46 -0400 Subject: [PATCH 5/6] Use `seedColor` as `sourceColorHex` in `AppMain.vue` --- src/app/AppMain.vue | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/app/AppMain.vue b/src/app/AppMain.vue index 6a1c30f..9f65cc8 100644 --- a/src/app/AppMain.vue +++ b/src/app/AppMain.vue @@ -38,9 +38,11 @@ stay hidden. -->