From 264f2322e42f81785a1054500efc5dc864511e1d Mon Sep 17 00:00:00 2001 From: Sergei Garin Date: Mon, 25 Nov 2024 15:19:34 +0300 Subject: [PATCH] Fixes --- app/common/src/text/english.json | 2 + .../AriaComponents/Dialog/Dialog.tsx | 96 ++++++++++--------- .../AriaComponents/Dialog/DialogProvider.tsx | 9 +- .../AriaComponents/Dialog/Popover.tsx | 13 ++- .../components/Devtools/EnsoDevtools.tsx | 45 ++++++--- .../Devtools/EnsoDevtoolsProvider.tsx | 31 ++++++ app/gui/src/dashboard/index.tsx | 13 ++- 7 files changed, 141 insertions(+), 68 deletions(-) diff --git a/app/common/src/text/english.json b/app/common/src/text/english.json index f92ad01eaf3ff..1e8274d39808c 100644 --- a/app/common/src/text/english.json +++ b/app/common/src/text/english.json @@ -477,6 +477,8 @@ "cannotCreateAssetsHere": "You do not have the permissions to create assets here.", "enableVersionChecker": "Enable Version Checker", "enableVersionCheckerDescription": "Show a dialog if the current version of the desktop app does not match the latest version.", + "disableAnimations": "Disable animations", + "disableAnimationsDescription": "Disable all animations in the app.", "removeTheLocalDirectoryXFromFavorites": "remove the local folder '$0' from your favorites", "changeLocalRootDirectoryInSettings": "Change your root folder in Settings.", "localStorage": "Local Storage", diff --git a/app/gui/src/dashboard/components/AriaComponents/Dialog/Dialog.tsx b/app/gui/src/dashboard/components/AriaComponents/Dialog/Dialog.tsx index da7e8498abf80..54e6fc2399eca 100644 --- a/app/gui/src/dashboard/components/AriaComponents/Dialog/Dialog.tsx +++ b/app/gui/src/dashboard/components/AriaComponents/Dialog/Dialog.tsx @@ -341,54 +341,56 @@ function DialogContent(props: DialogContentProps) { {...ariaDialogProps} > {(opts) => ( - - - - - - -
- {/* eslint-disable jsdoc/check-alignment */} - {/** - * This div is used to measure the content dimensions. - * It's takes the same grid area as the content, thus - * resizes together with the content. - * - * We use grid + grid-area to avoid setting `position: relative` - * on the element, which would interfere with the layout. - * - * It's set to `pointer-events-none` so that it doesn't - * interfere with the layout. - */} - {/* eslint-enable jsdoc/check-alignment */} -
-
- - - {typeof children === 'function' ? children(opts) : children} - - + <> + + + + + + +
+ {/* eslint-disable jsdoc/check-alignment */} + {/** + * This div is used to measure the content dimensions. + * It's takes the same grid area as the content, thus + * resizes together with the content. + * + * We use grid + grid-area to avoid setting `position: relative` + * on the element, which would interfere with the layout. + * + * It's set to `pointer-events-none` so that it doesn't + * interfere with the layout. + */} + {/* eslint-enable jsdoc/check-alignment */} +
+
+ + + {typeof children === 'function' ? children(opts) : children} + + +
-
-
-
+ + + )} diff --git a/app/gui/src/dashboard/components/AriaComponents/Dialog/DialogProvider.tsx b/app/gui/src/dashboard/components/AriaComponents/Dialog/DialogProvider.tsx index 3ab28218e323c..8e2272511bbfe 100644 --- a/app/gui/src/dashboard/components/AriaComponents/Dialog/DialogProvider.tsx +++ b/app/gui/src/dashboard/components/AriaComponents/Dialog/DialogProvider.tsx @@ -16,8 +16,13 @@ export interface DialogContextValue { const DialogContext = React.createContext(null) /** The provider for a dialog. */ -// eslint-disable-next-line no-restricted-syntax -export const DialogProvider = DialogContext.Provider +export function DialogProvider(props: DialogContextValue & React.PropsWithChildren) { + const { children, close, dialogId } = props + + const value = React.useMemo(() => ({ close, dialogId }), [close, dialogId]) + + return {children} +} /** Custom hook to get the dialog context. */ export function useDialogContext() { diff --git a/app/gui/src/dashboard/components/AriaComponents/Dialog/Popover.tsx b/app/gui/src/dashboard/components/AriaComponents/Dialog/Popover.tsx index 6738ed3fc99a1..76ce61ad7d6f1 100644 --- a/app/gui/src/dashboard/components/AriaComponents/Dialog/Popover.tsx +++ b/app/gui/src/dashboard/components/AriaComponents/Dialog/Popover.tsx @@ -110,7 +110,6 @@ export function Popover(props: PopoverProps) { }), }) - const dialogContextValue = React.useMemo(() => ({ close, dialogId }), [close, dialogId]) const popoverStyle = React.useMemo(() => ({ zIndex: '' }), []) return ( @@ -140,13 +139,13 @@ export function Popover(props: PopoverProps) { ref={dialogRef} className={POPOVER_STYLES({ ...opts, size, rounded }).dialog()} > - - - + + + {typeof children === 'function' ? children({ ...opts, close }) : children} - - - + + +
)} diff --git a/app/gui/src/dashboard/components/Devtools/EnsoDevtools.tsx b/app/gui/src/dashboard/components/Devtools/EnsoDevtools.tsx index 726098750e87e..e41c813d5522e 100644 --- a/app/gui/src/dashboard/components/Devtools/EnsoDevtools.tsx +++ b/app/gui/src/dashboard/components/Devtools/EnsoDevtools.tsx @@ -21,8 +21,10 @@ import * as authProvider from '#/providers/AuthProvider' import { UserSessionType } from '#/providers/AuthProvider' import * as textProvider from '#/providers/TextProvider' import { + useAnimationsDisabled, useEnableVersionChecker, usePaywallDevtools, + useSetAnimationsDisabled, useSetEnableVersionChecker, useShowDevtools, } from './EnsoDevtoolsProvider' @@ -60,6 +62,10 @@ export function EnsoDevtools() { const { features, setFeature } = usePaywallDevtools() const enableVersionChecker = useEnableVersionChecker() const setEnableVersionChecker = useSetEnableVersionChecker() + + const animationsDisabled = useAnimationsDisabled() + const setAnimationsDisabled = useSetAnimationsDisabled() + const { localStorage } = useLocalStorage() const [localStorageState, setLocalStorageState] = React.useState>({}) @@ -150,19 +156,36 @@ export function EnsoDevtools() { z.object({ enableVersionChecker: z.boolean() })} - defaultValues={{ enableVersionChecker: enableVersionChecker ?? !IS_DEV_MODE }} + schema={(z) => + z.object({ enableVersionChecker: z.boolean(), disableAnimations: z.boolean() }) + } + defaultValues={{ + enableVersionChecker: enableVersionChecker ?? !IS_DEV_MODE, + disableAnimations: animationsDisabled, + }} > {({ form }) => ( - { - setEnableVersionChecker(value) - }} - /> + <> + { + setAnimationsDisabled(value) + }} + /> + + { + setEnableVersionChecker(value) + }} + /> + )} diff --git a/app/gui/src/dashboard/components/Devtools/EnsoDevtoolsProvider.tsx b/app/gui/src/dashboard/components/Devtools/EnsoDevtoolsProvider.tsx index 1c3500964cd3e..c90492d39cebe 100644 --- a/app/gui/src/dashboard/components/Devtools/EnsoDevtoolsProvider.tsx +++ b/app/gui/src/dashboard/components/Devtools/EnsoDevtoolsProvider.tsx @@ -5,6 +5,7 @@ import type { PaywallFeatureName } from '#/hooks/billing' import * as zustand from '#/utilities/zustand' import { IS_DEV_MODE } from 'enso-common/src/detect' +import { MotionGlobalConfig } from 'framer-motion' /** Configuration for a paywall feature. */ export interface PaywallDevtoolsFeatureConfiguration { @@ -24,6 +25,8 @@ interface EnsoDevtoolsStore { readonly paywallFeatures: Record readonly setPaywallFeature: (feature: PaywallFeatureName, isForceEnabled: boolean | null) => void readonly setEnableVersionChecker: (showVersionChecker: boolean | null) => void + readonly animationsDisabled: boolean + readonly setAnimationsDisabled: (animationsDisabled: boolean) => void } export const ensoDevtoolsStore = zustand.createStore((set) => ({ @@ -51,6 +54,20 @@ export const ensoDevtoolsStore = zustand.createStore((set) => setEnableVersionChecker: (showVersionChecker) => { set({ showVersionChecker }) }, + animationsDisabled: localStorage.getItem('disableAnimations') === 'true', + setAnimationsDisabled: (animationsDisabled) => { + if (animationsDisabled) { + localStorage.setItem('disableAnimations', 'true') + MotionGlobalConfig.skipAnimations = true + document.documentElement.classList.add('disable-animations') + } else { + localStorage.setItem('disableAnimations', 'false') + MotionGlobalConfig.skipAnimations = false + document.documentElement.classList.remove('disable-animations') + } + + set({ animationsDisabled }) + }, })) // =============================== @@ -75,6 +92,20 @@ export function useSetEnableVersionChecker() { }) } +/** A function to get whether animations are disabled. */ +export function useAnimationsDisabled() { + return zustand.useStore(ensoDevtoolsStore, (state) => state.animationsDisabled, { + unsafeEnableTransition: true, + }) +} + +/** A function to set whether animations are disabled. */ +export function useSetAnimationsDisabled() { + return zustand.useStore(ensoDevtoolsStore, (state) => state.setAnimationsDisabled, { + unsafeEnableTransition: true, + }) +} + /** A hook that provides access to the paywall devtools. */ export function usePaywallDevtools() { return zustand.useStore( diff --git a/app/gui/src/dashboard/index.tsx b/app/gui/src/dashboard/index.tsx index 12e3c86ffc744..b096cad78a923 100644 --- a/app/gui/src/dashboard/index.tsx +++ b/app/gui/src/dashboard/index.tsx @@ -32,7 +32,18 @@ import { MotionGlobalConfig } from 'framer-motion' export type { GraphEditorRunner } from '#/layouts/Editor' -MotionGlobalConfig.skipAnimations = window.DISABLE_ANIMATIONS ?? false +const ARE_ANIMATIONS_DISABLED = + window.DISABLE_ANIMATIONS === true || + localStorage.getItem('disableAnimations') === 'true' || + false + +MotionGlobalConfig.skipAnimations = ARE_ANIMATIONS_DISABLED + +if (ARE_ANIMATIONS_DISABLED) { + document.documentElement.classList.add('disable-animations') +} else { + document.documentElement.classList.remove('disable-animations') +} // ================= // === Constants ===