MediaViewer Apply new breakpoints and fixed import

This commit is contained in:
Akmal Isomadinov 2023-12-06 16:47:05 +05:00
parent cc2ef4e21a
commit b0a57770e1
16 changed files with 115 additions and 54 deletions

View File

@ -1,4 +1,3 @@
import { isMobile } from "react-device-detect";
import React, { import React, {
useState, useState,
useCallback, useCallback,
@ -7,25 +6,29 @@ import React, {
useRef, useRef,
} from "react"; } from "react";
import ViewerWrapper from "./sub-components/ViewerWrapper"; import {
isMobile as isMobileUtils,
isTablet,
} from "@docspace/components/utils/device";
import { FileStatus } from "../../constants";
import { getFileExtension } from "../../utils";
import { checkDialogsOpen } from "../../utils/checkDialogsOpen";
import { MediaViewerProps } from "./MediaViewer.props";
import { FileStatus } from "@docspace/common/constants";
import { import {
isNullOrUndefined, isNullOrUndefined,
KeyboardEventKeys, KeyboardEventKeys,
mapSupplied, mapSupplied,
mediaTypes, mediaTypes,
} from "./helpers"; } from "./helpers";
import { getFileExtension } from "@docspace/common/utils";
import { import {
getDesktopMediaContextModel, getDesktopMediaContextModel,
getMobileMediaContextModel, getMobileMediaContextModel,
getPDFContextModel, getPDFContextModel,
} from "./helpers/contextModel"; } from "./helpers/contextModel";
import ViewerWrapper from "./sub-components/ViewerWrapper";
import { checkDialogsOpen } from "../../utils/checkDialogsOpen"; import type { MediaViewerProps } from "./MediaViewer.props";
function MediaViewer({ function MediaViewer({
playlistPos, playlistPos,
@ -244,6 +247,8 @@ function MediaViewer({
}); });
} }
const isMobile = isMobileUtils() || isTablet();
return isMobile return isMobile
? model ? model
: isImage && !isMobile : isImage && !isMobile

View File

@ -1,6 +1,6 @@
import { Dispatch, SetStateAction } from "react"; import type { Dispatch, SetStateAction } from "react";
import { getCustomToolbar } from "../../helpers/getCustomToolbar"; import { getCustomToolbar } from "../../helpers/getCustomToolbar";
import { ContextMenuModel } from "../../types"; import type { ContextMenuModel, DevicesType } from "../../types";
interface ImageViewerProps { interface ImageViewerProps {
src?: string; src?: string;
@ -14,6 +14,7 @@ interface ImageViewerProps {
panelVisible: boolean; panelVisible: boolean;
mobileDetails: JSX.Element; mobileDetails: JSX.Element;
toolbar: ReturnType<typeof getCustomToolbar>; toolbar: ReturnType<typeof getCustomToolbar>;
devices: DevicesType;
onPrev: VoidFunction; onPrev: VoidFunction;
onNext: VoidFunction; onNext: VoidFunction;

View File

@ -1,5 +1,5 @@
import { useGesture } from "@use-gesture/react"; import { useGesture } from "@use-gesture/react";
import { isMobile, isDesktop } from "react-device-detect"; import { isDesktop as isDesktopDeviceDetect } from "react-device-detect";
import { useSpring, config } from "@react-spring/web"; import { useSpring, config } from "@react-spring/web";
import React, { SyntheticEvent, useEffect, useRef, useState } from "react"; import React, { SyntheticEvent, useEffect, useRef, useState } from "react";
@ -55,6 +55,7 @@ function ImageViewer({
isTiff, isTiff,
contextModel, contextModel,
errorTitle, errorTitle,
devices,
}: ImageViewerProps) { }: ImageViewerProps) {
const imgRef = useRef<HTMLImageElement>(null); const imgRef = useRef<HTMLImageElement>(null);
const imgWrapperRef = useRef<HTMLDivElement>(null); const imgWrapperRef = useRef<HTMLDivElement>(null);
@ -84,6 +85,8 @@ function ImageViewer({
opacity: 1, opacity: 1,
})); }));
const { isMobile, isDesktop } = devices;
useEffect(() => { useEffect(() => {
unmountRef.current = false; unmountRef.current = false;
@ -846,10 +849,15 @@ function ImageViewer({
}, },
onClick: ({ pinching, event }) => { onClick: ({ pinching, event }) => {
if (isDesktop && event.target === imgWrapperRef.current) if (isDesktopDeviceDetect && event.target === imgWrapperRef.current)
return onMask(); return onMask();
if (!imgRef.current || !containerRef.current || pinching || isDesktop) if (
!imgRef.current ||
!containerRef.current ||
pinching ||
isDesktopDeviceDetect
)
return; return;
const time = new Date().getTime(); const time = new Date().getTime();
@ -1030,7 +1038,7 @@ function ImageViewer({
</ImageWrapper> </ImageWrapper>
</ImageViewerContainer> </ImageViewerContainer>
{isDesktop && panelVisible && !isError && ( {isDesktop && !isMobile && panelVisible && !isError && (
<ImageViewerToolbar <ImageViewerToolbar
ref={toolbarRef} ref={toolbarRef}
toolbar={toolbar} toolbar={toolbar}

View File

@ -1,5 +1,6 @@
import { Dispatch, SetStateAction } from "react"; import type { Dispatch, SetStateAction } from "react";
import { getPDFToolbar } from "./../../helpers/getCustomToolbar"; import { getPDFToolbar } from "./../../helpers/getCustomToolbar";
import type { DevicesType } from "../../types";
interface PDFViewerProps { interface PDFViewerProps {
src: string; src: string;
title: string; title: string;
@ -9,6 +10,7 @@ interface PDFViewerProps {
isLastImage: boolean; isLastImage: boolean;
isFistImage: boolean; isFistImage: boolean;
devices: DevicesType;
onMask: VoidFunction; onMask: VoidFunction;
generateContextMenu: ( generateContextMenu: (

View File

@ -3,6 +3,7 @@ interface PlayerMessageErrorProps {
errorTitle: string; errorTitle: string;
model: ContextMenuModel[]; model: ContextMenuModel[];
onMaskClick: VoidFunction; onMaskClick: VoidFunction;
isMobile: boolean;
} }
export default PlayerMessageErrorProps; export default PlayerMessageErrorProps;

View File

@ -1,5 +1,4 @@
import React from "react"; import React from "react";
import { isMobile } from "react-device-detect";
import { ReactSVG } from "react-svg"; import { ReactSVG } from "react-svg";
import Text from "@docspace/components/text"; import Text from "@docspace/components/text";
@ -11,8 +10,9 @@ import {
import { isSeparator } from "../../helpers"; import { isSeparator } from "../../helpers";
function PlayerMessageError({ function PlayerMessageError({
errorTitle,
model, model,
isMobile,
errorTitle,
onMaskClick, onMaskClick,
}: PlayerMessageErrorProps) { }: PlayerMessageErrorProps) {
const items = !isMobile const items = !isMobile

View File

@ -28,12 +28,10 @@ function PlayerSpeedControl({
const timerRef = useRef<NodeJS.Timeout>(); const timerRef = useRef<NodeJS.Timeout>();
const [currentIndexSpeed, setCurrentIndexSpeed] = useState<number>( const [currentIndexSpeed, setCurrentIndexSpeed] =
DefaultIndexSpeed useState<number>(DefaultIndexSpeed);
); const [isOpenSpeedContextMenu, setIsOpenSpeedContextMenu] =
const [isOpenSpeedContextMenu, setIsOpenSpeedContextMenu] = useState<boolean>( useState<boolean>(false);
false
);
const [speedToastVisible, setSpeedToastVisible] = useState<boolean>(false); const [speedToastVisible, setSpeedToastVisible] = useState<boolean>(false);
useEffect(() => { useEffect(() => {

View File

@ -1,6 +1,7 @@
import { isMobile } from "react-device-detect";
import styled, { css } from "styled-components"; import styled, { css } from "styled-components";
import { tablet } from "@docspace/components/utils/device";
export const HoverProgress = styled.div` export const HoverProgress = styled.div`
display: none; display: none;
position: absolute; position: absolute;
@ -177,5 +178,7 @@ export const PlayerTimelineWrapper = styled.div`
} }
} }
${isMobile && mobileCss} @media ${tablet} {
${mobileCss}
}
`; `;

View File

@ -1,7 +1,7 @@
import { tablet } from "@docspace/components/utils/device";
import { isMobile } from "react-device-detect";
import styled, { css } from "styled-components"; import styled, { css } from "styled-components";
import { tablet } from "@docspace/components/utils/device";
export const PlayerVolumeControlWrapper = styled.div` export const PlayerVolumeControlWrapper = styled.div`
display: flex; display: flex;
align-items: center; align-items: center;
@ -143,5 +143,7 @@ export const VolumeWrapper = styled.div`
} }
} }
${isMobile && mobilecss} @media ${tablet} {
${mobilecss}
}
`; `;

View File

@ -32,6 +32,8 @@ interface ViewerProps {
bottom?: string bottom?: string
) => JSX.Element; ) => JSX.Element;
onSetSelectionFile: VoidFunction; onSetSelectionFile: VoidFunction;
currentDeviceType?: string;
} }
export default ViewerProps; export default ViewerProps;

View File

@ -1,7 +1,14 @@
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import { isMobile } from "react-device-detect"; import { inject, observer } from "mobx-react";
import React, { useRef, useState, useEffect, useCallback } from "react"; import React, {
useRef,
useState,
useEffect,
useCallback,
useMemo,
} from "react";
import { DeviceType } from "../../../../constants";
import { StyledViewerContainer } from "../../StyledComponents"; import { StyledViewerContainer } from "../../StyledComponents";
import NextButton from "../NextButton"; import NextButton from "../NextButton";
@ -33,6 +40,19 @@ function Viewer(props: ViewerProps) {
const contextMenuRef = useRef<{ show: (e: any) => void }>(null); const contextMenuRef = useRef<{ show: (e: any) => void }>(null);
const [isFullscreen, setIsFullScreen] = useState<boolean>(false); const [isFullscreen, setIsFullScreen] = useState<boolean>(false);
const devices = useMemo(
() => ({
isMobileOnly: props.currentDeviceType === DeviceType.mobile,
isMobile:
props.currentDeviceType === DeviceType.tablet ||
props.currentDeviceType === DeviceType.mobile,
isDesktop: props.currentDeviceType === DeviceType.desktop,
}),
[props.currentDeviceType]
);
const { isMobile } = devices;
useEffect(() => { useEffect(() => {
document.body.appendChild(containerRef.current); document.body.appendChild(containerRef.current);
containerRef.current.style.direction = "ltr"; containerRef.current.style.direction = "ltr";
@ -61,7 +81,7 @@ function Viewer(props: ViewerProps) {
clearTimeout(timerIDRef.current); clearTimeout(timerIDRef.current);
setPanelVisible(true); setPanelVisible(true);
}; };
}, [setImageTimer, setPanelVisible]); }, [setImageTimer, setPanelVisible, isMobile]);
const resetToolbarVisibleTimer = () => { const resetToolbarVisibleTimer = () => {
if (panelToolbarRef.current) return; if (panelToolbarRef.current) return;
@ -210,6 +230,7 @@ function Viewer(props: ViewerProps) {
resetToolbarVisibleTimer={resetToolbarVisibleTimer} resetToolbarVisibleTimer={resetToolbarVisibleTimer}
contextModel={props.contextModel} contextModel={props.contextModel}
errorTitle={props.errorTitle} errorTitle={props.errorTitle}
devices={devices}
/>, />,
containerRef.current containerRef.current
) )
@ -243,6 +264,7 @@ function Viewer(props: ViewerProps) {
removeToolbarVisibleTimer={removeToolbarVisibleTimer} removeToolbarVisibleTimer={removeToolbarVisibleTimer}
removePanelVisibleTimeout={removePanelVisibleTimeout} removePanelVisibleTimeout={removePanelVisibleTimeout}
restartToolbarVisibleTimer={restartToolbarVisibleTimer} restartToolbarVisibleTimer={restartToolbarVisibleTimer}
devices={devices}
/>, />,
containerRef.current containerRef.current
) )
@ -262,6 +284,7 @@ function Viewer(props: ViewerProps) {
isFistImage={!isNotFirstElement} isFistImage={!isNotFirstElement}
onPrev={props.onPrevClick} onPrev={props.onPrevClick}
onNext={props.onNextClick} onNext={props.onNextClick}
devices={devices}
/>, />,
containerRef.current containerRef.current
)} )}
@ -269,4 +292,8 @@ function Viewer(props: ViewerProps) {
); );
} }
export default Viewer; export default inject<any>(({ auth }) => {
const { currentDeviceType } = auth.settingsStore;
return { currentDeviceType };
})(observer(Viewer));

View File

@ -1,4 +1,4 @@
import { ContextMenuModel } from "../../types"; import type { ContextMenuModel, DevicesType } from "../../types";
interface ViewerPlayerProps { interface ViewerPlayerProps {
src?: string; src?: string;
@ -16,6 +16,7 @@ interface ViewerPlayerProps {
isOpenContextMenu: boolean; isOpenContextMenu: boolean;
mobileDetails: JSX.Element; mobileDetails: JSX.Element;
thumbnailSrc?: string; thumbnailSrc?: string;
devices: DevicesType;
onMask: VoidFunction; onMask: VoidFunction;
onPrev: VoidFunction; onPrev: VoidFunction;
onNext: VoidFunction; onNext: VoidFunction;

View File

@ -1,7 +1,8 @@
import { isMobile, isMobileOnly } from "react-device-detect"; import styled from "styled-components";
import styled, { css } from "styled-components";
import { animated } from "@react-spring/web"; import { animated } from "@react-spring/web";
import { tablet, mobile } from "@docspace/components/utils/device";
export const ContainerPlayer = styled.div<{ $isFullScreen: boolean }>` export const ContainerPlayer = styled.div<{ $isFullScreen: boolean }>`
position: fixed; position: fixed;
inset: 0; inset: 0;
@ -30,11 +31,6 @@ export const VideoWrapper = styled(animated.div)<{ $visible: boolean }>`
} }
`; `;
const StyledMobilePlayerControls = css`
background-color: rgba(0, 0, 0, 0.8);
height: 80px;
`;
export const StyledPlayerControls = styled.div<{ $isShow: boolean }>` export const StyledPlayerControls = styled.div<{ $isShow: boolean }>`
position: fixed; position: fixed;
right: 0px; right: 0px;
@ -55,7 +51,10 @@ export const StyledPlayerControls = styled.div<{ $isShow: boolean }>`
rgba(0, 0, 0, 0.89) 100% rgba(0, 0, 0, 0.89) 100%
); );
${isMobile && StyledMobilePlayerControls} @media ${tablet} {
background-color: rgba(0, 0, 0, 0.8);
height: 80px;
}
`; `;
export const ControlContainer = styled.div` export const ControlContainer = styled.div`
@ -71,13 +70,12 @@ export const ControlContainer = styled.div`
justify-content: space-between; justify-content: space-between;
} }
${isMobile && @media ${tablet} {
css`
margin-top: 8px; margin-top: 8px;
.player_right-control { .player_right-control {
margin-right: -8px; margin-right: -8px;
} }
`} }
`; `;
export const PlayerControlsWrapper = styled.div` export const PlayerControlsWrapper = styled.div`
@ -85,13 +83,11 @@ export const PlayerControlsWrapper = styled.div`
width: 100%; width: 100%;
margin-top: 80px; margin-top: 80px;
${isMobile && @media ${tablet} {
css`
margin-top: 0px; margin-top: 0px;
`} }
${isMobileOnly && @media ${mobile} {
css`
padding: 0 15px; padding: 0 15px;
`} }
`; `;

View File

@ -1,7 +1,11 @@
import lodash from "lodash"; import lodash from "lodash";
import { useGesture } from "@use-gesture/react"; import { useGesture } from "@use-gesture/react";
import { useSpring, animated } from "@react-spring/web"; import { useSpring, animated } from "@react-spring/web";
import { isMobile, isDesktop, isIOS, isMobileOnly } from "react-device-detect"; import {
isDesktop as isDesktopDeviceDetect,
isIOS,
isMobileOnly,
} from "react-device-detect";
import React, { import React, {
useCallback, useCallback,
useEffect, useEffect,
@ -42,6 +46,7 @@ function ViewerPlayer({
isAudio, isAudio,
isVideo, isVideo,
isError, isError,
devices,
audioIcon, audioIcon,
errorTitle, errorTitle,
isLastImage, isLastImage,
@ -72,6 +77,8 @@ function ViewerPlayer({
const isDurationInfinityRef = useRef<boolean>(false); const isDurationInfinityRef = useRef<boolean>(false);
const { isDesktop, isMobile } = devices;
const [isLoading, setIsLoading] = useState<boolean>(false); const [isLoading, setIsLoading] = useState<boolean>(false);
const [isPlaying, setIsPlaying] = useState<boolean>(false); const [isPlaying, setIsPlaying] = useState<boolean>(false);
const [isWaiting, setIsWaiting] = useState<boolean>(false); const [isWaiting, setIsWaiting] = useState<boolean>(false);
@ -232,7 +239,8 @@ function ViewerPlayer({
}); });
}, },
onClick: ({ dragging, event }) => { onClick: ({ dragging, event }) => {
if (isDesktop && event.target === containerRef.current) return onMask(); if (isDesktopDeviceDetect && event.target === containerRef.current)
return onMask();
if ( if (
dragging || dragging ||
@ -385,7 +393,7 @@ function ViewerPlayer({
videoRef.current.play(); videoRef.current.play();
setIsPlaying(true); setIsPlaying(true);
} }
}, [isPlaying, isVideo]); }, [isPlaying, isVideo, isMobile]);
const handleBigPlayButtonClick = () => { const handleBigPlayButtonClick = () => {
togglePlay(); togglePlay();
@ -612,6 +620,7 @@ function ViewerPlayer({
model={model} model={model}
onMaskClick={onMask} onMaskClick={onMask}
errorTitle={errorTitle} errorTitle={errorTitle}
isMobile={isMobile}
/> />
) : ( ) : (
<StyledPlayerControls <StyledPlayerControls

View File

@ -1,5 +1,6 @@
import React, { useMemo, memo, useCallback } from "react";
import equal from "fast-deep-equal/react"; import equal from "fast-deep-equal/react";
import { useTheme } from "styled-components";
import React, { useMemo, memo, useCallback } from "react";
import Viewer from "../Viewer"; import Viewer from "../Viewer";
import { isSeparator } from "../../helpers"; import { isSeparator } from "../../helpers";
@ -12,7 +13,6 @@ import { ContextMenuModel } from "../../types";
import { StyledDropDown } from "../StyledDropDown"; import { StyledDropDown } from "../StyledDropDown";
import { StyledDropDownItem } from "../StyledDropDownItem"; import { StyledDropDownItem } from "../StyledDropDownItem";
import ViewerWrapperProps from "./ViewerWrapper.props"; import ViewerWrapperProps from "./ViewerWrapper.props";
import { useTheme } from "styled-components";
function ViewerWrapper(props: ViewerWrapperProps) { function ViewerWrapper(props: ViewerWrapperProps) {
const { interfaceDirection } = useTheme(); const { interfaceDirection } = useTheme();

View File

@ -17,6 +17,12 @@ export type NumberOrString = number | string;
export type NullOrUndefined = null | undefined; export type NullOrUndefined = null | undefined;
export type DevicesType = {
isMobile: boolean;
isMobileOnly: boolean;
isDesktop: boolean;
};
export type PlaylistType = { export type PlaylistType = {
id: number; id: number;
canShare: boolean; canShare: boolean;