diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style index 08c133a9e..34f9811a0 100644 --- a/Telegram/SourceFiles/boxes/boxes.style +++ b/Telegram/SourceFiles/boxes/boxes.style @@ -484,11 +484,6 @@ autoDownloadTopDelta: 10px; autoDownloadTitlePosition: point(23px, 18px); autoDownloadTitleFont: font(15px semibold); -editTextArea: InputField(defaultInputField) { - textMargins: margins(1px, 26px, 1px, 4px); - heightMax: 276px; -} - confirmCaptionArea: InputField(defaultInputField) { textMargins: margins(1px, 26px, 1px, 4px); heightMax: 78px; diff --git a/Telegram/SourceFiles/boxes/connection_box.cpp b/Telegram/SourceFiles/boxes/connection_box.cpp index 722b110c3..2b369aeaa 100644 --- a/Telegram/SourceFiles/boxes/connection_box.cpp +++ b/Telegram/SourceFiles/boxes/connection_box.cpp @@ -269,10 +269,9 @@ void AutoDownloadBox::onSave() { bool enabledGroups = ((cAutoDownloadAudio() & dbiadNoGroups) && !(autoDownloadAudio & dbiadNoGroups)); cSetAutoDownloadAudio(autoDownloadAudio); if (enabledPrivate || enabledGroups) { - const DocumentsData &data(App::documentsData()); - for (DocumentsData::const_iterator i = data.cbegin(), e = data.cend(); i != e; ++i) { - if (i.value()->voice()) { - i.value()->automaticLoadSettingsChanged(); + for (auto document : App::documentsData()) { + if (document->voice()) { + document->automaticLoadSettingsChanged(); } } } @@ -284,10 +283,9 @@ void AutoDownloadBox::onSave() { bool enabledGroups = ((cAutoDownloadGif() & dbiadNoGroups) && !(autoDownloadGif & dbiadNoGroups)); cSetAutoDownloadGif(autoDownloadGif); if (enabledPrivate || enabledGroups) { - const DocumentsData &data(App::documentsData()); - for (DocumentsData::const_iterator i = data.cbegin(), e = data.cend(); i != e; ++i) { - if (i.value()->isAnimation()) { - i.value()->automaticLoadSettingsChanged(); + for (auto document : App::documentsData()) { + if (document->isAnimation()) { + document->automaticLoadSettingsChanged(); } } } diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index f18d428fc..5448882c1 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -450,46 +450,46 @@ void SendFilesBox::closeHook() { } } -EditCaptionBox::EditCaptionBox(QWidget*, HistoryItem *msg) -: _msgId(msg->fullId()) { +EditCaptionBox::EditCaptionBox(QWidget*, HistoryMedia *media, FullMsgId msgId) : _msgId(msgId) { + Expects(media->canEditCaption()); + QSize dimensions; ImagePtr image; QString caption; DocumentData *doc = nullptr; - if (auto media = msg->getMedia()) { - auto t = media->type(); - switch (t) { - case MediaTypeGif: { - _animated = true; - doc = static_cast(media)->getDocument(); - dimensions = doc->dimensions; - image = doc->thumb; - } break; - case MediaTypePhoto: { - _photo = true; - PhotoData *photo = static_cast(media)->photo(); - dimensions = QSize(photo->full->width(), photo->full->height()); - image = photo->full; - } break; + switch (media->type()) { + case MediaTypeGif: { + _animated = true; + doc = static_cast(media)->getDocument(); + dimensions = doc->dimensions; + image = doc->thumb; + } break; - case MediaTypeVideo: { - _animated = true; - doc = static_cast(media)->getDocument(); - dimensions = doc->dimensions; - image = doc->thumb; - } break; + case MediaTypePhoto: { + _photo = true; + auto photo = static_cast(media)->photo(); + dimensions = QSize(photo->full->width(), photo->full->height()); + image = photo->full; + } break; - case MediaTypeFile: - case MediaTypeMusicFile: - case MediaTypeVoiceFile: { - _doc = true; - doc = static_cast(media)->getDocument(); - image = doc->thumb; - } break; - } - caption = media->getCaption().text; + case MediaTypeVideo: { + _animated = true; + doc = static_cast(media)->getDocument(); + dimensions = doc->dimensions; + image = doc->thumb; + } break; + + case MediaTypeFile: + case MediaTypeMusicFile: + case MediaTypeVoiceFile: { + _doc = true; + doc = static_cast(media)->getDocument(); + image = doc->thumb; + } break; } + caption = media->getCaption().text; + if ((!_animated && (dimensions.isEmpty() || doc)) || image->isNull()) { _animated = false; if (image->isNull()) { @@ -563,17 +563,11 @@ EditCaptionBox::EditCaptionBox(QWidget*, HistoryItem *msg) _thumb = App::pixmapFromImageInPlace(_thumb.toImage().scaled(_thumbw * cIntRetinaFactor(), _thumbh * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); _thumb.setDevicePixelRatio(cRetinaFactor()); } - if (_animated || _photo || _doc) { - _field.create(this, st::confirmCaptionArea, lang(lng_photo_caption), caption); - _field->setMaxLength(MaxPhotoCaption); - _field->setCtrlEnterSubmit(Ui::CtrlEnterSubmit::Both); - } else { - auto original = msg->originalText(); - auto text = textApplyEntities(original.text, original.entities); - _field.create(this, st::editTextArea, lang(lng_photo_caption), text); -// _field->setMaxLength(MaxMessageSize); // entities can make text in input field larger but still valid - _field->setCtrlEnterSubmit(cCtrlEnter() ? Ui::CtrlEnterSubmit::CtrlEnter : Ui::CtrlEnterSubmit::Enter); - } + t_assert(_animated || _photo || _doc); + + _field.create(this, st::confirmCaptionArea, lang(lng_photo_caption), caption); + _field->setMaxLength(MaxPhotoCaption); + _field->setCtrlEnterSubmit(Ui::CtrlEnterSubmit::Both); } void EditCaptionBox::prepareGifPreview(DocumentData *document) { @@ -613,20 +607,6 @@ void EditCaptionBox::clipCallback(Media::Clip::Notification notification) { } } -bool EditCaptionBox::canEdit(HistoryItem *message) { - if (auto media = message->getMedia()) { - switch (media->type()) { - case MediaTypeGif: - case MediaTypePhoto: - case MediaTypeVideo: - case MediaTypeFile: - case MediaTypeMusicFile: - case MediaTypeVoiceFile: return true; - } - } - return false; -} - void EditCaptionBox::prepare() { addButton(lang(lng_settings_save), [this] { onSave(); }); addButton(lang(lng_cancel), [this] { closeBox(); }); diff --git a/Telegram/SourceFiles/boxes/send_files_box.h b/Telegram/SourceFiles/boxes/send_files_box.h index 0ed06f9cf..b5a894a8b 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.h +++ b/Telegram/SourceFiles/boxes/send_files_box.h @@ -115,8 +115,7 @@ class EditCaptionBox : public BoxContent, public RPCSender { Q_OBJECT public: - EditCaptionBox(QWidget*, HistoryItem *msg); - static bool canEdit(HistoryItem *message); + EditCaptionBox(QWidget*, HistoryMedia *media, FullMsgId msgId); public slots: void onCaptionResized(); diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 69052a8a2..2cfb69462 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -756,20 +756,19 @@ void HistoryItem::setId(MsgId newId) { bool HistoryItem::canEdit(const QDateTime &cur) const { auto messageToMyself = (_history->peer->id == AuthSession::CurrentUserPeerId()); auto messageTooOld = messageToMyself ? false : (date.secsTo(cur) >= Global::EditTimeLimit()); - if (id < 0 || messageTooOld) return false; + if (id < 0 || messageTooOld) { + return false; + } if (auto msg = toHistoryMessage()) { - if (msg->Has() || msg->Has()) return false; + if (msg->Has() || msg->Has()) { + return false; + } if (auto media = msg->getMedia()) { - auto type = media->type(); - if (type != MediaTypePhoto && - type != MediaTypeVideo && - type != MediaTypeFile && - type != MediaTypeGif && - type != MediaTypeMusicFile && - type != MediaTypeVoiceFile && - type != MediaTypeWebPage) { + if (media->canEditCaption()) { + return true; + } else if (media->type() != MediaTypeWebPage) { return false; } } @@ -785,8 +784,12 @@ bool HistoryItem::canEdit(const QDateTime &cur) const { bool HistoryItem::canDeleteForEveryone(const QDateTime &cur) const { auto messageToMyself = (_history->peer->id == AuthSession::CurrentUserPeerId()); auto messageTooOld = messageToMyself ? false : (date.secsTo(cur) >= Global::EditTimeLimit()); - if (id < 0 || messageToMyself || messageTooOld) return false; - if (history()->peer->isChannel()) return false; + if (id < 0 || messageToMyself || messageTooOld) { + return false; + } + if (history()->peer->isChannel()) { + return false; + } if (auto msg = toHistoryMessage()) { return !isPost() && out(); @@ -803,21 +806,31 @@ bool HistoryItem::unread() const { if (out()) { // Outgoing messages in converted chats are always read. - if (history()->peer->migrateTo()) return false; + if (history()->peer->migrateTo()) { + return false; + } if (id > 0) { - if (id < history()->outboxReadBefore) return false; + if (id < history()->outboxReadBefore) { + return false; + } if (auto user = history()->peer->asUser()) { - if (user->botInfo) return false; + if (user->botInfo) { + return false; + } } else if (auto channel = history()->peer->asChannel()) { - if (!channel->isMegagroup()) return false; + if (!channel->isMegagroup()) { + return false; + } } } return true; } if (id > 0) { - if (id < history()->inboxReadBefore) return false; + if (id < history()->inboxReadBefore) { + return false; + } return true; } return (_flags & MTPDmessage_ClientFlag::f_clientside_unread); @@ -867,11 +880,15 @@ void HistoryItem::setUnreadBarFreezed() { void HistoryItem::clipCallback(Media::Clip::Notification notification) { using namespace Media::Clip; - HistoryMedia *media = getMedia(); - if (!media) return; + auto media = getMedia(); + if (!media) { + return; + } - Reader *reader = media ? media->getClipReader() : 0; - if (!reader) return; + auto reader = media ? media->getClipReader() : nullptr; + if (!reader) { + return; + } switch (notification) { case NotificationReinit: { @@ -903,7 +920,9 @@ void HistoryItem::clipCallback(Media::Clip::Notification notification) { void HistoryItem::recountDisplayDate() { bool displayingDate = ([this]() { - if (isEmpty()) return false; + if (isEmpty()) { + return false; + } if (auto previous = previousItem()) { return previous->isEmpty() || (previous->date.date() != date.date()); @@ -930,7 +949,9 @@ QString HistoryItem::notificationText() const { }; auto result = getText(); - if (result.size() > 0xFF) result = result.mid(0, 0xFF) + qsl("..."); + if (result.size() > 0xFF) { + result = result.mid(0, 0xFF) + qsl("..."); + } return result; } diff --git a/Telegram/SourceFiles/history/history_media.h b/Telegram/SourceFiles/history/history_media.h index ed8036caa..cbb50f9ea 100644 --- a/Telegram/SourceFiles/history/history_media.h +++ b/Telegram/SourceFiles/history/history_media.h @@ -171,6 +171,10 @@ public: return false; } + virtual bool canEditCaption() const { + return false; + } + // Sometimes click on media in message is overloaded by the messsage: // (for example it can open a link or a game instead of opening media) // But the overloading click handler should be used only when media diff --git a/Telegram/SourceFiles/history/history_media_types.h b/Telegram/SourceFiles/history/history_media_types.h index 933701eb5..3339aaf26 100644 --- a/Telegram/SourceFiles/history/history_media_types.h +++ b/Telegram/SourceFiles/history/history_media_types.h @@ -175,6 +175,9 @@ public: bool skipBubbleTail() const override { return isBubbleBottom() && _caption.isEmpty(); } + bool canEditCaption() const override { + return true; + } bool isReadyForOpen() const override { return _data->loaded(); } @@ -191,7 +194,7 @@ protected: } private: - PhotoData *_data; + gsl::not_null _data; int16 _pixw = 1; int16 _pixh = 1; Text _caption; @@ -266,6 +269,9 @@ public: bool skipBubbleTail() const override { return isBubbleBottom() && _caption.isEmpty(); } + bool canEditCaption() const override { + return true; + } protected: float64 dataProgress() const override { @@ -279,7 +285,7 @@ protected: } private: - DocumentData *_data; + gsl::not_null _data; int32 _thumbw; Text _caption; @@ -417,6 +423,9 @@ public: bool hideForwardedFrom() const override { return _data->song(); } + bool canEditCaption() const override { + return true; + } void step_voiceProgress(float64 ms, bool timer); @@ -445,7 +454,7 @@ private: template void buildStringRepresentation(Callback callback) const; - DocumentData *_data; + gsl::not_null _data; }; @@ -523,6 +532,9 @@ public: bool skipBubbleTail() const override { return isBubbleBottom() && _caption.isEmpty(); } + bool canEditCaption() const override { + return !_data->isRoundVideo(); + } bool isReadyForOpen() const override { return _data->loaded(); } @@ -535,7 +547,7 @@ protected: bool dataLoaded() const override; private: - DocumentData *_data; + gsl::not_null _data; int32 _thumbw = 1; int32 _thumbh = 1; Text _caption; @@ -606,7 +618,7 @@ private: int16 _pixw = 1; int16 _pixh = 1; ClickHandlerPtr _packLink; - DocumentData *_data; + gsl::not_null _data; QString _emoji; }; @@ -659,8 +671,7 @@ public: } private: - - int32 _userId; + int32 _userId = 0; UserData *_contact = nullptr; int _phonew = 0; @@ -671,6 +682,7 @@ private: ClickHandlerPtr _linkl; int _linkw = 0; QString _link; + }; class HistoryWebPage : public HistoryMedia { @@ -769,6 +781,7 @@ private: int16 _pixw = 0; int16 _pixh = 0; + }; class HistoryGame : public HistoryMedia { diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index bbf98a9ce..c2d2be925 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -434,8 +434,8 @@ MTPDmessage::Flags newForwardedFlags(PeerData *p, int32 from, HistoryMessage *fw if (HistoryMedia *media = fwd->getMedia()) { if (media->type() == MediaTypeVoiceFile) { result |= MTPDmessage::Flag::f_media_unread; - // } else if (media->type() == MediaTypeVideo) { - // result |= MTPDmessage::flag_media_unread; +// } else if (media->type() == MediaTypeVideo) { +// result |= MTPDmessage::flag_media_unread; } } } diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 31f447607..cb6d81aa7 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -89,7 +89,11 @@ MTPVector composeDocumentAttributes(DocumentData *document if (document->dimensions.width() > 0 && document->dimensions.height() > 0) { int32 duration = document->duration(); if (duration >= 0) { - attributes.push_back(MTP_documentAttributeVideo(MTP_flags(0), MTP_int(duration), MTP_int(document->dimensions.width()), MTP_int(document->dimensions.height()))); + auto flags = MTPDdocumentAttributeVideo::Flags(0); + if (document->isRoundVideo()) { + flags |= MTPDdocumentAttributeVideo::Flag::f_round_message; + } + attributes.push_back(MTP_documentAttributeVideo(MTP_flags(flags), MTP_int(duration), MTP_int(document->dimensions.width()), MTP_int(document->dimensions.height()))); } else { attributes.push_back(MTP_documentAttributeImageSize(MTP_int(document->dimensions.width()), MTP_int(document->dimensions.height()))); } @@ -1449,20 +1453,20 @@ void HistoryWidget::savedGifsGot(const MTPmessages_SavedGifs &gifs) { if (gifs.type() != mtpc_messages_savedGifs) return; auto &d = gifs.c_messages_savedGifs(); - auto &d_gifs = d.vgifs.v; + auto &gifsList = d.vgifs.v; - SavedGifs &saved(cRefSavedGifs()); + auto &saved = cRefSavedGifs(); saved.clear(); - saved.reserve(d_gifs.size()); - for (int32 i = 0, l = d_gifs.size(); i != l; ++i) { - DocumentData *doc = App::feedDocument(d_gifs.at(i)); - if (!doc || !doc->isAnimation()) { + saved.reserve(gifsList.size()); + for (auto &gif : gifsList) { + auto document = App::feedDocument(gif); + if (!document || !document->isGifv()) { LOG(("API Error: bad document returned in HistoryWidget::savedGifsGot!")); continue; } - saved.push_back(doc); + saved.push_back(document); } if (Local::countSavedGifsHash() != d.vhash.v) { LOG(("API Error: received saved gifs hash %1 while counted hash is %2").arg(d.vhash.v).arg(Local::countSavedGifsHash())); @@ -5315,55 +5319,58 @@ void HistoryWidget::onEditMessage() { auto to = App::contextItem(); if (!to) return; - if (EditCaptionBox::canEdit(to)) { - Ui::show(Box(to)); - } else { - if (_recording) { - // Just fix some strange inconsistency. - _send->clearState(); + if (auto media = to->getMedia()) { + if (media->canEditCaption()) { + Ui::show(Box(media, to->fullId())); + return; } - if (!_editMsgId) { - if (_replyToId || !_field->isEmpty()) { - _history->setLocalDraft(std::make_unique(_field, _replyToId, _previewCancelled)); - } else { - _history->clearLocalDraft(); - } - } - - auto original = to->originalText(); - auto editText = textApplyEntities(original.text, original.entities); - auto editTags = ConvertEntitiesToTextTags(original.entities); - TextWithTags editData = { editText, editTags }; - MessageCursor cursor = { editText.size(), editText.size(), QFIXED_MAX }; - _history->setEditDraft(std::make_unique(editData, to->id, cursor, false)); - applyDraft(false); - - _previewData = nullptr; - if (auto media = to->getMedia()) { - if (media->type() == MediaTypeWebPage) { - _previewData = static_cast(media)->webpage(); - updatePreview(); - } - } - if (!_previewData) { - onPreviewParse(); - } - - updateBotKeyboard(); - - if (!_field->isHidden()) _fieldBarCancel->show(); - updateFieldPlaceholder(); - updateMouseTracking(); - updateReplyToName(); - updateControlsGeometry(); - updateField(); - - _saveDraftText = true; - _saveDraftStart = getms(); - onDraftSave(); - - _field->setFocus(); } + + if (_recording) { + // Just fix some strange inconsistency. + _send->clearState(); + } + if (!_editMsgId) { + if (_replyToId || !_field->isEmpty()) { + _history->setLocalDraft(std::make_unique(_field, _replyToId, _previewCancelled)); + } else { + _history->clearLocalDraft(); + } + } + + auto original = to->originalText(); + auto editText = textApplyEntities(original.text, original.entities); + auto editTags = ConvertEntitiesToTextTags(original.entities); + TextWithTags editData = { editText, editTags }; + MessageCursor cursor = { editText.size(), editText.size(), QFIXED_MAX }; + _history->setEditDraft(std::make_unique(editData, to->id, cursor, false)); + applyDraft(false); + + _previewData = nullptr; + if (auto media = to->getMedia()) { + if (media->type() == MediaTypeWebPage) { + _previewData = static_cast(media)->webpage(); + updatePreview(); + } + } + if (!_previewData) { + onPreviewParse(); + } + + updateBotKeyboard(); + + if (!_field->isHidden()) _fieldBarCancel->show(); + updateFieldPlaceholder(); + updateMouseTracking(); + updateReplyToName(); + updateControlsGeometry(); + updateField(); + + _saveDraftText = true; + _saveDraftStart = getms(); + onDraftSave(); + + _field->setFocus(); } void HistoryWidget::onPinMessage() { diff --git a/Telegram/SourceFiles/layerwidget.cpp b/Telegram/SourceFiles/layerwidget.cpp index 331dbc9ba..e9898d27e 100644 --- a/Telegram/SourceFiles/layerwidget.cpp +++ b/Telegram/SourceFiles/layerwidget.cpp @@ -764,7 +764,7 @@ void MediaPreviewWidget::resizeEvent(QResizeEvent *e) { } void MediaPreviewWidget::showPreview(DocumentData *document) { - if (!document || (!document->isAnimation() && !document->sticker())) { + if (!document || (!document->isAnimation() && !document->sticker()) || document->isRoundVideo()) { hidePreview(); return; } diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index c5a5ee956..e41c30c02 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -487,7 +487,9 @@ bool MainWindow::ui_isLayerShown() { } void MainWindow::ui_showMediaPreview(DocumentData *document) { - if (!document || ((!document->isAnimation() || !document->loaded()) && !document->sticker())) return; + if (!document || ((!document->isAnimation() || !document->loaded()) && !document->sticker())) { + return; + } if (!_mediaPreview) { _mediaPreview.create(bodyWidget(), controller()); updateControlsGeometry(); diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index 47eae21c3..0a7775237 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -528,7 +528,7 @@ void MediaView::step_radial(TimeMs ms, bool timer) { if (!_doc->data().isEmpty() && (_doc->isAnimation() || _doc->isVideo())) { displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid)); } else { - const FileLocation &location(_doc->location(true)); + auto &location = _doc->location(true); if (location.accessEnable()) { if (_doc->isAnimation() || _doc->isVideo() || _doc->isTheme() || QImageReader(location.name()).canRead()) { displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid)); @@ -1384,8 +1384,8 @@ void MediaView::displayFinished() { } void MediaView::initAnimation() { - t_assert(_doc != nullptr); - t_assert(_doc->isAnimation() || _doc->isVideo()); + Expects(_doc != nullptr); + Expects(_doc->isAnimation() || _doc->isVideo()); auto &location = _doc->location(true); if (!_doc->data().isEmpty()) { @@ -1406,8 +1406,8 @@ void MediaView::initAnimation() { void MediaView::createClipReader() { if (_gif) return; - t_assert(_doc != nullptr); - t_assert(_doc->isAnimation() || _doc->isVideo()); + Expects(_doc != nullptr); + Expects(_doc->isAnimation() || _doc->isVideo()); if (_doc->dimensions.width() && _doc->dimensions.height()) { int w = _doc->dimensions.width(); diff --git a/Telegram/SourceFiles/storage/localstorage.cpp b/Telegram/SourceFiles/storage/localstorage.cpp index 7a98bf509..ed15fbe95 100644 --- a/Telegram/SourceFiles/storage/localstorage.cpp +++ b/Telegram/SourceFiles/storage/localstorage.cpp @@ -3662,8 +3662,8 @@ void readSavedGifs() { saved.reserve(cnt); OrderedSet read; for (uint32 i = 0; i < cnt; ++i) { - DocumentData *document = Serialize::Document::readFromStream(gifs.version, gifs.stream); - if (!document || !document->isAnimation()) continue; + auto document = Serialize::Document::readFromStream(gifs.version, gifs.stream); + if (!document || !document->isGifv()) continue; if (read.contains(document->id)) continue; read.insert(document->id); diff --git a/Telegram/SourceFiles/storage/serialize_document.cpp b/Telegram/SourceFiles/storage/serialize_document.cpp index 786448905..13af9a7de 100644 --- a/Telegram/SourceFiles/storage/serialize_document.cpp +++ b/Telegram/SourceFiles/storage/serialize_document.cpp @@ -119,6 +119,9 @@ DocumentData *Document::readFromStreamHelper(int streamAppVersion, QDataStream & if (width > 0 && height > 0) { if (duration >= 0) { auto flags = MTPDdocumentAttributeVideo::Flags(0); + if (type == RoundVideoDocument) { + flags |= MTPDdocumentAttributeVideo::Flag::f_round_message; + } attributes.push_back(MTP_documentAttributeVideo(MTP_flags(flags), MTP_int(duration), MTP_int(width), MTP_int(height))); } else { attributes.push_back(MTP_documentAttributeImageSize(MTP_int(width), MTP_int(height))); diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index 825d1d0d8..2e06681fb 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -1299,9 +1299,6 @@ VoiceData::~VoiceData() { } } -DocumentAdditionalData::~DocumentAdditionalData() { -} - DocumentData::DocumentData(DocumentId id, int32 dc, uint64 accessHash, int32 version, const QString &url, const QVector &attributes) : id(id) , _dc(dc) @@ -1353,7 +1350,7 @@ void DocumentData::setattributes(const QVector &attributes case mtpc_documentAttributeVideo: { auto &d = attributes[i].c_documentAttributeVideo(); if (type == FileDocument) { - type = VideoDocument; + type = d.is_round_message() ? RoundVideoDocument : VideoDocument; } _duration = d.vduration.v; dimensions = QSize(d.vw.v, d.vh.v); @@ -1440,8 +1437,10 @@ void DocumentData::automaticLoad(const HistoryItem *item) { } void DocumentData::automaticLoadSettingsChanged() { - if (loaded() || status != FileReady || (!isAnimation() && !voice()) || !saveToCache() || _loader != CancelledMtpFileLoader) return; - _loader = 0; + if (loaded() || status != FileReady || (!isAnimation() && !voice()) || !saveToCache() || _loader != CancelledMtpFileLoader) { + return; + } + _loader = nullptr; } void DocumentData::performActionOnLoad() { @@ -1450,10 +1449,10 @@ void DocumentData::performActionOnLoad() { auto loc = location(true); auto already = loc.name(); auto item = _actionOnLoadMsgId.msg ? App::histItemById(_actionOnLoadMsgId) : nullptr; - bool showImage = !isVideo() && (size < App::kImageSizeLimit); - bool playVoice = voice() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen); - bool playMusic = song() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen); - bool playAnimation = isAnimation() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && showImage && item && item->getMedia(); + auto showImage = !isVideo() && (size < App::kImageSizeLimit); + auto playVoice = voice() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen); + auto playMusic = song() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen); + auto playAnimation = isAnimation() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && showImage && item && item->getMedia(); if (auto applyTheme = isTheme()) { if (!loc.isEmpty() && loc.accessEnable()) { App::wnd()->showDocument(this, item); @@ -1784,7 +1783,9 @@ bool fileIsImage(const QString &name, const QString &mime) { } void DocumentData::recountIsImage() { - if (isAnimation() || isVideo()) return; + if (isAnimation() || isVideo()) { + return; + } _duration = fileIsImage(name, mime) ? 1 : -1; // hack } diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 8ef685f96..79623400c 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -1074,17 +1074,20 @@ enum FileStatus { FileReady = 1, }; +// Don't change the values. This type is used for serialization. enum DocumentType { - FileDocument = 0, - VideoDocument = 1, - SongDocument = 2, - StickerDocument = 3, - AnimatedDocument = 4, - VoiceDocument = 5, + FileDocument = 0, + VideoDocument = 1, + SongDocument = 2, + StickerDocument = 3, + AnimatedDocument = 4, + VoiceDocument = 5, + RoundVideoDocument = 6, }; struct DocumentAdditionalData { - virtual ~DocumentAdditionalData(); + virtual ~DocumentAdditionalData() = default; + }; struct StickerData : public DocumentAdditionalData { @@ -1099,9 +1102,7 @@ struct StickerData : public DocumentAdditionalData { }; struct SongData : public DocumentAdditionalData { - SongData() : duration(0) { - } - int32 duration; + int32 duration = 0; QString title, performer; }; @@ -1193,8 +1194,11 @@ public: const VoiceData *voice() const { return const_cast(this)->voice(); } + bool isRoundVideo() const { + return (type == RoundVideoDocument); + } bool isAnimation() const { - return (type == AnimatedDocument) || !mime.compare(qstr("image/gif"), Qt::CaseInsensitive); + return (type == AnimatedDocument) || isRoundVideo() || !mime.compare(qstr("image/gif"), Qt::CaseInsensitive); } bool isGifv() const { return (type == AnimatedDocument) && !mime.compare(qstr("video/mp4"), Qt::CaseInsensitive); @@ -1246,11 +1250,12 @@ public: ~DocumentData(); - DocumentId id; + DocumentId id = 0; DocumentType type = FileDocument; QSize dimensions; int32 date = 0; - QString name, mime; + QString name; + QString mime; ImagePtr thumb, replyPreview; int32 size = 0;