Fix DPR update when switching monitors (#4155)

This commit is contained in:
Alexander Zinchuk 2024-01-12 13:00:22 +01:00
parent 16c2fdbc04
commit e9dacf35f3
40 changed files with 137 additions and 98 deletions

View File

@ -24,10 +24,10 @@ import { compact } from '../../../util/iteratees';
import useAppLayout from '../../../hooks/useAppLayout'; import useAppLayout from '../../../hooks/useAppLayout';
import useFlag from '../../../hooks/useFlag'; import useFlag from '../../../hooks/useFlag';
import { useFullscreenStatus } from '../../../hooks/useFullscreen';
import { useIntersectionObserver, useIsIntersecting } from '../../../hooks/useIntersectionObserver'; import { useIntersectionObserver, useIsIntersecting } from '../../../hooks/useIntersectionObserver';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import { useFullscreenStatus } from '../../../hooks/window/useFullscreen';
import useGroupCallVideoLayout from './hooks/useGroupCallVideoLayout'; import useGroupCallVideoLayout from './hooks/useGroupCallVideoLayout';
import Button from '../../ui/Button'; import Button from '../../ui/Button';

View File

@ -15,7 +15,6 @@ import { hexToRgb } from '../../util/switchTheme';
import { IS_ELECTRON } from '../../util/windowEnvironment'; import { IS_ELECTRON } from '../../util/windowEnvironment';
import useColorFilter from '../../hooks/stickers/useColorFilter'; import useColorFilter from '../../hooks/stickers/useColorFilter';
import useBackgroundMode, { isBackgroundModeActive } from '../../hooks/useBackgroundMode';
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps'; import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
import useHeavyAnimationCheck, { isHeavyAnimating } from '../../hooks/useHeavyAnimationCheck'; import useHeavyAnimationCheck, { isHeavyAnimating } from '../../hooks/useHeavyAnimationCheck';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
@ -25,6 +24,7 @@ import { useStateRef } from '../../hooks/useStateRef';
import useSyncEffect from '../../hooks/useSyncEffect'; import useSyncEffect from '../../hooks/useSyncEffect';
import useThrottledCallback from '../../hooks/useThrottledCallback'; import useThrottledCallback from '../../hooks/useThrottledCallback';
import useUniqueId from '../../hooks/useUniqueId'; import useUniqueId from '../../hooks/useUniqueId';
import useBackgroundMode, { isBackgroundModeActive } from '../../hooks/window/useBackgroundMode';
export type OwnProps = { export type OwnProps = {
ref?: RefObject<HTMLDivElement>; ref?: RefObject<HTMLDivElement>;

View File

@ -8,9 +8,10 @@ import type { AvatarSize } from './Avatar';
import { selectPeerStories, selectTheme, selectUser } from '../../global/selectors'; import { selectPeerStories, selectTheme, selectUser } from '../../global/selectors';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import { DPR } from '../../util/windowEnvironment';
import { REM } from './helpers/mediaDimensions'; import { REM } from './helpers/mediaDimensions';
import useDevicePixelRatio from '../../hooks/window/useDevicePixelRatio';
interface OwnProps { interface OwnProps {
// eslint-disable-next-line react/no-unused-prop-types // eslint-disable-next-line react/no-unused-prop-types
peerId: string; peerId: string;
@ -27,15 +28,15 @@ interface StateProps {
} }
const SIZES: Record<AvatarSize, number> = { const SIZES: Record<AvatarSize, number> = {
micro: 1.125 * DPR * REM, micro: 1.125 * REM,
tiny: 2.125 * DPR * REM, tiny: 2.125 * REM,
mini: 1.625 * DPR * REM, mini: 1.625 * REM,
small: 2.25 * DPR * REM, small: 2.25 * REM,
'small-mobile': 2.625 * DPR * REM, 'small-mobile': 2.625 * REM,
medium: 2.875 * DPR * REM, medium: 2.875 * REM,
large: 3.5 * DPR * REM, large: 3.5 * REM,
giant: 5.125 * DPR * REM, giant: 5.125 * REM,
jumbo: 7.625 * DPR * REM, jumbo: 7.625 * REM,
}; };
const BLUE = ['#34C578', '#3CA3F3']; const BLUE = ['#34C578', '#3CA3F3'];
@ -43,8 +44,8 @@ const GREEN = ['#C9EB38', '#09C167'];
const PURPLE = ['#A667FF', '#55A5FF']; const PURPLE = ['#A667FF', '#55A5FF'];
const GRAY = '#C4C9CC'; const GRAY = '#C4C9CC';
const DARK_GRAY = '#737373'; const DARK_GRAY = '#737373';
const STROKE_WIDTH = 0.125 * DPR * REM; const STROKE_WIDTH = 0.125 * REM;
const STROKE_WIDTH_READ = 0.0625 * DPR * REM; const STROKE_WIDTH_READ = 0.0625 * REM;
const GAP_PERCENT = 2; const GAP_PERCENT = 2;
const SEGMENTS_MAX = 45; // More than this breaks rendering in Safari and Chrome const SEGMENTS_MAX = 45; // More than this breaks rendering in Safari and Chrome
@ -66,6 +67,8 @@ function AvatarStoryCircle({
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
const ref = useRef<HTMLCanvasElement>(null); const ref = useRef<HTMLCanvasElement>(null);
const dpr = useDevicePixelRatio();
const values = useMemo(() => { const values = useMemo(() => {
return (storyIds || []).reduce((acc, id) => { return (storyIds || []).reduce((acc, id) => {
acc.total += 1; acc.total += 1;
@ -84,20 +87,21 @@ function AvatarStoryCircle({
drawGradientCircle({ drawGradientCircle({
canvas: ref.current, canvas: ref.current,
size: SIZES[size], size: SIZES[size] * dpr,
segmentsCount: values.total, segmentsCount: values.total,
color: isCloseFriend ? 'green' : 'blue', color: isCloseFriend ? 'green' : 'blue',
readSegmentsCount: values.read, readSegmentsCount: values.read,
withExtraGap, withExtraGap,
readSegmentColor: appTheme === 'dark' ? DARK_GRAY : GRAY, readSegmentColor: appTheme === 'dark' ? DARK_GRAY : GRAY,
dpr,
}); });
}, [appTheme, isCloseFriend, size, values.read, values.total, withExtraGap]); }, [appTheme, isCloseFriend, size, values.read, values.total, withExtraGap, dpr]);
if (!values.total) { if (!values.total) {
return undefined; return undefined;
} }
const maxSize = SIZES[size] / DPR; const maxSize = SIZES[size];
return ( return (
<canvas <canvas
@ -129,6 +133,7 @@ export function drawGradientCircle({
readSegmentsCount = 0, readSegmentsCount = 0,
withExtraGap = false, withExtraGap = false,
readSegmentColor, readSegmentColor,
dpr,
}: { }: {
canvas: HTMLCanvasElement; canvas: HTMLCanvasElement;
size: number; size: number;
@ -137,6 +142,7 @@ export function drawGradientCircle({
readSegmentsCount?: number; readSegmentsCount?: number;
withExtraGap?: boolean; withExtraGap?: boolean;
readSegmentColor: string; readSegmentColor: string;
dpr: number;
}) { }) {
if (segmentsCount > SEGMENTS_MAX) { if (segmentsCount > SEGMENTS_MAX) {
readSegmentsCount = Math.round(readSegmentsCount * (SEGMENTS_MAX / segmentsCount)); readSegmentsCount = Math.round(readSegmentsCount * (SEGMENTS_MAX / segmentsCount));
@ -144,7 +150,7 @@ export function drawGradientCircle({
segmentsCount = SEGMENTS_MAX; segmentsCount = SEGMENTS_MAX;
} }
const strokeModifier = Math.max(Math.max(size - SIZES.large, 0) / DPR / REM / 1.5, 1); const strokeModifier = Math.max(Math.max(size - SIZES.large * dpr, 0) / REM / 1.5, 1);
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
if (!ctx) { if (!ctx) {

View File

@ -28,7 +28,7 @@ import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import useMediaTransition from '../../hooks/useMediaTransition'; import useMediaTransition from '../../hooks/useMediaTransition';
import useResizeObserver from '../../hooks/useResizeObserver'; import useResizeObserver from '../../hooks/useResizeObserver';
import useWindowSize from '../../hooks/useWindowSize'; import useWindowSize from '../../hooks/window/useWindowSize';
import Button from '../ui/Button'; import Button from '../ui/Button';
import ConfirmDialog from '../ui/ConfirmDialog'; import ConfirmDialog from '../ui/ConfirmDialog';

View File

@ -20,6 +20,7 @@ import useMedia from '../../hooks/useMedia';
import useMediaTransition from '../../hooks/useMediaTransition'; import useMediaTransition from '../../hooks/useMediaTransition';
import useThumbnail from '../../hooks/useThumbnail'; import useThumbnail from '../../hooks/useThumbnail';
import useUniqueId from '../../hooks/useUniqueId'; import useUniqueId from '../../hooks/useUniqueId';
import useDevicePixelRatio from '../../hooks/window/useDevicePixelRatio';
import OptimizedVideo from '../ui/OptimizedVideo'; import OptimizedVideo from '../ui/OptimizedVideo';
import AnimatedSticker from './AnimatedSticker'; import AnimatedSticker from './AnimatedSticker';
@ -87,6 +88,8 @@ const StickerView: FC<OwnProps> = ({
const isStatic = !isLottie && !isVideo; const isStatic = !isLottie && !isVideo;
const previewMediaHash = getStickerPreviewHash(sticker.id); const previewMediaHash = getStickerPreviewHash(sticker.id);
const dpr = useDevicePixelRatio();
const filterStyle = useColorFilter(customColor); const filterStyle = useColorFilter(customColor);
const isIntersectingForLoading = useIsIntersecting(containerRef, observeIntersectionForLoading); const isIntersectingForLoading = useIsIntersecting(containerRef, observeIntersectionForLoading);
@ -133,6 +136,7 @@ const StickerView: FC<OwnProps> = ({
id, id,
size, size,
(withSharedAnimation ? customColor : undefined), (withSharedAnimation ? customColor : undefined),
dpr,
].filter(Boolean).join('_'); ].filter(Boolean).join('_');
return ( return (

View File

@ -9,7 +9,7 @@ import { copyTextToClipboard } from '../../../util/clipboard';
import { areLinesWrapping } from '../helpers/renderText'; import { areLinesWrapping } from '../helpers/renderText';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import useWindowSize from '../../../hooks/useWindowSize'; import useWindowSize from '../../../hooks/window/useWindowSize';
import styles from './CodeOverlay.module.scss'; import styles from './CodeOverlay.module.scss';

View File

@ -29,10 +29,10 @@ import useAppLayout from '../../../hooks/useAppLayout';
import useConnectionStatus from '../../../hooks/useConnectionStatus'; import useConnectionStatus from '../../../hooks/useConnectionStatus';
import useElectronDrag from '../../../hooks/useElectronDrag'; import useElectronDrag from '../../../hooks/useElectronDrag';
import useFlag from '../../../hooks/useFlag'; import useFlag from '../../../hooks/useFlag';
import { useFullscreenStatus } from '../../../hooks/useFullscreen';
import { useHotkeys } from '../../../hooks/useHotkeys'; import { useHotkeys } from '../../../hooks/useHotkeys';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import { useFullscreenStatus } from '../../../hooks/window/useFullscreen';
import useLeftHeaderButtonRtlForumTransition from './hooks/useLeftHeaderButtonRtlForumTransition'; import useLeftHeaderButtonRtlForumTransition from './hooks/useLeftHeaderButtonRtlForumTransition';
import PickerSelectedItem from '../../common/PickerSelectedItem'; import PickerSelectedItem from '../../common/PickerSelectedItem';

View File

@ -12,7 +12,7 @@ import { pick } from '../../util/iteratees';
import useAppLayout from '../../hooks/useAppLayout'; import useAppLayout from '../../hooks/useAppLayout';
import useForceUpdate from '../../hooks/useForceUpdate'; import useForceUpdate from '../../hooks/useForceUpdate';
import useSyncEffect from '../../hooks/useSyncEffect'; import useSyncEffect from '../../hooks/useSyncEffect';
import useWindowSize from '../../hooks/useWindowSize'; import useWindowSize from '../../hooks/window/useWindowSize';
import styles from './ConfettiContainer.module.scss'; import styles from './ConfettiContainer.module.scss';

View File

@ -50,10 +50,7 @@ import updateIcon from '../../util/updateIcon';
import { IS_ANDROID, IS_ELECTRON } from '../../util/windowEnvironment'; import { IS_ANDROID, IS_ELECTRON } from '../../util/windowEnvironment';
import useAppLayout from '../../hooks/useAppLayout'; import useAppLayout from '../../hooks/useAppLayout';
import useBackgroundMode from '../../hooks/useBackgroundMode';
import useBeforeUnload from '../../hooks/useBeforeUnload';
import useForceUpdate from '../../hooks/useForceUpdate'; import useForceUpdate from '../../hooks/useForceUpdate';
import { useFullscreenStatus } from '../../hooks/useFullscreen';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck'; import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import useInterval from '../../hooks/useInterval'; import useInterval from '../../hooks/useInterval';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
@ -61,6 +58,9 @@ import usePreventPinchZoomGesture from '../../hooks/usePreventPinchZoomGesture';
import useShowTransition from '../../hooks/useShowTransition'; import useShowTransition from '../../hooks/useShowTransition';
import useSyncEffect from '../../hooks/useSyncEffect'; import useSyncEffect from '../../hooks/useSyncEffect';
import useTimeout from '../../hooks/useTimeout'; import useTimeout from '../../hooks/useTimeout';
import useBackgroundMode from '../../hooks/window/useBackgroundMode';
import useBeforeUnload from '../../hooks/window/useBeforeUnload';
import { useFullscreenStatus } from '../../hooks/window/useFullscreen';
import ActiveCallHeader from '../calls/ActiveCallHeader.async'; import ActiveCallHeader from '../calls/ActiveCallHeader.async';
import GroupCall from '../calls/group/GroupCall.async'; import GroupCall from '../calls/group/GroupCall.async';

View File

@ -5,11 +5,11 @@ import type { ApiUser } from '../../../../api/types';
import { selectUser } from '../../../../global/selectors'; import { selectUser } from '../../../../global/selectors';
import buildClassName from '../../../../util/buildClassName'; import buildClassName from '../../../../util/buildClassName';
import { DPR } from '../../../../util/windowEnvironment';
import { REM } from '../../../common/helpers/mediaDimensions'; import { REM } from '../../../common/helpers/mediaDimensions';
import useLang from '../../../../hooks/useLang'; import useLang from '../../../../hooks/useLang';
import useScrolledState from '../../../../hooks/useScrolledState'; import useScrolledState from '../../../../hooks/useScrolledState';
import useDevicePixelRatio from '../../../../hooks/window/useDevicePixelRatio';
import Avatar from '../../../common/Avatar'; import Avatar from '../../../common/Avatar';
import { drawGradientCircle } from '../../../common/AvatarStoryCircle'; import { drawGradientCircle } from '../../../common/AvatarStoryCircle';
@ -53,7 +53,7 @@ const STORY_FEATURE_ICONS = {
const STORY_FEATURE_ORDER = Object.keys(STORY_FEATURE_TITLES) as (keyof typeof STORY_FEATURE_TITLES)[]; const STORY_FEATURE_ORDER = Object.keys(STORY_FEATURE_TITLES) as (keyof typeof STORY_FEATURE_TITLES)[];
const CIRCLE_SIZE = 5.25 * DPR * REM; const CIRCLE_SIZE = 5.25 * REM;
const CIRCLE_SEGMENTS = 8; const CIRCLE_SEGMENTS = 8;
const CIRCLE_READ_SEGMENTS = 0; const CIRCLE_READ_SEGMENTS = 0;
@ -65,6 +65,8 @@ const PremiumFeaturePreviewVideo = ({
const lang = useLang(); const lang = useLang();
const dpr = useDevicePixelRatio();
useLayoutEffect(() => { useLayoutEffect(() => {
if (!circleRef.current) { if (!circleRef.current) {
return; return;
@ -72,17 +74,18 @@ const PremiumFeaturePreviewVideo = ({
drawGradientCircle({ drawGradientCircle({
canvas: circleRef.current, canvas: circleRef.current,
size: CIRCLE_SIZE, size: CIRCLE_SIZE * dpr,
segmentsCount: CIRCLE_SEGMENTS, segmentsCount: CIRCLE_SEGMENTS,
color: 'purple', color: 'purple',
readSegmentsCount: CIRCLE_READ_SEGMENTS, readSegmentsCount: CIRCLE_READ_SEGMENTS,
readSegmentColor: 'transparent', readSegmentColor: 'transparent',
dpr,
}); });
}, []); }, [dpr]);
const { handleScroll, isAtBeginning } = useScrolledState(); const { handleScroll, isAtBeginning } = useScrolledState();
const maxSize = CIRCLE_SIZE / DPR; const maxSize = CIRCLE_SIZE;
return ( return (
<div className={styles.root}> <div className={styles.root}>

View File

@ -186,18 +186,10 @@ const MediaViewer: FC<StateProps> = ({
const forceUpdate = useForceUpdate(); const forceUpdate = useForceUpdate();
useEffect(() => { useEffect(() => {
const mql = window.matchMedia(MEDIA_VIEWER_MEDIA_QUERY); const mql = window.matchMedia(MEDIA_VIEWER_MEDIA_QUERY);
if (typeof mql.addEventListener === 'function') { mql.addEventListener('change', forceUpdate);
mql.addEventListener('change', forceUpdate);
} else if (typeof mql.addListener === 'function') {
mql.addListener(forceUpdate);
}
return () => { return () => {
if (typeof mql.removeEventListener === 'function') { mql.removeEventListener('change', forceUpdate);
mql.removeEventListener('change', forceUpdate);
} else if (typeof mql.removeListener === 'function') {
mql.removeListener(forceUpdate);
}
}; };
}, [forceUpdate]); }, [forceUpdate]);

View File

@ -20,14 +20,14 @@ import { IS_IOS, IS_TOUCH_ENV } from '../../util/windowEnvironment';
import useDebouncedCallback from '../../hooks/useDebouncedCallback'; import useDebouncedCallback from '../../hooks/useDebouncedCallback';
import useDerivedState from '../../hooks/useDerivedState'; import useDerivedState from '../../hooks/useDerivedState';
import { useFullscreenStatus } from '../../hooks/useFullscreen';
import useHistoryBack from '../../hooks/useHistoryBack'; import useHistoryBack from '../../hooks/useHistoryBack';
import useLang from '../../hooks/useLang'; import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import useSignal from '../../hooks/useSignal'; import useSignal from '../../hooks/useSignal';
import { useSignalRef } from '../../hooks/useSignalRef'; import { useSignalRef } from '../../hooks/useSignalRef';
import useTimeout from '../../hooks/useTimeout'; import useTimeout from '../../hooks/useTimeout';
import useWindowSize from '../../hooks/useWindowSize'; import { useFullscreenStatus } from '../../hooks/window/useFullscreen';
import useWindowSize from '../../hooks/window/useWindowSize';
import useControlsSignal from './hooks/useControlsSignal'; import useControlsSignal from './hooks/useControlsSignal';
import useZoomChange from './hooks/useZoomChangeSignal'; import useZoomChange from './hooks/useZoomChangeSignal';

View File

@ -15,11 +15,11 @@ import useUnsupportedMedia from '../../hooks/media/useUnsupportedMedia';
import useAppLayout from '../../hooks/useAppLayout'; import useAppLayout from '../../hooks/useAppLayout';
import useBuffering from '../../hooks/useBuffering'; import useBuffering from '../../hooks/useBuffering';
import useCurrentTimeSignal from '../../hooks/useCurrentTimeSignal'; import useCurrentTimeSignal from '../../hooks/useCurrentTimeSignal';
import useFullscreen from '../../hooks/useFullscreen';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import usePictureInPicture from '../../hooks/usePictureInPicture'; import usePictureInPicture from '../../hooks/usePictureInPicture';
import useShowTransition from '../../hooks/useShowTransition'; import useShowTransition from '../../hooks/useShowTransition';
import useVideoCleanup from '../../hooks/useVideoCleanup'; import useVideoCleanup from '../../hooks/useVideoCleanup';
import useFullscreen from '../../hooks/window/useFullscreen';
import useControlsSignal from './hooks/useControlsSignal'; import useControlsSignal from './hooks/useControlsSignal';
import useVideoWaitingSignal from './hooks/useVideoWaitingSignal'; import useVideoWaitingSignal from './hooks/useVideoWaitingSignal';

View File

@ -58,7 +58,6 @@ import { debounce, onTickEnd } from '../../util/schedulers';
import { groupMessages } from './helpers/groupMessages'; import { groupMessages } from './helpers/groupMessages';
import { preventMessageInputBlur } from './helpers/preventMessageInputBlur'; import { preventMessageInputBlur } from './helpers/preventMessageInputBlur';
import { isBackgroundModeActive } from '../../hooks/useBackgroundMode';
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps'; import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck'; import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import useInterval from '../../hooks/useInterval'; import useInterval from '../../hooks/useInterval';
@ -67,6 +66,7 @@ import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps
import useNativeCopySelectedMessages from '../../hooks/useNativeCopySelectedMessages'; import useNativeCopySelectedMessages from '../../hooks/useNativeCopySelectedMessages';
import { useStateRef } from '../../hooks/useStateRef'; import { useStateRef } from '../../hooks/useStateRef';
import useSyncEffect from '../../hooks/useSyncEffect'; import useSyncEffect from '../../hooks/useSyncEffect';
import { isBackgroundModeActive } from '../../hooks/window/useBackgroundMode';
import useContainerHeight from './hooks/useContainerHeight'; import useContainerHeight from './hooks/useContainerHeight';
import useStickyDates from './hooks/useStickyDates'; import useStickyDates from './hooks/useStickyDates';

View File

@ -13,11 +13,11 @@ import {
import { selectBot, selectUserFullInfo } from '../../global/selectors'; import { selectBot, selectUserFullInfo } from '../../global/selectors';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import buildStyle from '../../util/buildStyle'; import buildStyle from '../../util/buildStyle';
import { DPR } from '../../util/windowEnvironment';
import renderText from '../common/helpers/renderText'; import renderText from '../common/helpers/renderText';
import useLang from '../../hooks/useLang'; import useLang from '../../hooks/useLang';
import useMedia from '../../hooks/useMedia'; import useMedia from '../../hooks/useMedia';
import useDevicePixelRatio from '../../hooks/window/useDevicePixelRatio';
import OptimizedVideo from '../ui/OptimizedVideo'; import OptimizedVideo from '../ui/OptimizedVideo';
import Skeleton from '../ui/placeholder/Skeleton'; import Skeleton from '../ui/placeholder/Skeleton';
@ -40,14 +40,15 @@ const MessageListBotInfo: FC<OwnProps & StateProps> = ({
isInMessageList, isInMessageList,
}) => { }) => {
const lang = useLang(); const lang = useLang();
const dpr = useDevicePixelRatio();
const botInfoPhotoUrl = useMedia(botInfo?.photo ? getBotCoverMediaHash(botInfo.photo) : undefined); const botInfoPhotoUrl = useMedia(botInfo?.photo ? getBotCoverMediaHash(botInfo.photo) : undefined);
const botInfoGifUrl = useMedia(botInfo?.gif ? getDocumentMediaHash(botInfo.gif) : undefined); const botInfoGifUrl = useMedia(botInfo?.gif ? getDocumentMediaHash(botInfo.gif) : undefined);
const botInfoDimensions = botInfo?.photo ? getPhotoFullDimensions(botInfo.photo) : botInfo?.gif const botInfoDimensions = botInfo?.photo ? getPhotoFullDimensions(botInfo.photo) : botInfo?.gif
? getVideoDimensions(botInfo.gif) : undefined; ? getVideoDimensions(botInfo.gif) : undefined;
const botInfoRealDimensions = botInfoDimensions && { const botInfoRealDimensions = botInfoDimensions && {
width: botInfoDimensions.width / DPR, width: botInfoDimensions.width / dpr,
height: botInfoDimensions.height / DPR, height: botInfoDimensions.height / dpr,
}; };
const isBotInfoEmpty = botInfo && !botInfo.description && !botInfo.gif && !botInfo.photo; const isBotInfoEmpty = botInfo && !botInfo.description && !botInfo.gif && !botInfo.photo;

View File

@ -72,7 +72,7 @@ import usePrevDuringAnimation from '../../hooks/usePrevDuringAnimation';
import usePrevious from '../../hooks/usePrevious'; import usePrevious from '../../hooks/usePrevious';
import { useResize } from '../../hooks/useResize'; import { useResize } from '../../hooks/useResize';
import useSyncEffect from '../../hooks/useSyncEffect'; import useSyncEffect from '../../hooks/useSyncEffect';
import useWindowSize from '../../hooks/useWindowSize'; import useWindowSize from '../../hooks/window/useWindowSize';
import usePinnedMessage from './hooks/usePinnedMessage'; import usePinnedMessage from './hooks/usePinnedMessage';
import Composer from '../common/Composer'; import Composer from '../common/Composer';

View File

@ -62,7 +62,7 @@ import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import usePrevious from '../../hooks/usePrevious'; import usePrevious from '../../hooks/usePrevious';
import useShowTransition from '../../hooks/useShowTransition'; import useShowTransition from '../../hooks/useShowTransition';
import useWindowSize from '../../hooks/useWindowSize'; import useWindowSize from '../../hooks/window/useWindowSize';
import GroupCallTopPane from '../calls/group/GroupCallTopPane'; import GroupCallTopPane from '../calls/group/GroupCallTopPane';
import GroupChatInfo from '../common/GroupChatInfo'; import GroupChatInfo from '../common/GroupChatInfo';

View File

@ -15,12 +15,12 @@ import parseHtmlAsFormattedText from '../../../../util/parseHtmlAsFormattedText'
import { IS_TOUCH_ENV } from '../../../../util/windowEnvironment'; import { IS_TOUCH_ENV } from '../../../../util/windowEnvironment';
import { getTextWithEntitiesAsHtml } from '../../../common/helpers/renderTextWithEntities'; import { getTextWithEntitiesAsHtml } from '../../../common/helpers/renderTextWithEntities';
import useBackgroundMode from '../../../../hooks/useBackgroundMode';
import useBeforeUnload from '../../../../hooks/useBeforeUnload';
import useLastCallback from '../../../../hooks/useLastCallback'; import useLastCallback from '../../../../hooks/useLastCallback';
import useLayoutEffectWithPrevDeps from '../../../../hooks/useLayoutEffectWithPrevDeps'; import useLayoutEffectWithPrevDeps from '../../../../hooks/useLayoutEffectWithPrevDeps';
import useRunDebounced from '../../../../hooks/useRunDebounced'; import useRunDebounced from '../../../../hooks/useRunDebounced';
import { useStateRef } from '../../../../hooks/useStateRef'; import { useStateRef } from '../../../../hooks/useStateRef';
import useBackgroundMode from '../../../../hooks/window/useBackgroundMode';
import useBeforeUnload from '../../../../hooks/window/useBeforeUnload';
let isFrozen = false; let isFrozen = false;

View File

@ -14,11 +14,11 @@ import parseHtmlAsFormattedText from '../../../../util/parseHtmlAsFormattedText'
import { getTextWithEntitiesAsHtml } from '../../../common/helpers/renderTextWithEntities'; import { getTextWithEntitiesAsHtml } from '../../../common/helpers/renderTextWithEntities';
import { useDebouncedResolver } from '../../../../hooks/useAsyncResolvers'; import { useDebouncedResolver } from '../../../../hooks/useAsyncResolvers';
import useBackgroundMode from '../../../../hooks/useBackgroundMode';
import useBeforeUnload from '../../../../hooks/useBeforeUnload';
import useDerivedSignal from '../../../../hooks/useDerivedSignal'; import useDerivedSignal from '../../../../hooks/useDerivedSignal';
import useEffectWithPrevDeps from '../../../../hooks/useEffectWithPrevDeps'; import useEffectWithPrevDeps from '../../../../hooks/useEffectWithPrevDeps';
import useLastCallback from '../../../../hooks/useLastCallback'; import useLastCallback from '../../../../hooks/useLastCallback';
import useBackgroundMode from '../../../../hooks/window/useBackgroundMode';
import useBeforeUnload from '../../../../hooks/window/useBeforeUnload';
const URL_ENTITIES = new Set<string>([ApiMessageEntityTypes.TextUrl, ApiMessageEntityTypes.Url]); const URL_ENTITIES = new Set<string>([ApiMessageEntityTypes.TextUrl, ApiMessageEntityTypes.Url]);
const DEBOUNCE_MS = 300; const DEBOUNCE_MS = 300;

View File

@ -20,11 +20,12 @@ import { REM } from '../../../common/helpers/mediaDimensions';
import useColorFilter from '../../../../hooks/stickers/useColorFilter'; import useColorFilter from '../../../../hooks/stickers/useColorFilter';
import useDynamicColorListener from '../../../../hooks/stickers/useDynamicColorListener'; import useDynamicColorListener from '../../../../hooks/stickers/useDynamicColorListener';
import useBackgroundMode from '../../../../hooks/useBackgroundMode';
import useEffectWithPrevDeps from '../../../../hooks/useEffectWithPrevDeps'; import useEffectWithPrevDeps from '../../../../hooks/useEffectWithPrevDeps';
import useLastCallback from '../../../../hooks/useLastCallback'; import useLastCallback from '../../../../hooks/useLastCallback';
import useResizeObserver from '../../../../hooks/useResizeObserver'; import useResizeObserver from '../../../../hooks/useResizeObserver';
import useThrottledCallback from '../../../../hooks/useThrottledCallback'; import useThrottledCallback from '../../../../hooks/useThrottledCallback';
import useBackgroundMode from '../../../../hooks/window/useBackgroundMode';
import useDevicePixelRatio from '../../../../hooks/window/useDevicePixelRatio';
const SIZE = 1.25 * REM; const SIZE = 1.25 * REM;
const THROTTLE_MS = 300; const THROTTLE_MS = 300;
@ -49,6 +50,7 @@ export default function useInputCustomEmojis(
) { ) {
const customColor = useDynamicColorListener(inputRef, !isReady); const customColor = useDynamicColorListener(inputRef, !isReady);
const colorFilter = useColorFilter(customColor, true); const colorFilter = useColorFilter(customColor, true);
const dpr = useDevicePixelRatio();
const playersById = useRef<Map<string, CustomEmojiPlayer>>(new Map()); const playersById = useRef<Map<string, CustomEmojiPlayer>>(new Map());
const clearPlayers = useLastCallback((ids: string[]) => { const clearPlayers = useLastCallback((ids: string[]) => {
@ -99,7 +101,7 @@ export default function useInputCustomEmojis(
} }
const isHq = customEmoji?.stickerSetInfo && selectIsAlwaysHighPriorityEmoji(global, customEmoji.stickerSetInfo); const isHq = customEmoji?.stickerSetInfo && selectIsAlwaysHighPriorityEmoji(global, customEmoji.stickerSetInfo);
const renderId = [ const renderId = [
prefixId, documentId, customColor, prefixId, documentId, customColor, dpr,
].filter(Boolean).join('_'); ].filter(Boolean).join('_');
createPlayer({ createPlayer({
@ -159,6 +161,12 @@ export default function useInputCustomEmojis(
false, false,
); );
useResizeObserver(sharedCanvasRef, throttledSynchronizeElements); useResizeObserver(sharedCanvasRef, throttledSynchronizeElements);
useEffectWithPrevDeps(([prevDpr]) => {
if (dpr !== prevDpr) {
clearPlayers(Array.from(playersById.current.keys()));
synchronizeElements();
}
}, [dpr, synchronizeElements]);
const freezeAnimation = useLastCallback(() => { const freezeAnimation = useLastCallback(() => {
playersById.current.forEach((player) => { playersById.current.forEach((player) => {

View File

@ -7,8 +7,8 @@ import type { PinnedIntersectionChangedCallback } from './usePinnedMessage';
import { IS_ANDROID } from '../../../util/windowEnvironment'; import { IS_ANDROID } from '../../../util/windowEnvironment';
import useAppLayout from '../../../hooks/useAppLayout'; import useAppLayout from '../../../hooks/useAppLayout';
import useBackgroundMode, { isBackgroundModeActive } from '../../../hooks/useBackgroundMode';
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver'; import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
import useBackgroundMode, { isBackgroundModeActive } from '../../../hooks/window/useBackgroundMode';
const INTERSECTION_THROTTLE_FOR_READING = 150; const INTERSECTION_THROTTLE_FOR_READING = 150;
const INTERSECTION_THROTTLE_FOR_MEDIA = IS_ANDROID ? 1000 : 350; const INTERSECTION_THROTTLE_FOR_MEDIA = IS_ANDROID ? 1000 : 350;

View File

@ -10,7 +10,7 @@ import buildClassName from '../../../util/buildClassName';
import { REM } from '../../common/helpers/mediaDimensions'; import { REM } from '../../common/helpers/mediaDimensions';
import useAppLayout from '../../../hooks/useAppLayout'; import useAppLayout from '../../../hooks/useAppLayout';
import useWindowSize from '../../../hooks/useWindowSize'; import useWindowSize from '../../../hooks/window/useWindowSize';
import ReactionEmoji from '../../common/ReactionEmoji'; import ReactionEmoji from '../../common/ReactionEmoji';

View File

@ -2,10 +2,10 @@ import { useEffect, useRef } from '../../../../lib/teact/teact';
import { requestMeasure } from '../../../../lib/fasterdom/fasterdom'; import { requestMeasure } from '../../../../lib/fasterdom/fasterdom';
import useBackgroundMode, { isBackgroundModeActive } from '../../../../hooks/useBackgroundMode';
import useHeavyAnimationCheck, { isHeavyAnimating } from '../../../../hooks/useHeavyAnimationCheck'; import useHeavyAnimationCheck, { isHeavyAnimating } from '../../../../hooks/useHeavyAnimationCheck';
import useLastCallback from '../../../../hooks/useLastCallback'; import useLastCallback from '../../../../hooks/useLastCallback';
import usePriorityPlaybackCheck, { isPriorityPlaybackActive } from '../../../../hooks/usePriorityPlaybackCheck'; import usePriorityPlaybackCheck, { isPriorityPlaybackActive } from '../../../../hooks/usePriorityPlaybackCheck';
import useBackgroundMode, { isBackgroundModeActive } from '../../../../hooks/window/useBackgroundMode';
export default function useVideoAutoPause( export default function useVideoAutoPause(
playerRef: { current: HTMLVideoElement | null }, canPlay: boolean, isPriority?: boolean, playerRef: { current: HTMLVideoElement | null }, canPlay: boolean, isPriority?: boolean,

View File

@ -6,7 +6,7 @@ import type { WebAppInboundEvent, WebAppOutboundEvent } from '../../../../types/
import { extractCurrentThemeParams } from '../../../../util/themeStyle'; import { extractCurrentThemeParams } from '../../../../util/themeStyle';
import useLastCallback from '../../../../hooks/useLastCallback'; import useLastCallback from '../../../../hooks/useLastCallback';
import useWindowSize from '../../../../hooks/useWindowSize'; import useWindowSize from '../../../../hooks/window/useWindowSize';
const SCROLLBAR_STYLE = `* { const SCROLLBAR_STYLE = `* {
scrollbar-width: thin; scrollbar-width: thin;

View File

@ -18,7 +18,7 @@ import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
import useHistoryBack from '../../hooks/useHistoryBack'; import useHistoryBack from '../../hooks/useHistoryBack';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps'; import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps';
import useWindowSize from '../../hooks/useWindowSize'; import useWindowSize from '../../hooks/window/useWindowSize';
import Transition from '../ui/Transition'; import Transition from '../ui/Transition';
import AddChatMembers from './AddChatMembers'; import AddChatMembers from './AddChatMembers';

View File

@ -34,7 +34,6 @@ import { PRIMARY_VIDEO_MIME, SECONDARY_VIDEO_MIME } from './helpers/videoFormats
import useUnsupportedMedia from '../../hooks/media/useUnsupportedMedia'; import useUnsupportedMedia from '../../hooks/media/useUnsupportedMedia';
import useAppLayout, { getIsMobile } from '../../hooks/useAppLayout'; import useAppLayout, { getIsMobile } from '../../hooks/useAppLayout';
import useBackgroundMode from '../../hooks/useBackgroundMode';
import useCanvasBlur from '../../hooks/useCanvasBlur'; import useCanvasBlur from '../../hooks/useCanvasBlur';
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev'; import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps'; import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
@ -45,6 +44,7 @@ import useLongPress from '../../hooks/useLongPress';
import useMediaTransition from '../../hooks/useMediaTransition'; import useMediaTransition from '../../hooks/useMediaTransition';
import useShowTransition from '../../hooks/useShowTransition'; import useShowTransition from '../../hooks/useShowTransition';
import { useStreaming } from '../../hooks/useStreaming'; import { useStreaming } from '../../hooks/useStreaming';
import useBackgroundMode from '../../hooks/window/useBackgroundMode';
import useStoryPreloader from './hooks/useStoryPreloader'; import useStoryPreloader from './hooks/useStoryPreloader';
import useStoryProps from './hooks/useStoryProps'; import useStoryProps from './hooks/useStoryProps';

View File

@ -36,7 +36,7 @@ import useHistoryBack from '../../hooks/useHistoryBack';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import usePrevious from '../../hooks/usePrevious'; import usePrevious from '../../hooks/usePrevious';
import useSignal from '../../hooks/useSignal'; import useSignal from '../../hooks/useSignal';
import useWindowSize from '../../hooks/useWindowSize'; import useWindowSize from '../../hooks/window/useWindowSize';
import useSlideSizes from './hooks/useSlideSizes'; import useSlideSizes from './hooks/useSlideSizes';
import Story from './Story'; import Story from './Story';

View File

@ -2,7 +2,7 @@ import { useMemo } from '../../../lib/teact/teact';
import { calculateSlideSizes } from '../helpers/dimensions'; import { calculateSlideSizes } from '../helpers/dimensions';
import useWindowSize from '../../../hooks/useWindowSize'; import useWindowSize from '../../../hooks/window/useWindowSize';
export default function useSlideSizes() { export default function useSlideSizes() {
const { width: windowWidth, height: windowHeight } = useWindowSize(); const { width: windowWidth, height: windowHeight } = useWindowSize();

View File

@ -8,7 +8,7 @@ import { requestMutation } from '../../../lib/fasterdom/fasterdom';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
import buildStyle from '../../../util/buildStyle'; import buildStyle from '../../../util/buildStyle';
import useWindowSize from '../../../hooks/useWindowSize'; import useWindowSize from '../../../hooks/window/useWindowSize';
import MediaAreaSuggestedReaction from './MediaAreaSuggestedReaction'; import MediaAreaSuggestedReaction from './MediaAreaSuggestedReaction';

View File

@ -4,18 +4,18 @@ import React, { memo, useEffect, useRef } from '../../lib/teact/teact';
import { requestMutation } from '../../lib/fasterdom/fasterdom'; import { requestMutation } from '../../lib/fasterdom/fasterdom';
import { animate, timingFunctions } from '../../util/animation'; import { animate, timingFunctions } from '../../util/animation';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import { DPR } from '../../util/windowEnvironment';
import { useStateRef } from '../../hooks/useStateRef'; import { useStateRef } from '../../hooks/useStateRef';
import useDevicePixelRatio from '../../hooks/window/useDevicePixelRatio';
import './ProgressSpinner.scss'; import './ProgressSpinner.scss';
const SIZES = { const SIZES = {
s: 42, m: 48, l: 54, xl: 52, s: 42, m: 48, l: 54, xl: 52,
}; };
const STROKE_WIDTH = 2 * DPR; const STROKE_WIDTH = 2;
const STROKE_WIDTH_XL = 3 * DPR; const STROKE_WIDTH_XL = 3;
const PADDING = 2 * DPR; const PADDING = 2;
const MIN_PROGRESS = 0.05; const MIN_PROGRESS = 0.05;
const MAX_PROGRESS = 1; const MAX_PROGRESS = 1;
const GROW_DURATION = 600; // 0.6 s const GROW_DURATION = 600; // 0.6 s
@ -41,6 +41,8 @@ const ProgressSpinner: FC<{
const width = SIZES[size]; const width = SIZES[size];
const progressRef = useStateRef(progress); const progressRef = useStateRef(progress);
const dpr = useDevicePixelRatio();
useEffect(() => { useEffect(() => {
let isFirst = true; let isFirst = true;
let growFrom = MIN_PROGRESS; let growFrom = MIN_PROGRESS;
@ -65,10 +67,11 @@ const ProgressSpinner: FC<{
drawSpinnerArc( drawSpinnerArc(
canvasRef.current, canvasRef.current,
width * DPR, width * dpr,
size === 'xl' ? STROKE_WIDTH_XL : STROKE_WIDTH, (size === 'xl' ? STROKE_WIDTH_XL : STROKE_WIDTH) * dpr,
'white', 'white',
currentProgress, currentProgress,
dpr,
isFirst, isFirst,
); );
@ -76,7 +79,7 @@ const ProgressSpinner: FC<{
return currentProgress < 1; return currentProgress < 1;
}, requestMutation); }, requestMutation);
}, [progressRef, size, width]); }, [progressRef, size, width, dpr]);
const className = buildClassName( const className = buildClassName(
`ProgressSpinner size-${size}`, `ProgressSpinner size-${size}`,
@ -101,10 +104,11 @@ function drawSpinnerArc(
strokeWidth: number, strokeWidth: number,
color: string, color: string,
progress: number, progress: number,
dpr: number,
shouldInit = false, shouldInit = false,
) { ) {
const centerCoordinate = size / 2; const centerCoordinate = size / 2;
const radius = (size - strokeWidth) / 2 - PADDING; const radius = (size - strokeWidth) / 2 - PADDING * dpr;
const rotationOffset = (Date.now() % ROTATE_DURATION) / ROTATE_DURATION; const rotationOffset = (Date.now() % ROTATE_DURATION) / ROTATE_DURATION;
const startAngle = (2 * Math.PI) * rotationOffset; const startAngle = (2 * Math.PI) * rotationOffset;
const endAngle = startAngle + (2 * Math.PI) * progress; const endAngle = startAngle + (2 * Math.PI) * progress;

View File

@ -1,7 +1,7 @@
import type { GlobalState } from '../global/types'; import type { GlobalState } from '../global/types';
import type { LangFn } from './useLang'; import type { LangFn } from './useLang';
import useBrowserOnline from './useBrowserOnline'; import useBrowserOnline from './window/useBrowserOnline';
export enum ConnectionStatus { export enum ConnectionStatus {
waitingForNetwork, waitingForNetwork,

View File

@ -1,7 +1,7 @@
import { useEffect } from '../lib/teact/teact'; import { useEffect } from '../../lib/teact/teact';
import { createCallbackManager } from '../util/callbacks'; import { createCallbackManager } from '../../util/callbacks';
import useLastCallback from './useLastCallback'; import useLastCallback from '../useLastCallback';
const blurCallbacks = createCallbackManager(); const blurCallbacks = createCallbackManager();
const focusCallbacks = createCallbackManager(); const focusCallbacks = createCallbackManager();

View File

@ -1,7 +1,7 @@
import { useEffect } from '../lib/teact/teact'; import { useEffect } from '../../lib/teact/teact';
import { onBeforeUnload } from '../util/schedulers'; import { onBeforeUnload } from '../../util/schedulers';
import useLastCallback from './useLastCallback'; import useLastCallback from '../useLastCallback';
export default function useBeforeUnload(callback: AnyToVoidFunction) { export default function useBeforeUnload(callback: AnyToVoidFunction) {
const lastCallback = useLastCallback(callback); const lastCallback = useLastCallback(callback);

View File

@ -1,4 +1,4 @@
import { useEffect, useState } from '../lib/teact/teact'; import { useEffect, useState } from '../../lib/teact/teact';
export default function useBrowserOnline() { export default function useBrowserOnline() {
const [isOnline, setIsOnline] = useState(window.navigator.onLine); const [isOnline, setIsOnline] = useState(window.navigator.onLine);

View File

@ -0,0 +1,28 @@
import { useState } from '../../lib/teact/teact';
import { createCallbackManager } from '../../util/callbacks';
import useEffectOnce from '../useEffectOnce';
const callbacks = createCallbackManager();
function createListener() {
window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`)
.addEventListener('change', callbacks.runCallbacks, { once: true });
}
export default function useDevicePixelRatio() {
const [dpr, setDpr] = useState(window.devicePixelRatio);
useEffectOnce(() => {
callbacks.addCallback(() => {
setDpr(window.devicePixelRatio);
});
});
return dpr;
}
createListener();
// Set up new listener for the next `devicePixelRatio` change
callbacks.addCallback(createListener);

View File

@ -1,8 +1,8 @@
import { useEffect, useLayoutEffect, useState } from '../lib/teact/teact'; import { useEffect, useLayoutEffect, useState } from '../../lib/teact/teact';
import { ElectronEvent } from '../types/electron'; import { ElectronEvent } from '../../types/electron';
import { IS_IOS } from '../util/windowEnvironment'; import { IS_IOS } from '../../util/windowEnvironment';
type RefType = { type RefType = {
current: HTMLVideoElement | null; current: HTMLVideoElement | null;

View File

@ -1,8 +1,8 @@
import { useEffect, useMemo, useState } from '../lib/teact/teact'; import { useEffect, useMemo, useState } from '../../lib/teact/teact';
import { throttle } from '../util/schedulers'; import { throttle } from '../../util/schedulers';
import windowSize from '../util/windowSize'; import windowSize from '../../util/windowSize';
import useDebouncedCallback from './useDebouncedCallback'; import useDebouncedCallback from '../useDebouncedCallback';
const THROTTLE = 250; const THROTTLE = 250;

View File

@ -4,8 +4,7 @@ import Deferred from '../../util/Deferred';
import generateUniqueId from '../../util/generateUniqueId'; import generateUniqueId from '../../util/generateUniqueId';
import launchMediaWorkers, { MAX_WORKERS } from '../../util/launchMediaWorkers'; import launchMediaWorkers, { MAX_WORKERS } from '../../util/launchMediaWorkers';
import { import {
DPR, IS_ANDROID, IS_IOS, IS_ANDROID, IS_IOS, IS_SAFARI,
IS_SAFARI,
} from '../../util/windowEnvironment'; } from '../../util/windowEnvironment';
import { requestMeasure, requestMutation } from '../fasterdom/fasterdom'; import { requestMeasure, requestMutation } from '../fasterdom/fasterdom';
@ -338,7 +337,7 @@ class RLottie {
} = this.params; } = this.params;
// Reduced quality only looks acceptable on high DPR screens // Reduced quality only looks acceptable on high DPR screens
return Math.max(DPR * quality, 1); return Math.max(window.devicePixelRatio * quality, 1);
} }
private destroy() { private destroy() {

View File

@ -20,9 +20,5 @@ export function setSystemThemeChangeCallback(callback: (newTheme: ThemeKey) => v
themeChangeCallback = callback; themeChangeCallback = callback;
} }
const mql = window.matchMedia('(prefers-color-scheme: dark)'); window.matchMedia('(prefers-color-scheme: dark)')
if (typeof mql.addEventListener === 'function') { .addEventListener('change', handleSystemThemeChange);
mql.addEventListener('change', handleSystemThemeChange);
} else if (typeof mql.addListener === 'function') {
mql.addListener(handleSystemThemeChange);
}

View File

@ -80,8 +80,6 @@ export const IS_WEBM_SUPPORTED = Boolean(TEST_VIDEO.canPlayType('video/webm; cod
export const ARE_WEBCODECS_SUPPORTED = 'VideoDecoder' in window; export const ARE_WEBCODECS_SUPPORTED = 'VideoDecoder' in window;
export const DPR = window.devicePixelRatio || 1;
export const MASK_IMAGE_DISABLED = true; export const MASK_IMAGE_DISABLED = true;
export const IS_OPFS_SUPPORTED = Boolean(navigator.storage?.getDirectory); export const IS_OPFS_SUPPORTED = Boolean(navigator.storage?.getDirectory);
if (IS_OPFS_SUPPORTED) { if (IS_OPFS_SUPPORTED) {