Create reduced motIon setting (#226)

Adds a new setting that emulates the prefers-reduced-motion media query, allowing users to disable Wave animations without affecting other apps on their system. It also honors the prefers-reduced-motion query in case a system-level configuration is present.
This commit is contained in:
Evan Simkowitz
2024-08-14 21:47:09 -07:00
committed by GitHub
parent 3c9b3423a9
commit b5c6c1a937
7 changed files with 38 additions and 15 deletions
+20 -2
View File
@@ -459,8 +459,20 @@ const AppKeyHandlers = () => {
};
const AppInner = () => {
const [prefersReducedMotion, setPrefersReducedMotion] = React.useState(false);
const prefersReducedMotionSetting = jotai.useAtomValue(atoms.reducedMotionPreferenceAtom);
const client = jotai.useAtomValue(atoms.client);
const windowData = jotai.useAtomValue(atoms.waveWindow);
const isFullScreen = jotai.useAtomValue(atoms.isFullScreen);
React.useEffect(() => {
const reducedMotionQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
setPrefersReducedMotion(!reducedMotionQuery || reducedMotionQuery.matches);
reducedMotionQuery.addEventListener("change", () => {
setPrefersReducedMotion(reducedMotionQuery.matches);
});
}, []);
if (client == null || windowData == null) {
return (
<div className="mainapp">
@@ -470,12 +482,18 @@ const AppInner = () => {
);
}
const isFullScreen = jotai.useAtomValue(atoms.isFullScreen);
return (
<div className={clsx("mainapp", PLATFORM, { fullscreen: isFullScreen })} onContextMenu={handleContextMenu}>
<div
className={clsx("mainapp", PLATFORM, {
fullscreen: isFullScreen,
"prefers-reduced-motion": prefersReducedMotion || prefersReducedMotionSetting,
})}
onContextMenu={handleContextMenu}
>
<AppBackground />
<AppKeyHandlers />
<AppSettingsUpdater />
-m
<DndProvider backend={HTML5Backend}>
<Workspace />
</DndProvider>
+1 -1
View File
@@ -26,7 +26,7 @@
}
}
@media (prefers-reduced-motion) {
.prefers-reduced-motion {
.magnify-icon svg {
#arrow1,
#arrow2 {
+9 -7
View File
@@ -101,16 +101,17 @@ function initGlobalAtoms(initOpts: GlobalInitOptions) {
return windowData.activetabid;
});
const controlShiftDelayAtom = jotai.atom(false);
const updateStatusAtom = jotai.atom<UpdaterStatus>("up-to-date") as jotai.PrimitiveAtom<UpdaterStatus>;
const updaterStatusAtom = jotai.atom<UpdaterStatus>("up-to-date") as jotai.PrimitiveAtom<UpdaterStatus>;
try {
globalStore.set(updateStatusAtom, getApi().getUpdaterStatus());
globalStore.set(updaterStatusAtom, getApi().getUpdaterStatus());
getApi().onUpdaterStatusChange((status) => {
console.log("updater status change", status);
globalStore.set(updateStatusAtom, status);
globalStore.set(updaterStatusAtom, status);
});
} catch (_) {
// do nothing
}
const reducedMotionPreferenceAtom = jotai.atom((get) => get(settingsConfigAtom).window.reducedmotion);
atoms = {
// initialized in wave.ts (will not be null inside of application)
windowId: windowIdAtom,
@@ -119,12 +120,13 @@ function initGlobalAtoms(initOpts: GlobalInitOptions) {
client: clientAtom,
waveWindow: windowDataAtom,
workspace: workspaceAtom,
settingsConfigAtom: settingsConfigAtom,
tabAtom: tabAtom,
settingsConfigAtom,
tabAtom,
activeTabId: activeTabIdAtom,
isFullScreen: isFullScreenAtom,
controlShiftDelayAtom: controlShiftDelayAtom,
updaterStatusAtom: updateStatusAtom,
controlShiftDelayAtom,
updaterStatusAtom,
reducedMotionPreferenceAtom,
};
}
+1 -1
View File
@@ -125,7 +125,7 @@
}
}
@media (prefers-reduced-motion) {
.prefers-reduced-motion {
.tile-layout {
&.animate {
.tile-node,
+1
View File
@@ -17,6 +17,7 @@ declare global {
activeTabId: jotai.Atom<string>; // derrived from windowDataAtom
isFullScreen: jotai.PrimitiveAtom<boolean>;
controlShiftDelayAtom: jotai.PrimitiveAtom<boolean>;
reducedMotionPreferenceAtom: jotai.Atom<boolean>;
updaterStatusAtom: jotai.PrimitiveAtom<UpdaterStatus>;
};
+1
View File
@@ -616,6 +616,7 @@ declare global {
blur: boolean;
opacity: number;
bgcolor: string;
reducedmotion: boolean;
};
// wstore.Workspace
+5 -4
View File
@@ -89,10 +89,11 @@ type TermThemesConfigType map[string]TermThemeType
// note we pointers so we preserve nulls
type WindowSettingsType struct {
Transparent *bool `json:"transparent"`
Blur *bool `json:"blur"`
Opacity *float64 `json:"opacity"`
BgColor *string `json:"bgcolor"`
Transparent *bool `json:"transparent"`
Blur *bool `json:"blur"`
Opacity *float64 `json:"opacity"`
BgColor *string `json:"bgcolor"`
ReducedMotion *bool `json:"reducedmotion"`
}
type TelemetrySettingsType struct {