import React, { memo, useEffect, useRef } from '../../../lib/teact/teact'; import { getActions } from '../../../global'; import type { ApiMediaArea, ApiStory } from '../../../api/types'; import { MOBILE_SCREEN_MAX_WIDTH } from '../../../config'; import { requestMutation } from '../../../lib/fasterdom/fasterdom'; import buildClassName from '../../../util/buildClassName'; import buildStyle from '../../../util/buildStyle'; import useWindowSize from '../../../hooks/window/useWindowSize'; import MediaAreaSuggestedReaction from './MediaAreaSuggestedReaction'; import styles from './MediaArea.module.scss'; type OwnProps = { story: ApiStory; isActive?: boolean; className?: string; }; const STORY_ASPECT_RATIO = 9 / 16; const MediaAreaOverlay = ({ story, isActive, className, }: OwnProps) => { const { openMapModal, focusMessage, closeStoryViewer, openUrl, } = getActions(); // eslint-disable-next-line no-null/no-null const ref = useRef(null); const windowSize = useWindowSize(); useEffect(() => { if (!ref.current || !isActive) return; const element = ref.current; if (windowSize.width > MOBILE_SCREEN_MAX_WIDTH) { requestMutation(() => { element.style.removeProperty('--media-width'); element.style.removeProperty('--media-height'); }); return; } const screenAspectRatio = windowSize.width / windowSize.height; const width = screenAspectRatio < STORY_ASPECT_RATIO ? element.clientHeight * STORY_ASPECT_RATIO : element.clientWidth; const height = screenAspectRatio < STORY_ASPECT_RATIO ? element.clientHeight : element.clientWidth / STORY_ASPECT_RATIO; requestMutation(() => { element.style.setProperty('--media-width', `${width}px`); element.style.setProperty('--media-height', `${height}px`); }); }, [isActive, windowSize]); const handleMediaAreaClick = (mediaArea: ApiMediaArea) => { switch (mediaArea.type) { case 'geoPoint': case 'venue': { openMapModal({ geoPoint: mediaArea.geo }); break; } case 'channelPost': { focusMessage({ chatId: mediaArea.channelId, messageId: mediaArea.messageId, }); closeStoryViewer(); break; } case 'url': { openUrl({ url: mediaArea.url }); break; } } }; const mediaAreas = story.mediaAreas; return (
{mediaAreas?.map((mediaArea, i) => { switch (mediaArea.type) { case 'geoPoint': case 'venue': case 'channelPost': case 'url': { const isShiny = isActive && (mediaArea.type !== 'channelPost'); return (
handleMediaAreaClick(mediaArea)} /> ); } case 'suggestedReaction': return ( ); default: return undefined; } })}
); }; function prepareStyle(mediaArea: ApiMediaArea) { const { x, y, width, height, rotation, radius, } = mediaArea.coordinates; return buildStyle( `left: ${x}%`, `top: ${y}%`, `width: ${width}%`, `height: ${height}%`, `transform: rotate(${rotation}deg) translate(-50%, -50%)`, Boolean(radius) && `border-radius: ${radius}%`, ); } export default memo(MediaAreaOverlay);