mirror of
https://github.com/danog/telegram-tt.git
synced 2025-01-22 05:11:55 +01:00
Video: Display .mov as document when playing not supported (#1455)
This commit is contained in:
parent
135db2345b
commit
2de5600602
@ -23,7 +23,14 @@ import {
|
||||
ApiInvoice,
|
||||
} from '../../types';
|
||||
|
||||
import { DELETED_COMMENTS_CHANNEL_ID, LOCAL_MESSAGE_ID_BASE, SERVICE_NOTIFICATIONS_USER_ID } from '../../../config';
|
||||
import {
|
||||
DELETED_COMMENTS_CHANNEL_ID,
|
||||
LOCAL_MESSAGE_ID_BASE,
|
||||
SERVICE_NOTIFICATIONS_USER_ID,
|
||||
SUPPORTED_IMAGE_CONTENT_TYPES,
|
||||
SUPPORTED_VIDEO_CONTENT_TYPES,
|
||||
VIDEO_MOV_TYPE,
|
||||
} from '../../../config';
|
||||
import { pick } from '../../../util/iteratees';
|
||||
import { getApiChatIdFromMtpPeer } from './chats';
|
||||
import { buildStickerFromDocument } from './symbols';
|
||||
@ -286,6 +293,11 @@ export function buildVideoFromDocument(document: GramJs.Document): ApiVideo | un
|
||||
id, mimeType, thumbs, size, attributes,
|
||||
} = document;
|
||||
|
||||
// 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);
|
||||
|
||||
@ -419,7 +431,7 @@ export function buildApiDocument(document: GramJs.TypeDocument): ApiDocument | u
|
||||
height: photoSize.h,
|
||||
};
|
||||
|
||||
if (mimeType.startsWith('image/')) {
|
||||
if (SUPPORTED_IMAGE_CONTENT_TYPES.has(mimeType)) {
|
||||
mediaType = 'photo';
|
||||
|
||||
const imageAttribute = attributes
|
||||
@ -432,7 +444,7 @@ export function buildApiDocument(document: GramJs.TypeDocument): ApiDocument | u
|
||||
height,
|
||||
};
|
||||
}
|
||||
} else if (mimeType.startsWith('video/')) {
|
||||
} else if (SUPPORTED_VIDEO_CONTENT_TYPES.has(mimeType)) {
|
||||
mediaType = 'video';
|
||||
}
|
||||
}
|
||||
|
@ -44,9 +44,14 @@ export async function init(_onUpdate: OnApiUpdate, initialArgs: ApiInitialArgs)
|
||||
|
||||
onUpdate = _onUpdate;
|
||||
|
||||
const { userAgent, platform, sessionData } = initialArgs;
|
||||
const {
|
||||
userAgent, platform, sessionData, isMovSupported,
|
||||
} = initialArgs;
|
||||
const session = new sessions.CallbackSession(sessionData, onSessionUpdate);
|
||||
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
(self as any).isMovSupported = isMovSupported;
|
||||
|
||||
client = new TelegramClient(
|
||||
session,
|
||||
process.env.TELEGRAM_T_API_ID,
|
||||
|
@ -18,7 +18,13 @@ import {
|
||||
ApiReportReason,
|
||||
} from '../../types';
|
||||
|
||||
import { ALL_FOLDER_ID, DEBUG, PINNED_MESSAGES_LIMIT } from '../../../config';
|
||||
import {
|
||||
ALL_FOLDER_ID,
|
||||
DEBUG,
|
||||
PINNED_MESSAGES_LIMIT,
|
||||
SUPPORTED_IMAGE_CONTENT_TYPES,
|
||||
SUPPORTED_VIDEO_CONTENT_TYPES,
|
||||
} from '../../../config';
|
||||
import { invokeRequest, uploadFile } from './client';
|
||||
import {
|
||||
buildApiMessage,
|
||||
@ -506,9 +512,11 @@ async function uploadMedia(localMessage: ApiMessage, attachment: ApiAttachment,
|
||||
|
||||
const attributes: GramJs.TypeDocumentAttribute[] = [new GramJs.DocumentAttributeFilename({ fileName: filename })];
|
||||
if (quick) {
|
||||
if (mimeType.startsWith('image/')) {
|
||||
if (SUPPORTED_IMAGE_CONTENT_TYPES.has(mimeType)) {
|
||||
return new GramJs.InputMediaUploadedPhoto({ file: inputFile });
|
||||
} else {
|
||||
}
|
||||
|
||||
if (SUPPORTED_VIDEO_CONTENT_TYPES.has(mimeType)) {
|
||||
const { width, height, duration } = quick;
|
||||
if (duration !== undefined) {
|
||||
attributes.push(new GramJs.DocumentAttributeVideo({
|
||||
|
@ -4,6 +4,7 @@ export interface ApiInitialArgs {
|
||||
userAgent: string;
|
||||
platform?: string;
|
||||
sessionData?: ApiSessionData;
|
||||
isMovSupported?: boolean;
|
||||
}
|
||||
|
||||
export interface ApiOnProgress {
|
||||
|
@ -13,12 +13,12 @@ import {
|
||||
MIN_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN,
|
||||
SAFE_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN,
|
||||
SAFE_SCREEN_WIDTH_FOR_CHAT_INFO,
|
||||
CONTENT_TYPES_FOR_QUICK_UPLOAD,
|
||||
ANIMATION_LEVEL_MAX,
|
||||
ANIMATION_END_DELAY,
|
||||
DARK_THEME_BG_COLOR,
|
||||
LIGHT_THEME_BG_COLOR,
|
||||
ANIMATION_LEVEL_MIN,
|
||||
SUPPORTED_IMAGE_CONTENT_TYPES,
|
||||
} from '../../config';
|
||||
import {
|
||||
IS_SINGLE_COLUMN_LAYOUT,
|
||||
@ -99,8 +99,8 @@ type DispatchProps = Pick<GlobalActions, (
|
||||
|
||||
const CLOSE_ANIMATION_DURATION = IS_SINGLE_COLUMN_LAYOUT ? 450 + ANIMATION_END_DELAY : undefined;
|
||||
|
||||
function canBeQuicklyUploaded(item: DataTransferItem) {
|
||||
return item.kind === 'file' && item.type && CONTENT_TYPES_FOR_QUICK_UPLOAD.has(item.type);
|
||||
function isImage(item: DataTransferItem) {
|
||||
return item.kind === 'file' && item.type && SUPPORTED_IMAGE_CONTENT_TYPES.has(item.type);
|
||||
}
|
||||
|
||||
const MiddleColumn: FC<StateProps & DispatchProps> = ({
|
||||
@ -228,7 +228,8 @@ const MiddleColumn: FC<StateProps & DispatchProps> = ({
|
||||
// Filter unnecessary element for drag and drop images in Firefox (https://github.com/Ajaxy/telegram-tt/issues/49)
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#image
|
||||
.filter((item) => item.type !== 'text/uri-list')
|
||||
.every(canBeQuicklyUploaded);
|
||||
// As of September 2021, native clients suggest "send quick, but compressed" only for images
|
||||
.every(isImage);
|
||||
|
||||
setDropAreaState(shouldDrawQuick ? DropAreaState.QuickFile : DropAreaState.Document);
|
||||
}, []);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { FC, memo, useCallback } from '../../../lib/teact/teact';
|
||||
|
||||
import { CONTENT_TYPES_FOR_QUICK_UPLOAD } from '../../../config';
|
||||
import { CONTENT_TYPES_WITH_PREVIEW } from '../../../config';
|
||||
import { IS_TOUCH_ENV } from '../../../util/environment';
|
||||
import { openSystemFilesDialog } from '../../../util/systemFilesDialog';
|
||||
import { IAllowedAttachmentOptions } from '../../../modules/helpers';
|
||||
@ -35,7 +35,7 @@ const AttachMenu: FC<OwnProps> = ({
|
||||
|
||||
const handleQuickSelect = useCallback(() => {
|
||||
openSystemFilesDialog(
|
||||
Array.from(CONTENT_TYPES_FOR_QUICK_UPLOAD).join(','),
|
||||
Array.from(CONTENT_TYPES_WITH_PREVIEW).join(','),
|
||||
(e) => handleFileSelect(e, true),
|
||||
);
|
||||
}, [handleFileSelect]);
|
||||
|
@ -4,7 +4,12 @@ import React, {
|
||||
|
||||
import { ApiAttachment, ApiChatMember, ApiUser } from '../../../api/types';
|
||||
|
||||
import { CONTENT_TYPES_FOR_QUICK_UPLOAD, EDITABLE_INPUT_MODAL_ID } from '../../../config';
|
||||
import {
|
||||
CONTENT_TYPES_WITH_PREVIEW,
|
||||
EDITABLE_INPUT_MODAL_ID,
|
||||
SUPPORTED_IMAGE_CONTENT_TYPES,
|
||||
SUPPORTED_VIDEO_CONTENT_TYPES,
|
||||
} from '../../../config';
|
||||
import { getFileExtension } from '../../common/helpers/documentInfo';
|
||||
import captureEscKeyListener from '../../../util/captureEscKeyListener';
|
||||
import usePrevious from '../../../hooks/usePrevious';
|
||||
@ -128,7 +133,7 @@ const AttachmentModal: FC<OwnProps> = ({
|
||||
if (files?.length) {
|
||||
const newFiles = isQuick
|
||||
? Array.from(files).filter((file) => {
|
||||
return file.type && CONTENT_TYPES_FOR_QUICK_UPLOAD.has(file.type);
|
||||
return file.type && CONTENT_TYPES_WITH_PREVIEW.has(file.type);
|
||||
})
|
||||
: Array.from(files);
|
||||
|
||||
@ -149,8 +154,8 @@ const AttachmentModal: FC<OwnProps> = ({
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const areAllPhotos = renderingAttachments.every((a) => a.mimeType.startsWith('image/'));
|
||||
const areAllVideos = renderingAttachments.every((a) => a.mimeType.startsWith('video/'));
|
||||
const areAllPhotos = renderingAttachments.every((a) => SUPPORTED_IMAGE_CONTENT_TYPES.has(a.mimeType));
|
||||
const areAllVideos = renderingAttachments.every((a) => SUPPORTED_VIDEO_CONTENT_TYPES.has(a.mimeType));
|
||||
const areAllAudios = renderingAttachments.every((a) => a.mimeType.startsWith('audio/'));
|
||||
|
||||
let title = '';
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { ApiAttachment } from '../../../../api/types';
|
||||
import { SUPPORTED_IMAGE_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES } from '../../../../config';
|
||||
import {
|
||||
preloadImage,
|
||||
preloadVideo,
|
||||
@ -17,7 +18,7 @@ export default async function buildAttachment(
|
||||
let quick;
|
||||
let previewBlobUrl;
|
||||
|
||||
if (mimeType.startsWith('image/')) {
|
||||
if (SUPPORTED_IMAGE_CONTENT_TYPES.has(mimeType)) {
|
||||
if (isQuick) {
|
||||
const img = await preloadImage(blobUrl);
|
||||
const { width, height } = img;
|
||||
@ -33,7 +34,7 @@ export default async function buildAttachment(
|
||||
} else {
|
||||
previewBlobUrl = blobUrl;
|
||||
}
|
||||
} else if (mimeType.startsWith('video/')) {
|
||||
} else if (SUPPORTED_VIDEO_CONTENT_TYPES.has(mimeType)) {
|
||||
const { videoWidth: width, videoHeight: height, duration } = await preloadVideo(blobUrl);
|
||||
quick = { width, height, duration };
|
||||
|
||||
|
@ -121,8 +121,19 @@ export const BASE_EMOJI_KEYWORD_LANG = 'en';
|
||||
export const MENU_TRANSITION_DURATION = 200;
|
||||
export const SLIDE_TRANSITION_DURATION = 450;
|
||||
|
||||
export const CONTENT_TYPES_FOR_QUICK_UPLOAD = new Set([
|
||||
'image/png', 'image/gif', 'image/jpeg', 'video/mp4', 'video/avi', 'video/quicktime',
|
||||
export const VIDEO_MOV_TYPE = 'video/quicktime';
|
||||
|
||||
export const SUPPORTED_IMAGE_CONTENT_TYPES = new Set([
|
||||
'image/png', 'image/gif', 'image/jpeg',
|
||||
]);
|
||||
|
||||
export const SUPPORTED_VIDEO_CONTENT_TYPES = new Set([
|
||||
'video/mp4', // video/quicktime added dynamically in environment.ts
|
||||
]);
|
||||
|
||||
export const CONTENT_TYPES_WITH_PREVIEW = new Set([
|
||||
...SUPPORTED_IMAGE_CONTENT_TYPES,
|
||||
...SUPPORTED_VIDEO_CONTENT_TYPES,
|
||||
]);
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
MEDIA_PROGRESSIVE_CACHE_NAME,
|
||||
IS_TEST,
|
||||
} from '../../../config';
|
||||
import { PLATFORM_ENV } from '../../../util/environment';
|
||||
import { IS_MOV_SUPPORTED, PLATFORM_ENV } from '../../../util/environment';
|
||||
import { unsubscribe } from '../../../util/notifications';
|
||||
import * as cacheApi from '../../../util/cacheApi';
|
||||
import { updateAppBadge } from '../../../util/appBadge';
|
||||
@ -37,6 +37,7 @@ addReducer('initApi', (global: GlobalState, actions) => {
|
||||
userAgent: navigator.userAgent,
|
||||
platform: PLATFORM_ENV,
|
||||
sessionData: loadStoredSession(),
|
||||
isMovSupported: IS_MOV_SUPPORTED,
|
||||
});
|
||||
})();
|
||||
});
|
||||
|
@ -4,6 +4,8 @@ import {
|
||||
MOBILE_SCREEN_LANDSCAPE_MAX_HEIGHT,
|
||||
MOBILE_SCREEN_LANDSCAPE_MAX_WIDTH,
|
||||
IS_TEST,
|
||||
SUPPORTED_VIDEO_CONTENT_TYPES,
|
||||
VIDEO_MOV_TYPE,
|
||||
} from '../config';
|
||||
|
||||
export * from './environmentWebp';
|
||||
@ -67,6 +69,14 @@ export const IS_CANVAS_FILTER_SUPPORTED = (
|
||||
);
|
||||
export const LAYERS_ANIMATION_NAME = IS_ANDROID ? 'slide-fade' : IS_IOS ? 'slide-layers' : 'push-slide';
|
||||
|
||||
const TEST_VIDEO = document.createElement('video');
|
||||
export const IS_MOV_SUPPORTED = Boolean(
|
||||
TEST_VIDEO.canPlayType(VIDEO_MOV_TYPE).replace('no', '')
|
||||
|| IS_IOS, // IOS reports '', but still plays .mov files
|
||||
);
|
||||
|
||||
if (IS_MOV_SUPPORTED) SUPPORTED_VIDEO_CONTENT_TYPES.add(VIDEO_MOV_TYPE);
|
||||
|
||||
export const DPR = window.devicePixelRatio || 1;
|
||||
|
||||
export const MASK_IMAGE_DISABLED = true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user