From 6619cccd3e3fb0fe21bfc0c31b93217daa7377d2 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 10 Feb 2026 18:56:14 +0400 Subject: [PATCH] Allow sending videos as files. --- Telegram/Resources/langs/lang.strings | 4 ++ .../SourceFiles/boxes/edit_caption_box.cpp | 4 +- Telegram/SourceFiles/boxes/send_files_box.cpp | 51 ++++++++++--------- .../SourceFiles/history/history_drag_area.cpp | 15 ++++++ .../SourceFiles/storage/localimageloader.cpp | 32 ++++++------ .../storage/storage_media_prepare.cpp | 9 ++++ .../storage/storage_media_prepare.h | 1 + .../ui/chat/attach/attach_prepare.cpp | 10 ++-- 8 files changed, 84 insertions(+), 42 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index f3d0e5486a..14f0f8d5b4 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -5116,6 +5116,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_send_grouped" = "Group items"; "lng_send_compressed_one" = "Compress the image"; "lng_send_compressed" = "Compress images"; +"lng_send_as_documents_one" = "Send as a document"; +"lng_send_as_documents" = "Send as documents"; "lng_send_media_invalid_files" = "Sorry, no valid files found."; "lng_send_image" = "Send an image"; "lng_send_file" = "Send as a file"; @@ -5349,10 +5351,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_drag_images_here" = "Drop images here"; "lng_drag_photos_here" = "Drop photos here"; "lng_drag_files_here" = "Drop files here"; +"lng_drag_media_here" = "Drop photos and videos"; "lng_drag_to_send_quick" = "to send them in a quick way"; "lng_drag_to_send_no_compression" = "to send them without compression"; "lng_drag_to_send_files" = "to send them as documents"; +"lng_drag_to_send_media" = "to send them as media files"; "lng_selected_clear" = "Cancel"; "lng_selected_delete" = "Delete"; diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp index cf4ae2ddcb..32d01b297d 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp @@ -841,7 +841,9 @@ void EditCaptionBox::setupDragArea() { auto computeState = [=](const QMimeData *data) { using DragState = Storage::MimeDataState; const auto state = Storage::ComputeMimeDataState(data); - return (state == DragState::PhotoFiles || state == DragState::Image) + return (state == DragState::PhotoFiles + || state == DragState::Image + || state == DragState::MediaFiles) ? (_asFile ? DragState::Files : DragState::Image) : state; }; diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index 769cfb4031..f3dd804918 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -264,14 +264,16 @@ SendFilesBox::Block::Block( }); _preview.reset(preview); } else { - const auto media = Ui::SingleMediaPreview::Create( - parent, - st, - gifPaused, - first, - [=](Ui::AttachActionType type) { - return actionAllowed((*_items)[from], type); - }); + const auto media = way.sendImagesAsPhotos() + ? Ui::SingleMediaPreview::Create( + parent, + st, + gifPaused, + first, + [=](Ui::AttachActionType type) { + return actionAllowed((*_items)[from], type); + }) + : nullptr; if (media) { _isSingleMedia = true; _preview.reset(media); @@ -633,7 +635,9 @@ void SendFilesBox::setupDragArea() { auto computeState = [=](const QMimeData *data) { using DragState = Storage::MimeDataState; const auto state = Storage::ComputeMimeDataState(data); - return (state == DragState::PhotoFiles || state == DragState::Image) + return (state == DragState::PhotoFiles + || state == DragState::Image + || state == DragState::MediaFiles) ? (_sendWay.current().sendImagesAsPhotos() ? DragState::Image : DragState::Files) @@ -973,11 +977,11 @@ void SendFilesBox::initSendWay() { const auto was = hidden(); updateCaptionPlaceholder(); updateEmojiPanelGeometry(); - for (auto &block : _blocks) { - block.setSendWay(value); - } - refreshButtons(); - refreshPriceTag(); + applyBlockChanges(); + generatePreviewFrom(0); + _inner->resizeToWidth(st::boxWideWidth); + refreshControls(); + captionResized(); if (was != hidden()) { updateBoxSize(); updateControlsGeometry(); @@ -1296,15 +1300,15 @@ void SendFilesBox::setupSendWayControls() { _st.files.check); _sendImagesAsPhotos.create( this, - tr::lng_send_compressed(tr::now), - _sendWay.current().sendImagesAsPhotos(), + tr::lng_send_as_documents(tr::now), + !_sendWay.current().sendImagesAsPhotos(), _st.files.checkbox, _st.files.check); _sendWay.changes( ) | rpl::on_next([=](SendFilesWay value) { _groupFiles->setChecked(value.groupFiles()); - _sendImagesAsPhotos->setChecked(value.sendImagesAsPhotos()); + _sendImagesAsPhotos->setChecked(!value.sendImagesAsPhotos()); }, lifetime()); _groupFiles->checkedChanges( @@ -1326,10 +1330,10 @@ void SendFilesBox::setupSendWayControls() { _sendImagesAsPhotos->checkedChanges( ) | rpl::on_next([=](bool checked) { auto sendWay = _sendWay.current(); - if (sendWay.sendImagesAsPhotos() == checked) { + if (sendWay.sendImagesAsPhotos() == !checked) { return; } - sendWay.setSendImagesAsPhotos(checked); + sendWay.setSendImagesAsPhotos(!checked); if (checkWithWay(sendWay)) { _sendWay = sendWay; } else { @@ -1349,9 +1353,10 @@ void SendFilesBox::setupSendWayControls() { rpl::combine( _groupFiles->checkedValue(), _sendImagesAsPhotos->checkedValue() - ) | rpl::on_next([=](bool groupFiles, bool asPhoto) { + ) | rpl::on_next([=](bool groupFiles, bool asDocuments) { _wayRemember->setVisible( - (groupFiles != groupFilesFirst) || (asPhoto != asPhotosFirst)); + (groupFiles != groupFilesFirst) + || ((!asDocuments) != asPhotosFirst)); captionResized(); }, lifetime()); @@ -1388,8 +1393,8 @@ void SendFilesBox::updateSendWayControls() { _sendImagesAsPhotos->setVisible( _list.hasSendImagesAsPhotosOption(onlyOne)); _sendImagesAsPhotos->setText((_list.files.size() > 1) - ? tr::lng_send_compressed(tr::now) - : tr::lng_send_compressed_one(tr::now)); + ? tr::lng_send_as_documents(tr::now) + : tr::lng_send_as_documents_one(tr::now)); _hintLabel->setVisible( _show->session().settings().photoEditorHintShown() diff --git a/Telegram/SourceFiles/history/history_drag_area.cpp b/Telegram/SourceFiles/history/history_drag_area.cpp index f407c573d2..cbfd5e74d2 100644 --- a/Telegram/SourceFiles/history/history_drag_area.cpp +++ b/Telegram/SourceFiles/history/history_drag_area.cpp @@ -93,6 +93,7 @@ DragArea::Areas DragArea::SetupDragAreaToContainer( moveToTop(attachDragDocument); break; case DragState::PhotoFiles: + case DragState::MediaFiles: attachDragDocument->resize( width() - horizontalMargins, (height() - verticalMargins) / 2); @@ -147,6 +148,20 @@ DragArea::Areas DragArea::SetupDragAreaToContainer( attachDragDocument->otherEnter(); attachDragPhoto->otherEnter(); break; + case DragState::MediaFiles: + attachDragDocument->setText( + tr::lng_drag_files_here(tr::now), + hideSubtext + ? QString() + : tr::lng_drag_to_send_files(tr::now)); + attachDragPhoto->setText( + tr::lng_drag_media_here(tr::now), + hideSubtext + ? QString() + : tr::lng_drag_to_send_media(tr::now)); + attachDragDocument->otherEnter(); + attachDragPhoto->otherEnter(); + break; case DragState::Image: attachDragPhoto->setText( tr::lng_drag_images_here(tr::now), diff --git a/Telegram/SourceFiles/storage/localimageloader.cpp b/Telegram/SourceFiles/storage/localimageloader.cpp index e2885751fa..8c143c2a10 100644 --- a/Telegram/SourceFiles/storage/localimageloader.cpp +++ b/Telegram/SourceFiles/storage/localimageloader.cpp @@ -887,22 +887,24 @@ void FileLoadTask::process(Args &&args) { isVideo = true; auto coverWidth = video->thumbnail.width(); auto coverHeight = video->thumbnail.height(); - if (video->isGifv && !_album) { - attributes.push_back(MTP_documentAttributeAnimated()); + if (!_forceFile) { + if (video->isGifv && !_album) { + attributes.push_back(MTP_documentAttributeAnimated()); + } + auto flags = MTPDdocumentAttributeVideo::Flags(0); + if (video->supportsStreaming) { + flags |= MTPDdocumentAttributeVideo::Flag::f_supports_streaming; + } + const auto realSeconds = video->duration / 1000.; + attributes.push_back(MTP_documentAttributeVideo( + MTP_flags(flags), + MTP_double(realSeconds), + MTP_int(coverWidth), + MTP_int(coverHeight), + MTPint(), + MTPdouble(), + MTPstring())); } - auto flags = MTPDdocumentAttributeVideo::Flags(0); - if (video->supportsStreaming) { - flags |= MTPDdocumentAttributeVideo::Flag::f_supports_streaming; - } - const auto realSeconds = video->duration / 1000.; - attributes.push_back(MTP_documentAttributeVideo( - MTP_flags(flags), - MTP_double(realSeconds), - MTP_int(coverWidth), - MTP_int(coverHeight), - MTPint(), // preload_prefix_size - MTPdouble(), // video_start_ts - MTPstring())); // video_codec if (args.generateGoodThumbnail) { goodThumbnail = video->thumbnail; diff --git a/Telegram/SourceFiles/storage/storage_media_prepare.cpp b/Telegram/SourceFiles/storage/storage_media_prepare.cpp index 588d901440..dfb03616e3 100644 --- a/Telegram/SourceFiles/storage/storage_media_prepare.cpp +++ b/Telegram/SourceFiles/storage/storage_media_prepare.cpp @@ -133,6 +133,7 @@ MimeDataState ComputeMimeDataState(const QMimeData *data) { } auto allAreSmallImages = true; + auto allAreMedia = true; for (const auto &url : urls) { if (!url.isLocalFile()) { return MimeDataState::None; @@ -162,9 +163,17 @@ MimeDataState ComputeMimeDataState(const QMimeData *data) { } } } + if (allAreMedia) { + const auto type = DetectNameType(file); + if (type != NameType::Image && type != NameType::Video) { + allAreMedia = false; + } + } } return allAreSmallImages ? MimeDataState::PhotoFiles + : allAreMedia + ? MimeDataState::MediaFiles : MimeDataState::Files; } diff --git a/Telegram/SourceFiles/storage/storage_media_prepare.h b/Telegram/SourceFiles/storage/storage_media_prepare.h index d806fa47d3..15b94c904e 100644 --- a/Telegram/SourceFiles/storage/storage_media_prepare.h +++ b/Telegram/SourceFiles/storage/storage_media_prepare.h @@ -27,6 +27,7 @@ enum class MimeDataState { None, Files, PhotoFiles, + MediaFiles, //PremiumFile, Image, }; diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp index fb968607b3..3cdae65132 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp @@ -235,9 +235,13 @@ bool PreparedList::hasGroupOption(bool slowmode) const { bool PreparedList::hasSendImagesAsPhotosOption(bool slowmode) const { using Type = PreparedFile::Type; - return slowmode - ? ((files.size() == 1) && (files.front().type == Type::Photo)) - : ranges::contains(files, Type::Photo, &PreparedFile::type); + if (slowmode) { + const auto t = files.front().type; + return (files.size() == 1) + && (t == Type::Photo || t == Type::Video); + } + return ranges::contains(files, Type::Photo, &PreparedFile::type) + || ranges::contains(files, Type::Video, &PreparedFile::type); } bool PreparedList::canHaveEditorHintLabel() const {