From e367d82c6cf0bd1e950e627d5d5e5f0baa57c44f Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Mon, 14 Aug 2023 11:17:38 +0200 Subject: [PATCH] Video: Notify user on unsupported formats (#3706) --- src/api/gramjs/apiBuilders/messages.ts | 6 -- src/api/gramjs/methods/client.ts | 8 +-- src/api/types/misc.ts | 2 +- src/components/main/Notifications.tsx | 3 +- src/components/mediaViewer/VideoPlayer.tsx | 17 ++--- .../composer/helpers/buildAttachment.ts | 13 ++-- src/components/middle/message/Video.tsx | 11 ++-- .../middle/message/_message-content.scss | 7 +++ src/config.ts | 3 +- src/global/actions/api/initial.ts | 3 +- src/global/types.ts | 1 + src/hooks/media/useUnsupportedMedia.ts | 63 +++++++++++++++++++ src/util/fallbackLangPack.ts | 2 + src/util/files.ts | 46 +++++++------- src/util/windowEnvironment.ts | 12 ---- 15 files changed, 129 insertions(+), 68 deletions(-) create mode 100644 src/hooks/media/useUnsupportedMedia.ts diff --git a/src/api/gramjs/apiBuilders/messages.ts b/src/api/gramjs/apiBuilders/messages.ts index ec4dcafc1..73dcb2359 100644 --- a/src/api/gramjs/apiBuilders/messages.ts +++ b/src/api/gramjs/apiBuilders/messages.ts @@ -48,7 +48,6 @@ import { SUPPORTED_AUDIO_CONTENT_TYPES, SUPPORTED_IMAGE_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES, - VIDEO_MOV_TYPE, VIDEO_WEBM_TYPE, } from '../../../config'; import { pick } from '../../../util/iteratees'; @@ -484,11 +483,6 @@ export function buildVideoFromDocument(document: GramJs.Document, isSpoiler?: bo return undefined; } - // eslint-disable-next-line no-restricted-globals - if (mimeType === VIDEO_MOV_TYPE && !(self as any).isMovSupported) { - return undefined; - } - const videoAttr = attributes .find((a: any): a is GramJs.DocumentAttributeVideo => a instanceof GramJs.DocumentAttributeVideo); diff --git a/src/api/gramjs/methods/client.ts b/src/api/gramjs/methods/client.ts index 64623be78..4e4d86dfe 100644 --- a/src/api/gramjs/methods/client.ts +++ b/src/api/gramjs/methods/client.ts @@ -14,7 +14,7 @@ import type { } from '../../types'; import { - DEBUG, DEBUG_GRAMJS, UPLOAD_WORKERS, IS_TEST, SUPPORTED_VIDEO_CONTENT_TYPES, VIDEO_MOV_TYPE, + DEBUG, DEBUG_GRAMJS, UPLOAD_WORKERS, IS_TEST, } from '../../../config'; import { onRequestPhoneNumber, onRequestCode, onRequestPassword, onRequestRegistration, @@ -64,16 +64,12 @@ export async function init(_onUpdate: OnApiUpdate, initialArgs: ApiInitialArgs) onUpdate = _onUpdate; const { - userAgent, platform, sessionData, isTest, isMovSupported, isWebmSupported, maxBufferSize, webAuthToken, dcId, + userAgent, platform, sessionData, isTest, isWebmSupported, maxBufferSize, webAuthToken, dcId, mockScenario, shouldForceHttpTransport, shouldAllowHttpTransport, shouldDebugExportedSenders, } = initialArgs; const session = new sessions.CallbackSession(sessionData, onSessionUpdate); - // eslint-disable-next-line no-restricted-globals - (self as any).isMovSupported = isMovSupported; - // Hacky way to update this set inside GramJS worker - if (isMovSupported) SUPPORTED_VIDEO_CONTENT_TYPES.add(VIDEO_MOV_TYPE); // eslint-disable-next-line no-restricted-globals (self as any).isWebmSupported = isWebmSupported; // eslint-disable-next-line no-restricted-globals diff --git a/src/api/types/misc.ts b/src/api/types/misc.ts index 80b80f567..13773a736 100644 --- a/src/api/types/misc.ts +++ b/src/api/types/misc.ts @@ -7,7 +7,6 @@ export interface ApiInitialArgs { platform?: string; sessionData?: ApiSessionData; isTest?: boolean; - isMovSupported?: boolean; isWebmSupported?: boolean; maxBufferSize?: number; webAuthToken?: string; @@ -112,6 +111,7 @@ export type ApiNotification = { actionText?: string; action?: CallbackAction; className?: string; + duration?: number; }; export type ApiError = { diff --git a/src/components/main/Notifications.tsx b/src/components/main/Notifications.tsx index 637f090f1..f6d012e14 100644 --- a/src/components/main/Notifications.tsx +++ b/src/components/main/Notifications.tsx @@ -24,13 +24,14 @@ const Notifications: FC = ({ notifications }) => { return (
{notifications.map(({ - message, className, localId, action, actionText, title, + message, className, localId, action, actionText, title, duration, }) => ( dismissNotification({ localId })} diff --git a/src/components/mediaViewer/VideoPlayer.tsx b/src/components/mediaViewer/VideoPlayer.tsx index 075d9263b..932f362e1 100644 --- a/src/components/mediaViewer/VideoPlayer.tsx +++ b/src/components/mediaViewer/VideoPlayer.tsx @@ -21,6 +21,7 @@ import useAppLayout from '../../hooks/useAppLayout'; import useCurrentTimeSignal from './hooks/useCurrentTimeSignal'; import useControlsSignal from './hooks/useControlsSignal'; import useVideoWaitingSignal from './hooks/useVideoWaitingSignal'; +import useUnsupportedMedia from '../../hooks/media/useUnsupportedMedia'; import Button from '../ui/Button'; import ProgressSpinner from '../ui/ProgressSpinner'; @@ -120,22 +121,23 @@ const VideoPlayer: FC = ({ const { isReady, isBuffered, bufferedRanges, bufferingHandlers, bufferedProgress, } = useBuffering(); + const isUnsupported = useUnsupportedMedia(videoRef, undefined, !url); const { shouldRender: shouldRenderSpinner, transitionClassNames: spinnerClassNames, - } = useShowTransition(!isBuffered, undefined, undefined, 'slow'); + } = useShowTransition(!isBuffered && !isUnsupported, undefined, undefined, 'slow'); const { shouldRender: shouldRenderPlayButton, transitionClassNames: playButtonClassNames, - } = useShowTransition(IS_IOS && !isPlaying && !shouldRenderSpinner, undefined, undefined, 'slow'); + } = useShowTransition(IS_IOS && !isPlaying && !shouldRenderSpinner && !isUnsupported, undefined, undefined, 'slow'); useEffect(() => { lockControls(shouldRenderSpinner); }, [lockControls, shouldRenderSpinner]); useEffect(() => { - if (noPlay || !isMediaViewerOpen) { + if (noPlay || !isMediaViewerOpen || isUnsupported) { videoRef.current!.pause(); } else if (url && !IS_TOUCH_ENV) { // Chrome does not automatically start playing when `url` becomes available (even with `autoPlay`), @@ -143,7 +145,7 @@ const VideoPlayer: FC = ({ // so we need to use `autoPlay` instead to allow pre-buffering. safePlay(videoRef.current!); } - }, [noPlay, isMediaViewerOpen, url, setMediaViewerMuted]); + }, [noPlay, isMediaViewerOpen, url, setMediaViewerMuted, isUnsupported]); useEffect(() => { videoRef.current!.volume = volume; @@ -307,9 +309,8 @@ const VideoPlayer: FC = ({ bufferingHandlers.onPause(e); }} onTimeUpdate={handleTimeUpdate} - > - {url && } - + src={url} + />
{shouldRenderPlayButton && (