diff --git a/src/core/public/ui_settings/types.ts b/src/core/public/ui_settings/types.ts index 86f78443eee6..039cf19c59de 100644 --- a/src/core/public/ui_settings/types.ts +++ b/src/core/public/ui_settings/types.ts @@ -53,6 +53,7 @@ export interface IUiSettingsClient { * by any plugin then an error is thrown, otherwise reads the default value defined by a plugin. */ get: (key: string, defaultOverride?: T) => T; + getWithBrowserSettings: (key: string, defaultOverride?: T) => T; /** * Gets an observable of the current value for a config key, and all updates to that config diff --git a/src/core/public/ui_settings/ui_settings_client.ts b/src/core/public/ui_settings/ui_settings_client.ts index 31a38e75ca19..83302e61d091 100644 --- a/src/core/public/ui_settings/ui_settings_client.ts +++ b/src/core/public/ui_settings/ui_settings_client.ts @@ -28,7 +28,7 @@ * under the License. */ -import { cloneDeep, defaultsDeep } from 'lodash'; +import { cloneDeep, defaultsDeep, merge } from 'lodash'; import { Observable, Subject, concat, defer, of } from 'rxjs'; import { filter, map } from 'rxjs/operators'; @@ -52,6 +52,7 @@ export class UiSettingsClient implements IUiSettingsClient { private readonly api: UiSettingsApi; private readonly defaults: Record; private cache: Record; + private readonly browserStoredSettings: Record = {}; constructor(params: UiSettingsClientParams) { this.api = params.api; @@ -62,7 +63,8 @@ export class UiSettingsClient implements IUiSettingsClient { this.cache['theme:enableUserControl']?.userValue ?? this.cache['theme:enableUserControl']?.value ) { - this.cache = defaultsDeep(this.cache, this.getBrowserStoredSettings()); + this.browserStoredSettings = this.getBrowserStoredSettings(); + this.cache = defaultsDeep({}, this.defaults, this.cache, this.browserStoredSettings); } params.done$.subscribe({ @@ -114,6 +116,34 @@ You can use \`IUiSettingsClient.get("${key}", defaultValue)\`, which will just r return this.resolveValue(value, type); } + getWithBrowserSettings(key: string, defaultOverride?: T) { + const declared = this.isDeclared(key); + + if (!declared && defaultOverride !== undefined) { + return defaultOverride; + } + + if (!declared) { + throw new Error( + `Unexpected \`IUiSettingsClient.get("${key}")\` call on unrecognized configuration setting "${key}".` + ); + } + + const type = this.cache[key].type; + const userValue = this.cache[key].userValue; + const browserValue = this.browserStoredSettings[key]?.userValue; + const defaultValue = defaultOverride !== undefined ? defaultOverride : this.cache[key].value; + + let value; + if (this.cache['theme:enableUserControl']?.userValue ?? this.cache['theme:enableUserControl']?.value) { + value = browserValue ?? userValue ?? defaultValue; + } else { + value = userValue ?? defaultValue; + } + + return this.resolveValue(value, type); + } + get$(key: string, defaultOverride?: T) { return concat( defer(() => of(this.get(key, defaultOverride))), @@ -250,6 +280,7 @@ You can use \`IUiSettingsClient.get("${key}", defaultValue)\`, which will just r ? this.setBrowserStoredSettings(key, newVal) : (await this.api.batchSet(key, newVal)) || {}; this.cache = defaultsDeep({}, defaults, this.getBrowserStoredSettings(), settings); + console.log("this.cache"); } else { const { settings } = (await this.api.batchSet(key, newVal)) || {}; this.cache = defaultsDeep({}, defaults, settings); diff --git a/src/core/server/ui_settings/settings/theme.ts b/src/core/server/ui_settings/settings/theme.ts index 3f0af93aa5b6..62154b4ef4b7 100644 --- a/src/core/server/ui_settings/settings/theme.ts +++ b/src/core/server/ui_settings/settings/theme.ts @@ -85,7 +85,7 @@ export const getThemeSettings = (): Record => { defaultMessage: `

Switch between the themes used for the current and next versions of OpenSearch Dashboards. A page refresh is required for the setting to be applied.

{linkText}

`, values: { href: 'https://forum.opensearch.org/t/feedback-on-dark-mode-experience/15725', - linkText: 'Theme feedback', + linkText: 'Theme feedback1', }, }), requiresPageReload: true, diff --git a/src/plugins/advanced_settings/public/header_user_theme_menu.tsx b/src/plugins/advanced_settings/public/header_user_theme_menu.tsx index 86a78cbcc2d2..dc2feff450b5 100644 --- a/src/plugins/advanced_settings/public/header_user_theme_menu.tsx +++ b/src/plugins/advanced_settings/public/header_user_theme_menu.tsx @@ -50,21 +50,28 @@ export const HeaderUserThemeMenu = () => { const defaultScreenMode = uiSettings.getDefault('theme:darkMode'); const prefersAutomatic = (window.localStorage.getItem('useBrowserColorScheme') && window.matchMedia) || false; + + const [enableUserControl] = useUiSetting$('theme:enableUserControl'); const [darkMode, setDarkMode] = useUiSetting$('theme:darkMode'); const [themeVersion, setThemeVersion] = useUiSetting$('theme:version'); const [isPopoverOpen, setPopover] = useState(false); // TODO: improve naming? - const [theme, setTheme] = useState( - themeOptions.find((t) => t.value === themeVersionValueMap[themeVersion])?.value || - themeVersionValueMap[defaultTheme] - ); - const [screenMode, setScreenMode] = useState( - prefersAutomatic - ? screenModeOptions[2].value - : darkMode - ? screenModeOptions[1].value - : screenModeOptions[0].value - ); + + + const [theme, setTheme] = useState(() => { + const currentTheme = enableUserControl + ? uiSettings.getWithBrowserSettings('theme:version') + : uiSettings.get('theme:version'); + return themeOptions.find((t) => t.value === themeVersionValueMap[currentTheme])?.value || + themeVersionValueMap[defaultTheme]; + }); + const [screenMode, setScreenMode] = useState(() => { + if (prefersAutomatic) return 'automatic'; + const currentDarkMode = enableUserControl + ? uiSettings.getWithBrowserSettings('theme:darkMode') + : uiSettings.get('theme:darkMode'); + return currentDarkMode ? 'dark' : 'light'; + }); const legacyAppearance = !uiSettings.get('home:useNewHomePage');