Merge pull request #685 from robintown/reduced-motion
Disable animations for users that prefer reduced motion
This commit is contained in:
		
				commit
				
					
						e6eb2e093c
					
				
			
		
					 3 changed files with 58 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -60,6 +60,7 @@ import { useAudioOutputDevice } from "../video-grid/useAudioOutputDevice";
 | 
			
		|||
import { widget, ElementWidgetActions } from "../widget";
 | 
			
		||||
import { useJoinRule } from "./useJoinRule";
 | 
			
		||||
import { useUrlParams } from "../UrlParams";
 | 
			
		||||
import { usePrefersReducedMotion } from "../usePrefersReducedMotion";
 | 
			
		||||
 | 
			
		||||
const canScreenshare = "getDisplayMedia" in (navigator.mediaDevices ?? {});
 | 
			
		||||
// There is currently a bug in Safari our our code with cloning and sending MediaStreams
 | 
			
		||||
| 
						 | 
				
			
			@ -265,6 +266,8 @@ export function InCallView({
 | 
			
		|||
    []
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const prefersReducedMotion = usePrefersReducedMotion();
 | 
			
		||||
 | 
			
		||||
  const renderContent = (): JSX.Element => {
 | 
			
		||||
    if (items.length === 0) {
 | 
			
		||||
      return (
 | 
			
		||||
| 
						 | 
				
			
			@ -292,7 +295,11 @@ export function InCallView({
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <VideoGrid items={items} layout={layout} disableAnimations={isSafari}>
 | 
			
		||||
      <VideoGrid
 | 
			
		||||
        items={items}
 | 
			
		||||
        layout={layout}
 | 
			
		||||
        disableAnimations={prefersReducedMotion || isSafari}
 | 
			
		||||
      >
 | 
			
		||||
        {({
 | 
			
		||||
          item,
 | 
			
		||||
          ...rest
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,7 @@ import styles from "./PTTButton.module.css";
 | 
			
		|||
import { ReactComponent as MicIcon } from "../icons/Mic.svg";
 | 
			
		||||
import { useEventTarget } from "../useEvents";
 | 
			
		||||
import { Avatar } from "../Avatar";
 | 
			
		||||
import { usePrefersReducedMotion } from "../usePrefersReducedMotion";
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
  enabled: boolean;
 | 
			
		||||
| 
						 | 
				
			
			@ -159,8 +160,14 @@ export const PTTButton: React.FC<Props> = ({
 | 
			
		|||
  // TODO: We will need to disable this for a global PTT hotkey to work
 | 
			
		||||
  useEventTarget(window, "blur", unhold);
 | 
			
		||||
 | 
			
		||||
  const prefersReducedMotion = usePrefersReducedMotion();
 | 
			
		||||
  const { shadow } = useSpring({
 | 
			
		||||
    shadow: (Math.max(activeSpeakerVolume, -70) + 70) * 0.6,
 | 
			
		||||
    immediate: prefersReducedMotion,
 | 
			
		||||
    shadow: prefersReducedMotion
 | 
			
		||||
      ? activeSpeakerUserId
 | 
			
		||||
        ? 17
 | 
			
		||||
        : 0
 | 
			
		||||
      : (Math.max(activeSpeakerVolume, -70) + 70) * 0.6,
 | 
			
		||||
    config: {
 | 
			
		||||
      clamp: true,
 | 
			
		||||
      tension: 300,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										42
									
								
								src/usePrefersReducedMotion.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/usePrefersReducedMotion.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2022 New Vector Ltd
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
import { useCallback, useRef, useState } from "react";
 | 
			
		||||
 | 
			
		||||
import { useEventTarget } from "./useEvents";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @returns Whether the user has requested reduced motion.
 | 
			
		||||
 */
 | 
			
		||||
export const usePrefersReducedMotion = () => {
 | 
			
		||||
  const mediaQuery = useRef<MediaQueryList>();
 | 
			
		||||
  if (mediaQuery.current === undefined)
 | 
			
		||||
    mediaQuery.current = matchMedia("(prefers-reduced-motion)");
 | 
			
		||||
 | 
			
		||||
  const [prefersReducedMotion, setPrefersReducedMotion] = useState(
 | 
			
		||||
    mediaQuery.current.matches
 | 
			
		||||
  );
 | 
			
		||||
  useEventTarget(
 | 
			
		||||
    mediaQuery.current!,
 | 
			
		||||
    "change",
 | 
			
		||||
    useCallback(
 | 
			
		||||
      () => setPrefersReducedMotion(mediaQuery.current!.matches),
 | 
			
		||||
      [setPrefersReducedMotion]
 | 
			
		||||
    )
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return prefersReducedMotion;
 | 
			
		||||
};
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue