Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/shared/storage/OptionsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export interface IOptionsStore {
/** whether we should open the calendar in a new tab; default is to focus an existing calendar tab */
alwaysOpenCalendarInNewTab: boolean;

/** whether animations should be reduced or not
*/
enableReducedMotion: boolean;

/** whether the calendar sidebar should be shown when the calendar is opened */
showCalendarSidebar: boolean;

Expand All @@ -32,6 +36,7 @@ export const OptionsStore = createSyncStore<IOptionsStore>({
enableScrollToLoad: true,
enableDataRefreshing: false,
alwaysOpenCalendarInNewTab: false,
enableReducedMotion: false,
showCalendarSidebar: true,
showUTDiningPromo: true,
});
Expand All @@ -48,6 +53,7 @@ export const initSettings = async () =>
enableScrollToLoad: await OptionsStore.get('enableScrollToLoad'),
enableDataRefreshing: await OptionsStore.get('enableDataRefreshing'),
alwaysOpenCalendarInNewTab: await OptionsStore.get('alwaysOpenCalendarInNewTab'),
enableReducedMotion: await OptionsStore.get('enableReducedMotion'),
showCalendarSidebar: await OptionsStore.get('showCalendarSidebar'),
showUTDiningPromo: await OptionsStore.get('showUTDiningPromo'),
}) satisfies IOptionsStore;
Expand Down
33 changes: 29 additions & 4 deletions src/views/components/common/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import type { PropsWithChildren } from 'react';
import React, { Fragment } from 'react';

import ExtensionRoot from './ExtensionRoot/ExtensionRoot';
import { useEffect } from 'react';
import { useState } from 'react';
import { OptionsStore } from 'src/shared/storage/OptionsStore';

/**
* Represents the props for the _Dialog component
Expand All @@ -32,16 +35,30 @@ export type DialogProps = _DialogProps & Omit<TransitionRootProps<typeof HDialog
*/
export default function Dialog(props: PropsWithChildren<DialogProps>): JSX.Element {
const { children, className, open, title, description, ...rest } = props;
const [reducedMotion, setReducedMotion] = useState(false);

useEffect(() => {
OptionsStore.get('enableReducedMotion').then(val => {
setReducedMotion(val);
});
const listener = OptionsStore.listen('enableReducedMotion', ({ newValue }) => {
setReducedMotion(newValue);
});
}, []);

return (
<Transition show={open} as={HDialog} {...rest}>
<ExtensionRoot>
<TransitionChild
as={Fragment}
enter='transition duration-300 motion-reduce:duration-150 ease-out'
enter={
reducedMotion
? 'transition-none'
: 'transition duration-300 motion-reduce:duration-150 ease-out'
}
enterFrom='opacity-0'
enterTo='opacity-100'
leave='transition duration-150 ease-in delay-25'
leave={reducedMotion ? 'transition-none' : 'transition duration-150 ease-in delay-25'}
leaveFrom='opacity-100'
leaveTo='opacity-0'
>
Expand All @@ -50,10 +67,18 @@ export default function Dialog(props: PropsWithChildren<DialogProps>): JSX.Eleme
<div className='fixed inset-0 z-50 flex items-center justify-center p-2'>
<TransitionChild
as={Fragment}
enter='transition duration-375 motion-reduce:duration-0 ease-[cubic-bezier(0.05,0.4,0.2,1)]'
enter={
reducedMotion
? 'transition-none'
: 'transition duration-375 motion-reduce:duration-0 ease-[cubic-bezier(0.05,0.4,0.2,1)]'
}
enterFrom='transform-gpu scale-95 opacity-0'
enterTo='transform-gpu scale-100 opacity-100'
leave='transition duration-250 motion-reduce:duration-0 ease-[cubic-bezier(0.23,0.01,0.92,0.72)]'
leave={
reducedMotion
? 'transition-none'
: 'transition duration-250 motion-reduce:duration-0 ease-[cubic-bezier(0.23,0.01,0.92,0.72)]'
}
leaveFrom='transform-gpu scale-100 opacity-100'
leaveTo='transform-gpu scale-95 opacity-0'
>
Expand Down
2 changes: 2 additions & 0 deletions src/views/components/common/DialogProvider/DialogProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import React, { useCallback, useRef, useState } from 'react';

import Dialog from '../Dialog';
import Text from '../Text/Text';
import { useEffect } from 'react';
import { OptionsStore } from 'src/shared/storage/OptionsStore';

type DialogElement = (show: boolean) => ReactNode;

Expand Down
24 changes: 24 additions & 0 deletions src/views/components/settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export default function Settings(): JSX.Element {
const [loadAllCourses, setLoadAllCourses] = useState<boolean>(false);
const [_enableDataRefreshing, setEnableDataRefreshing] = useState<boolean>(false);
const [calendarNewTab, setCalendarNewTab] = useState<boolean>(false);
const [reducedMotion, setReducedMotion] = useState<boolean>(false);

const showMigrationDialog = useMigrationDialog();

Expand Down Expand Up @@ -189,13 +190,18 @@ export default function Settings(): JSX.Element {
// console.log('alwaysOpenCalendarInNewTab', newValue);
});

const l6 = OptionsStore.listen('enableReducedMotion', async ({ newValue }) => {
setReducedMotion(newValue);
});

// Remove listeners when the component is unmounted
return () => {
OptionsStore.removeListener(l1);
OptionsStore.removeListener(l2);
OptionsStore.removeListener(l3);
OptionsStore.removeListener(l4);
OptionsStore.removeListener(l5);
OptionsStore.removeListener(l6);

DevStore.removeListener(ds_l1);

Expand Down Expand Up @@ -487,6 +493,24 @@ export default function Settings(): JSX.Element {
/>
</div>

<div className='flex items-center justify-between'>
<div className='max-w-xs'>
<Text variant='h4' className='text-ut-burntorange font-semibold'>
Reduced Motion
</Text>
<p className='text-sm text-gray-600'>
Disable animations and transitions for users who prefer reduced motion.
</p>
</div>
<SwitchButton
isChecked={reducedMotion}
onChange={() => {
setReducedMotion(!reducedMotion);
OptionsStore.set('enableReducedMotion', !reducedMotion);
}}
/>
</div>

<Divider size='auto' orientation='horizontal' />

<div className='flex items-center justify-between'>
Expand Down
Loading