feat: show toast before applying system color scheme (#964)
This commit is contained in:
@@ -13,8 +13,15 @@ import {
|
|||||||
CreateDecryptedLocalStorageContextPayload,
|
CreateDecryptedLocalStorageContextPayload,
|
||||||
InternalEventBus,
|
InternalEventBus,
|
||||||
} from '@standardnotes/snjs';
|
} from '@standardnotes/snjs';
|
||||||
|
import {
|
||||||
|
dismissToast,
|
||||||
|
ToastType,
|
||||||
|
addTimedToast,
|
||||||
|
} from '@standardnotes/stylekit';
|
||||||
|
|
||||||
const CACHED_THEMES_KEY = 'cachedThemes';
|
const CachedThemesKey = 'cachedThemes';
|
||||||
|
const TimeBeforeApplyingColorScheme = 5;
|
||||||
|
const DefaultThemeIdentifier = 'Default';
|
||||||
|
|
||||||
export class ThemeManager extends ApplicationService {
|
export class ThemeManager extends ApplicationService {
|
||||||
private activeThemes: UuidString[] = [];
|
private activeThemes: UuidString[] = [];
|
||||||
@@ -39,7 +46,7 @@ export class ThemeManager extends ApplicationService {
|
|||||||
this.deactivateAllThemes();
|
this.deactivateAllThemes();
|
||||||
this.activeThemes = [];
|
this.activeThemes = [];
|
||||||
this.application?.removeValue(
|
this.application?.removeValue(
|
||||||
CACHED_THEMES_KEY,
|
CachedThemesKey,
|
||||||
StorageValueModes.Nonwrapped
|
StorageValueModes.Nonwrapped
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
@@ -71,19 +78,17 @@ export class ThemeManager extends ApplicationService {
|
|||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
if (useDeviceThemeSettings === this.lastUseDeviceThemeSettings) {
|
if (useDeviceThemeSettings !== this.lastUseDeviceThemeSettings) {
|
||||||
return;
|
this.lastUseDeviceThemeSettings = useDeviceThemeSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lastUseDeviceThemeSettings = useDeviceThemeSettings;
|
if (useDeviceThemeSettings) {
|
||||||
|
const prefersDarkColorScheme = window.matchMedia(
|
||||||
|
'(prefers-color-scheme: dark)'
|
||||||
|
);
|
||||||
|
|
||||||
const prefersDarkColorScheme = window.matchMedia(
|
this.setThemeAsPerColorScheme(prefersDarkColorScheme.matches);
|
||||||
'(prefers-color-scheme: dark)'
|
}
|
||||||
);
|
|
||||||
this.setThemeAsPerColorScheme(
|
|
||||||
useDeviceThemeSettings,
|
|
||||||
prefersDarkColorScheme.matches
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get webApplication() {
|
get webApplication() {
|
||||||
@@ -141,37 +146,59 @@ export class ThemeManager extends ApplicationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private colorSchemeEventHandler(event: MediaQueryListEvent) {
|
private colorSchemeEventHandler(event: MediaQueryListEvent) {
|
||||||
this.setThemeAsPerColorScheme(
|
this.setThemeAsPerColorScheme(event.matches);
|
||||||
this.lastUseDeviceThemeSettings,
|
}
|
||||||
event.matches
|
|
||||||
|
private showColorSchemeToast(setThemeCallback: () => void) {
|
||||||
|
const [toastId, intervalId] = addTimedToast(
|
||||||
|
{
|
||||||
|
type: ToastType.Regular,
|
||||||
|
message: (timeRemaining) =>
|
||||||
|
`Applying system color scheme in ${timeRemaining}s...`,
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
label: 'Keep current theme',
|
||||||
|
handler: () => {
|
||||||
|
dismissToast(toastId);
|
||||||
|
clearInterval(intervalId);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Apply now',
|
||||||
|
handler: () => {
|
||||||
|
dismissToast(toastId);
|
||||||
|
clearInterval(intervalId);
|
||||||
|
setThemeCallback();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
setThemeCallback,
|
||||||
|
TimeBeforeApplyingColorScheme
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private setThemeAsPerColorScheme(
|
private setThemeAsPerColorScheme(prefersDarkColorScheme: boolean) {
|
||||||
useDeviceThemeSettings: boolean,
|
const preference = prefersDarkColorScheme
|
||||||
prefersDarkColorScheme: boolean
|
? PrefKey.AutoDarkThemeIdentifier
|
||||||
) {
|
: PrefKey.AutoLightThemeIdentifier;
|
||||||
if (useDeviceThemeSettings) {
|
|
||||||
const preference = prefersDarkColorScheme
|
|
||||||
? PrefKey.AutoDarkThemeIdentifier
|
|
||||||
: PrefKey.AutoLightThemeIdentifier;
|
|
||||||
const themes = this.application.items.getDisplayableItems<SNTheme>(
|
|
||||||
ContentType.Theme
|
|
||||||
);
|
|
||||||
|
|
||||||
const enableDefaultTheme = () => {
|
const themes = this.application.items.getDisplayableItems(
|
||||||
const activeTheme = themes.find(
|
ContentType.Theme
|
||||||
(theme) => theme.active && !theme.isLayerable()
|
) as SNTheme[];
|
||||||
);
|
|
||||||
if (activeTheme) this.application.mutator.toggleTheme(activeTheme);
|
|
||||||
};
|
|
||||||
|
|
||||||
const themeIdentifier = this.application.getPreference(
|
const activeTheme = themes.find(
|
||||||
preference,
|
(theme) => theme.active && !theme.isLayerable()
|
||||||
'Default'
|
);
|
||||||
) as string;
|
|
||||||
if (themeIdentifier === 'Default') {
|
const themeIdentifier = this.application.getPreference(
|
||||||
enableDefaultTheme();
|
preference,
|
||||||
|
DefaultThemeIdentifier
|
||||||
|
) as string;
|
||||||
|
|
||||||
|
const setTheme = () => {
|
||||||
|
if (themeIdentifier === DefaultThemeIdentifier && activeTheme) {
|
||||||
|
this.application.mutator.toggleTheme(activeTheme);
|
||||||
} else {
|
} else {
|
||||||
const theme = themes.find(
|
const theme = themes.find(
|
||||||
(theme) => theme.package_info.identifier === themeIdentifier
|
(theme) => theme.package_info.identifier === themeIdentifier
|
||||||
@@ -180,6 +207,16 @@ export class ThemeManager extends ApplicationService {
|
|||||||
this.application.mutator.toggleTheme(theme);
|
this.application.mutator.toggleTheme(theme);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const isPreferredThemeNotActive =
|
||||||
|
activeTheme?.identifier !== themeIdentifier;
|
||||||
|
|
||||||
|
const isDefaultThemePreferredAndNotActive =
|
||||||
|
themeIdentifier === DefaultThemeIdentifier && activeTheme;
|
||||||
|
|
||||||
|
if (isPreferredThemeNotActive || isDefaultThemePreferredAndNotActive) {
|
||||||
|
this.showColorSchemeToast(setTheme);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,7 +316,7 @@ export class ThemeManager extends ApplicationService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return this.application.setValue(
|
return this.application.setValue(
|
||||||
CACHED_THEMES_KEY,
|
CachedThemesKey,
|
||||||
mapped,
|
mapped,
|
||||||
StorageValueModes.Nonwrapped
|
StorageValueModes.Nonwrapped
|
||||||
);
|
);
|
||||||
@@ -287,7 +324,7 @@ export class ThemeManager extends ApplicationService {
|
|||||||
|
|
||||||
private async getCachedThemes() {
|
private async getCachedThemes() {
|
||||||
const cachedThemes = (await this.application.getValue(
|
const cachedThemes = (await this.application.getValue(
|
||||||
CACHED_THEMES_KEY,
|
CachedThemesKey,
|
||||||
StorageValueModes.Nonwrapped
|
StorageValueModes.Nonwrapped
|
||||||
)) as SNTheme[];
|
)) as SNTheme[];
|
||||||
if (cachedThemes) {
|
if (cachedThemes) {
|
||||||
|
|||||||
Reference in New Issue
Block a user