From 6ba57e713e3a7dfe8203bc8e4c777cdd0af50cfa Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 16 Jun 2017 23:33:35 +0300 Subject: [PATCH] Use forwarded messages only for one selected chat. Different chats now can have different forwarded "drafts". --- Telegram/SourceFiles/history.cpp | 22 +++ Telegram/SourceFiles/history.h | 9 +- .../history/history_inner_widget.cpp | 12 +- .../history/history_inner_widget.h | 2 +- Telegram/SourceFiles/historywidget.cpp | 148 +++++++++++++----- Telegram/SourceFiles/historywidget.h | 16 +- Telegram/SourceFiles/mainwidget.cpp | 127 +++------------ Telegram/SourceFiles/mainwidget.h | 14 +- Telegram/SourceFiles/overviewwidget.cpp | 26 +-- Telegram/SourceFiles/overviewwidget.h | 4 +- 10 files changed, 197 insertions(+), 183 deletions(-) diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index 1ee498cc3..03e8af6f0 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -201,6 +201,28 @@ void History::draftSavedToCloud() { if (App::main()) App::main()->writeDrafts(this); } +SelectedItemSet History::validateForwardDraft() { + auto result = SelectedItemSet(); + auto count = 0; + for_const (auto &fullMsgId, _forwardDraft) { + if (auto item = App::histItemById(fullMsgId)) { + result.insert(++count, item); + } + } + if (result.size() != _forwardDraft.size()) { + setForwardDraft(result); + } + return result; +} + +void History::setForwardDraft(const SelectedItemSet &items) { + _forwardDraft.clear(); + _forwardDraft.reserve(items.size()); + for_const (auto item, items) { + _forwardDraft.push_back(item->fullId()); + } +} + bool History::updateSendActionNeedsAnimating(UserData *user, const MTPSendMessageAction &action) { using Type = SendAction::Type; if (action.type() == mtpc_sendMessageCancelAction) { diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h index 78be71feb..253726e8e 100644 --- a/Telegram/SourceFiles/history.h +++ b/Telegram/SourceFiles/history.h @@ -28,7 +28,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org void historyInit(); class HistoryItem; -using SelectedItemSet = QMap; +using SelectedItemSet = QMap>; enum NewMessageType { NewMessageUnread, @@ -382,6 +382,12 @@ public: return _editDraft ? editDraft() : localDraft(); } + QVector forwardDraft() const { + return _forwardDraft; + } + SelectedItemSet validateForwardDraft(); + void setForwardDraft(const SelectedItemSet &items); + // some fields below are a property of a currently displayed instance of this // conversation history not a property of the conversation history itself public: @@ -558,6 +564,7 @@ private: std::unique_ptr _localDraft, _cloudDraft; std::unique_ptr _editDraft; + QVector _forwardDraft; using TypingUsers = QMap; TypingUsers _typing; diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index b38ea3d04..9b66fa7d1 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -1960,19 +1960,23 @@ void HistoryInner::clearSelectedItems(bool onlyTextSelection) { } } -void HistoryInner::fillSelectedItems(SelectedItemSet &sel, bool forDelete) { - if (_selected.isEmpty() || _selected.cbegin().value() != FullSelection) return; +SelectedItemSet HistoryInner::getSelectedItems() const { + auto result = SelectedItemSet(); + if (_selected.isEmpty() || _selected.cbegin().value() != FullSelection) { + return result; + } for (auto i = _selected.cbegin(), e = _selected.cend(); i != e; ++i) { auto item = i.key(); if (item && item->toHistoryMessage() && item->id > 0) { if (item->history() == _migrated) { - sel.insert(item->id - ServerMaxMsgId, item); + result.insert(item->id - ServerMaxMsgId, item); } else { - sel.insert(item->id, item); + result.insert(item->id, item); } } } + return result; } void HistoryInner::selectItem(HistoryItem *item) { diff --git a/Telegram/SourceFiles/history/history_inner_widget.h b/Telegram/SourceFiles/history/history_inner_widget.h index f3caf6cc8..6d329e8d8 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.h +++ b/Telegram/SourceFiles/history/history_inner_widget.h @@ -62,7 +62,7 @@ public: Window::TopBarWidget::SelectedState getSelectionState() const; void clearSelectedItems(bool onlyTextSelection = false); - void fillSelectedItems(SelectedItemSet &sel, bool forDelete = true); + SelectedItemSet getSelectedItems() const; void selectItem(HistoryItem *item); void updateBotInfo(bool recount = true); diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index fc910dc5e..89c718cec 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -1795,6 +1795,8 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re if (_history) { if (_peer->id == peerId && !reload) { + updateForwarding(); + bool canShowNow = _history->isReadyFor(showAtMsgId); if (!canShowNow) { delayedShowAt(showAtMsgId); @@ -1930,6 +1932,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re _history = App::history(_peer->id); _migrated = _peer->migrateFrom() ? App::history(_peer->migrateFrom()->id) : 0; + updateForwarding(); if (_channel) { updateNotifySettings(); @@ -3663,7 +3666,7 @@ bool HistoryWidget::canSendMessages(PeerData *peer) const { } bool HistoryWidget::readyToForward() const { - return _canSendMessages && App::main()->hasForwardingItems(); + return _canSendMessages && !_toForward.isEmpty(); } bool HistoryWidget::hasSilentToggle() const { @@ -5649,7 +5652,7 @@ void HistoryWidget::onReplyToMessage() { return; } - App::main()->cancelForwarding(); + App::main()->cancelForwarding(_history); if (_editMsgId) { if (auto localDraft = _history->localDraft()) { @@ -5887,11 +5890,6 @@ void HistoryWidget::cancelEdit() { update(); } -void HistoryWidget::cancelForwarding() { - updateControlsVisibility(); - updateControlsGeometry(); -} - void HistoryWidget::onFieldBarCancel() { Ui::hideLayer(); _replyForwardPressed = false; @@ -5905,7 +5903,7 @@ void HistoryWidget::onFieldBarCancel() { } else if (_editMsgId) { cancelEdit(); } else if (readyToForward()) { - App::main()->cancelForwarding(); + App::main()->cancelForwarding(_history); } else if (_replyToId) { cancelReply(); } else if (_kbReplyTo) { @@ -6184,8 +6182,7 @@ void HistoryWidget::confirmDeleteContextItem() { void HistoryWidget::confirmDeleteSelectedItems() { if (!_list) return; - SelectedItemSet selected; - _list->fillSelectedItems(selected); + auto selected = _list->getSelectedItems(); if (selected.isEmpty()) return; App::main()->deleteLayer(selected.size()); @@ -6218,8 +6215,7 @@ void HistoryWidget::deleteSelectedItems(bool forEveryone) { Ui::hideLayer(); if (!_list) return; - SelectedItemSet selected; - _list->fillSelectedItems(selected); + auto selected = _list->getSelectedItems(); if (selected.isEmpty()) return; QMap> idsByPeer; @@ -6294,8 +6290,8 @@ void HistoryWidget::stopAnimActive() { _activeAnimMsgId = 0; } -void HistoryWidget::fillSelectedItems(SelectedItemSet &sel, bool forDelete) { - if (_list) _list->fillSelectedItems(sel, forDelete); +SelectedItemSet HistoryWidget::getSelectedItems() const { + return _list ? _list->getSelectedItems() : SelectedItemSet(); } void HistoryWidget::updateTopBarSelection() { @@ -6359,11 +6355,80 @@ void HistoryWidget::updateReplyEditTexts(bool force) { } } -void HistoryWidget::updateForwarding(bool force) { - if (readyToForward()) { - updateControlsVisibility(); +void HistoryWidget::updateForwarding() { + if (_history) { + _toForward = _history->validateForwardDraft(); + updateForwardingTexts(); } else { - updateControlsGeometry(); + _toForward.clear(); + } + updateForwardingItemRemovedSubscription(); + updateControlsVisibility(); + updateControlsGeometry(); +} + +void HistoryWidget::updateForwardingTexts() { + int32 version = 0; + QString from, text; + if (!_toForward.isEmpty()) { + QMap fromUsersMap; + QVector fromUsers; + fromUsers.reserve(_toForward.size()); + for (auto i = _toForward.cbegin(), e = _toForward.cend(); i != e; ++i) { + auto from = i.value()->authorOriginal(); + if (!fromUsersMap.contains(from)) { + fromUsersMap.insert(from, true); + fromUsers.push_back(from); + } + version += from->nameVersion; + } + if (fromUsers.size() > 2) { + from = lng_forwarding_from(lt_count, fromUsers.size() - 1, lt_user, fromUsers.at(0)->shortName()); + } else if (fromUsers.size() < 2) { + from = fromUsers.at(0)->name; + } else { + from = lng_forwarding_from_two(lt_user, fromUsers.at(0)->shortName(), lt_second_user, fromUsers.at(1)->shortName()); + } + + if (_toForward.size() < 2) { + text = _toForward.cbegin().value()->inReplyText(); + } else { + text = lng_forward_messages(lt_count, _toForward.size()); + } + } + _toForwardFrom.setText(st::msgNameStyle, from, _textNameOptions); + _toForwardText.setText(st::messageTextStyle, textClean(text), _textDlgOptions); + _toForwardNameVersion = version; +} + +void HistoryWidget::checkForwardingInfo() { + if (!_toForward.isEmpty()) { + auto version = 0; + for_const (auto item, _toForward) { + version += item->authorOriginal()->nameVersion; + } + if (version != _toForwardNameVersion) { + updateForwardingTexts(); + } + } +} + +void HistoryWidget::updateForwardingItemRemovedSubscription() { + if (_toForward.isEmpty()) { + unsubscribe(_forwardingItemRemovedSubscription); + _forwardingItemRemovedSubscription = 0; + } else if (!_forwardingItemRemovedSubscription) { + _forwardingItemRemovedSubscription = subscribe(Global::RefItemRemoved(), [this](HistoryItem *item) { + auto i = _toForward.find(item->id); + if (i == _toForward.cend() || i.value() != item) { + i = _toForward.find(item->id - ServerMaxMsgId); + } + if (i != _toForward.cend() && i.value() == item) { + _toForward.erase(i); + updateForwardingItemRemovedSubscription(); + updateForwardingTexts(); + } + }); } } @@ -6380,10 +6445,9 @@ void HistoryWidget::updateField() { } void HistoryWidget::drawField(Painter &p, const QRect &rect) { - int32 backy = _field->y() - st::historySendPadding, backh = _field->height() + 2 * st::historySendPadding; - Text *from = 0, *text = 0; - bool serviceColor = false, hasForward = readyToForward(); - ImagePtr preview; + auto backy = _field->y() - st::historySendPadding; + auto backh = _field->height() + 2 * st::historySendPadding; + auto hasForward = readyToForward(); auto drawMsgText = (_editMsgId || _replyToId) ? _replyEditMsg : _kbReplyTo; if (_editMsgId || _replyToId || (!hasForward && _kbReplyTo)) { if (!_editMsgId && drawMsgText && drawMsgText->author()->nameVersion > _replyToNameVersion) { @@ -6392,24 +6456,24 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) { backy -= st::historyReplyHeight; backh += st::historyReplyHeight; } else if (hasForward) { - App::main()->fillForwardingInfo(from, text, serviceColor, preview); + checkForwardingInfo(); backy -= st::historyReplyHeight; backh += st::historyReplyHeight; } else if (_previewData && _previewData->pendingTill >= 0) { backy -= st::historyReplyHeight; backh += st::historyReplyHeight; } - bool drawPreview = (_previewData && _previewData->pendingTill >= 0) && !_replyForwardPressed; + auto drawWebPagePreview = (_previewData && _previewData->pendingTill >= 0) && !_replyForwardPressed; p.fillRect(myrtlrect(0, backy, _chatWidth, backh), st::historyReplyBg); if (_editMsgId || _replyToId || (!hasForward && _kbReplyTo)) { - int32 replyLeft = st::historyReplySkip; + auto replyLeft = st::historyReplySkip; (_editMsgId ? st::historyEditIcon : st::historyReplyIcon).paint(p, st::historyReplyIconPosition + QPoint(0, backy), width()); - if (!drawPreview) { + if (!drawWebPagePreview) { if (drawMsgText) { if (drawMsgText->getMedia() && drawMsgText->getMedia()->hasReplyPreview()) { - ImagePtr replyPreview = drawMsgText->getMedia()->replyPreview(); + auto replyPreview = drawMsgText->getMedia()->replyPreview(); if (!replyPreview->isNull()) { - QRect to(replyLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); + auto to = QRect(replyLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small)); } replyLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x(); @@ -6428,37 +6492,41 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) { p.drawText(replyLeft, backy + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(lang(lng_profile_loading), _chatWidth - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right())); } } - } else if (from && text) { - int forwardLeft = st::historyReplySkip; + } else if (hasForward) { + auto forwardLeft = st::historyReplySkip; st::historyForwardIcon.paint(p, st::historyReplyIconPosition + QPoint(0, backy), width()); - if (!drawPreview) { + if (!drawWebPagePreview) { + auto firstItem = _toForward.cbegin().value(); + auto firstMedia = firstItem->getMedia(); + auto serviceColor = (_toForward.size() > 1) || (firstMedia != nullptr) || firstItem->serviceMsg(); + auto preview = (_toForward.size() < 2 && firstMedia && firstMedia->hasReplyPreview()) ? firstMedia->replyPreview() : ImagePtr(); if (!preview->isNull()) { - QRect to(forwardLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); + auto to = QRect(forwardLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); if (preview->width() == preview->height()) { p.drawPixmap(to.x(), to.y(), preview->pix()); } else { - QRect from = (preview->width() > preview->height()) ? QRect((preview->width() - preview->height()) / 2, 0, preview->height(), preview->height()) : QRect(0, (preview->height() - preview->width()) / 2, preview->width(), preview->width()); + auto from = (preview->width() > preview->height()) ? QRect((preview->width() - preview->height()) / 2, 0, preview->height(), preview->height()) : QRect(0, (preview->height() - preview->width()) / 2, preview->width(), preview->width()); p.drawPixmap(to, preview->pix(), from); } forwardLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x(); } p.setPen(st::historyReplyNameFg); - from->drawElided(p, forwardLeft, backy + st::msgReplyPadding.top(), width() - forwardLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()); + _toForwardFrom.drawElided(p, forwardLeft, backy + st::msgReplyPadding.top(), width() - forwardLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()); p.setPen(serviceColor ? st::historyComposeAreaFgService : st::historyComposeAreaFg); - text->drawElided(p, forwardLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, _chatWidth - forwardLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()); + _toForwardText.drawElided(p, forwardLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, _chatWidth - forwardLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()); } } - if (drawPreview) { - int32 previewLeft = st::historyReplySkip + st::webPageLeft; + if (drawWebPagePreview) { + auto previewLeft = st::historyReplySkip + st::webPageLeft; p.fillRect(st::historyReplySkip, backy + st::msgReplyPadding.top(), st::webPageBar, st::msgReplyBarSize.height(), st::msgInReplyBarColor); if ((_previewData->photo && !_previewData->photo->thumb->isNull()) || (_previewData->document && !_previewData->document->thumb->isNull())) { - ImagePtr replyPreview = _previewData->photo ? _previewData->photo->makeReplyPreview() : _previewData->document->makeReplyPreview(); + auto replyPreview = _previewData->photo ? _previewData->photo->makeReplyPreview() : _previewData->document->makeReplyPreview(); if (!replyPreview->isNull()) { - QRect to(previewLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); + auto to = QRect(previewLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); if (replyPreview->width() == replyPreview->height()) { p.drawPixmap(to.x(), to.y(), replyPreview->pix()); } else { - QRect from = (replyPreview->width() > replyPreview->height()) ? QRect((replyPreview->width() - replyPreview->height()) / 2, 0, replyPreview->height(), replyPreview->height()) : QRect(0, (replyPreview->height() - replyPreview->width()) / 2, replyPreview->width(), replyPreview->width()); + auto from = (replyPreview->width() > replyPreview->height()) ? QRect((replyPreview->width() - replyPreview->height()) / 2, 0, replyPreview->height(), replyPreview->height()) : QRect(0, (replyPreview->height() - replyPreview->width()) / 2, replyPreview->width(), replyPreview->width()); p.drawPixmap(to, replyPreview->pix(), from); } } diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 2d0100cfa..1fcdb38f3 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -262,7 +262,7 @@ public: uint64 animActiveTimeStart(const HistoryItem *msg) const; void stopAnimActive(); - void fillSelectedItems(SelectedItemSet &sel, bool forDelete = true); + SelectedItemSet getSelectedItems() const; void itemEdited(HistoryItem *item); void updateScrollColors(); @@ -272,8 +272,9 @@ public: bool lastForceReplyReplied(const FullMsgId &replyTo = FullMsgId(NoChannel, -1)) const; bool cancelReply(bool lastKeyboardUsed = false); void cancelEdit(); - void updateForwarding(bool force = false); - void cancelForwarding(); // called by MainWidget + void updateForwarding(); + void updateForwardingTexts(); + void updateForwardingItemRemovedSubscription(); void clearReplyReturns(); void pushReplyReturn(HistoryItem *item); @@ -540,10 +541,17 @@ private: void hideSelectorControlsAnimated(); int countMembersDropdownHeightMax() const; + void updateReplyToName(); + void checkForwardingInfo(); + MsgId _replyToId = 0; Text _replyToName; int _replyToNameVersion = 0; - void updateReplyToName(); + + SelectedItemSet _toForward; + Text _toForwardFrom, _toForwardText; + int _toForwardNameVersion = 0; + int _forwardingItemRemovedSubscription = 0; int _chatWidth = 0; MsgId _editMsgId = 0; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index b9df47157..dd6b98ff6 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -583,11 +583,7 @@ bool MainWidget::onForward(const PeerId &peerId, ForwardWhatMessages what) { auto toForward = SelectedItemSet(); if (what == ForwardSelectedMessages) { - if (_overview) { - _overview->fillSelectedItems(toForward, false); - } else { - _history->fillSelectedItems(toForward, false); - } + toForward = _overview ? _overview->getSelectedItems() : _history->getSelectedItems(); } else { auto item = (HistoryItem*)nullptr; if (what == ForwardContextMessage) { @@ -615,13 +611,10 @@ bool MainWidget::onForward(const PeerId &peerId, ForwardWhatMessages what) { } } - _toForward = toForward; + App::history(peer)->setForwardDraft(toForward); _history->cancelReply(); - updateForwardingItemRemovedSubscription(); - updateForwardingTexts(); Ui::showPeerHistory(peer, ShowAtUnreadMsgId); _history->onClearSelected(); - _history->updateForwarding(); return true; } @@ -665,93 +658,17 @@ bool MainWidget::onInlineSwitchChosen(const PeerId &peer, const QString &botAndQ return true; } -bool MainWidget::hasForwardingItems() { - return !_toForward.isEmpty(); -} - -void MainWidget::fillForwardingInfo(Text *&from, Text *&text, bool &serviceColor, ImagePtr &preview) { - if (_toForward.isEmpty()) return; - int32 version = 0; - for (SelectedItemSet::const_iterator i = _toForward.cbegin(), e = _toForward.cend(); i != e; ++i) { - version += i.value()->authorOriginal()->nameVersion; - } - if (version != _toForwardNameVersion) { - updateForwardingTexts(); - } - from = &_toForwardFrom; - text = &_toForwardText; - serviceColor = (_toForward.size() > 1) || _toForward.cbegin().value()->getMedia() || _toForward.cbegin().value()->serviceMsg(); - if (_toForward.size() < 2 && _toForward.cbegin().value()->getMedia() && _toForward.cbegin().value()->getMedia()->hasReplyPreview()) { - preview = _toForward.cbegin().value()->getMedia()->replyPreview(); - } -} - -void MainWidget::updateForwardingTexts() { - int32 version = 0; - QString from, text; - if (!_toForward.isEmpty()) { - QMap fromUsersMap; - QVector fromUsers; - fromUsers.reserve(_toForward.size()); - for (SelectedItemSet::const_iterator i = _toForward.cbegin(), e = _toForward.cend(); i != e; ++i) { - PeerData *from = i.value()->authorOriginal(); - if (!fromUsersMap.contains(from)) { - fromUsersMap.insert(from, true); - fromUsers.push_back(from); - } - version += from->nameVersion; - } - if (fromUsers.size() > 2) { - from = lng_forwarding_from(lt_count, fromUsers.size() - 1, lt_user, fromUsers.at(0)->shortName()); - } else if (fromUsers.size() < 2) { - from = fromUsers.at(0)->name; - } else { - from = lng_forwarding_from_two(lt_user, fromUsers.at(0)->shortName(), lt_second_user, fromUsers.at(1)->shortName()); - } - - if (_toForward.size() < 2) { - text = _toForward.cbegin().value()->inReplyText(); - } else { - text = lng_forward_messages(lt_count, _toForward.size()); - } - } - _toForwardFrom.setText(st::msgNameStyle, from, _textNameOptions); - _toForwardText.setText(st::messageTextStyle, textClean(text), _textDlgOptions); - _toForwardNameVersion = version; -} - -void MainWidget::updateForwardingItemRemovedSubscription() { - if (_toForward.isEmpty()) { - unsubscribe(_forwardingItemRemovedSubscription); - _forwardingItemRemovedSubscription = 0; - } else if (!_forwardingItemRemovedSubscription) { - _forwardingItemRemovedSubscription = subscribe(Global::RefItemRemoved(), [this](HistoryItem *item) { - auto i = _toForward.find(item->id); - if (i == _toForward.cend() || i.value() != item) { - i = _toForward.find(item->id - ServerMaxMsgId); - } - if (i != _toForward.cend() && i.value() == item) { - _toForward.erase(i); - updateForwardingItemRemovedSubscription(); - updateForwardingTexts(); - } - }); - } -} - -void MainWidget::cancelForwarding() { - if (_toForward.isEmpty()) return; - - _toForward.clear(); - _history->cancelForwarding(); - updateForwardingItemRemovedSubscription(); +void MainWidget::cancelForwarding(History *history) { + history->setForwardDraft(SelectedItemSet()); + _history->updateForwarding(); } void MainWidget::finishForwarding(History *history, bool silent) { if (!history) return; - if (!_toForward.isEmpty()) { - bool genClientSideMessage = (_toForward.size() < 2); + auto toForward = history->validateForwardDraft(); + if (!toForward.isEmpty()) { + auto genClientSideMessage = (toForward.size() < 2); PeerData *forwardFrom = 0; App::main()->readServerHistory(history); @@ -773,16 +690,17 @@ void MainWidget::finishForwarding(History *history, bool silent) { QVector ids; QVector randomIds; - ids.reserve(_toForward.size()); - randomIds.reserve(_toForward.size()); - for (SelectedItemSet::const_iterator i = _toForward.cbegin(), e = _toForward.cend(); i != e; ++i) { - uint64 randomId = rand_value(); + ids.reserve(toForward.size()); + randomIds.reserve(toForward.size()); + for (auto i = toForward.cbegin(), e = toForward.cend(); i != e; ++i) { + auto randomId = rand_value(); if (genClientSideMessage) { - FullMsgId newId(peerToChannel(history->peer->id), clientMsgId()); - auto msg = static_cast(_toForward.cbegin().value()); - auto messageFromId = showFromName ? AuthSession::CurrentUserId() : 0; - history->addNewForwarded(newId.msg, flags, date(MTP_int(unixtime())), messageFromId, msg); - App::historyRegRandom(randomId, newId); + if (auto message = i.value()->toHistoryMessage()) { + auto newId = FullMsgId(peerToChannel(history->peer->id), clientMsgId()); + auto messageFromId = showFromName ? AuthSession::CurrentUserId() : 0; + history->addNewForwarded(newId.msg, flags, date(MTP_int(unixtime())), messageFromId, message); + App::historyRegRandom(randomId, newId); + } } if (forwardFrom != i.value()->history()->peer) { if (forwardFrom) { @@ -801,7 +719,7 @@ void MainWidget::finishForwarding(History *history, bool silent) { _history->peerMessagesUpdated(); } - cancelForwarding(); + cancelForwarding(history); } historyToDown(history); @@ -1076,12 +994,7 @@ void MainWidget::forwardLayer(int forwardSelected) { void MainWidget::deleteLayer(int selectedCount) { if (selectedCount) { auto forDelete = true; - SelectedItemSet selected; - if (_overview) { - _overview->fillSelectedItems(selected, forDelete); - } else { - _history->fillSelectedItems(selected, forDelete); - } + auto selected = _overview ? _overview->getSelectedItems() : _history->getSelectedItems(); if (!selected.isEmpty()) { Ui::show(Box(selected)); } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index fc1c38958..39b260c27 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -348,10 +348,8 @@ public: void pushReplyReturn(HistoryItem *item); - bool hasForwardingItems(); - void fillForwardingInfo(Text *&from, Text *&text, bool &serviceColor, ImagePtr &preview); - void cancelForwarding(); - void finishForwarding(History *hist, bool silent); // send them + void cancelForwarding(History *history); + void finishForwarding(History *history, bool silent); // send them void mediaMarkRead(DocumentData *data); void mediaMarkRead(const HistoryItemsMap &items); @@ -506,9 +504,6 @@ private: void updateControlsGeometry(); void updateDialogsWidthAnimated(); - void updateForwardingTexts(); - void updateForwardingItemRemovedSubscription(); - void createPlayer(); void switchToPanelPlayer(); void switchToFixedPlayer(); @@ -609,11 +604,6 @@ private: gsl::not_null _controller; bool _started = false; - SelectedItemSet _toForward; - Text _toForwardFrom, _toForwardText; - int32 _toForwardNameVersion = 0; - int _forwardingItemRemovedSubscription = 0; - OrderedSet _webPagesUpdated; OrderedSet _gamesUpdated; QTimer _webPageOrGameUpdater; diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index d553fde92..f28371865 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -1580,19 +1580,23 @@ void OverviewInner::clearSelectedItems(bool onlyTextSelection) { } } -void OverviewInner::fillSelectedItems(SelectedItemSet &sel, bool forDelete) { - if (_selected.isEmpty() || _selected.cbegin().value() != FullSelection) return; +SelectedItemSet OverviewInner::getSelectedItems() const { + auto result = SelectedItemSet(); + if (_selected.isEmpty() || _selected.cbegin().value() != FullSelection) { + return result; + } - for (SelectedItems::const_iterator i = _selected.cbegin(), e = _selected.cend(); i != e; ++i) { - HistoryItem *item = App::histItemById(itemChannel(i.key()), itemMsgId(i.key())); + for (auto i = _selected.cbegin(), e = _selected.cend(); i != e; ++i) { + auto item = App::histItemById(itemChannel(i.key()), itemMsgId(i.key())); if (item && item->toHistoryMessage() && item->id > 0) { if (item->history() == _migrated) { - sel.insert(item->id - ServerMaxMsgId, item); + result.insert(item->id - ServerMaxMsgId, item); } else { - sel.insert(item->id, item); + result.insert(item->id, item); } } } + return result; } void OverviewInner::onTouchSelect() { @@ -2275,8 +2279,8 @@ void OverviewWidget::notify_historyItemLayoutChanged(const HistoryItem *item) { } } -void OverviewWidget::fillSelectedItems(SelectedItemSet &sel, bool forDelete) { - _inner->fillSelectedItems(sel, forDelete); +SelectedItemSet OverviewWidget::getSelectedItems() const { + return _inner->getSelectedItems(); } void OverviewWidget::updateAfterDrag() { @@ -2360,8 +2364,7 @@ void OverviewWidget::confirmDeleteContextItem() { } void OverviewWidget::confirmDeleteSelectedItems() { - SelectedItemSet selected; - _inner->fillSelectedItems(selected); + auto selected = _inner->getSelectedItems(); if (selected.isEmpty()) return; App::main()->deleteLayer(selected.size()); @@ -2393,8 +2396,7 @@ void OverviewWidget::deleteContextItem(bool forEveryone) { void OverviewWidget::deleteSelectedItems(bool forEveryone) { Ui::hideLayer(); - SelectedItemSet selected; - _inner->fillSelectedItems(selected); + auto selected = _inner->getSelectedItems(); if (selected.isEmpty()) return; QMap> idsByPeer; diff --git a/Telegram/SourceFiles/overviewwidget.h b/Telegram/SourceFiles/overviewwidget.h index 1438fab7f..f28671ce0 100644 --- a/Telegram/SourceFiles/overviewwidget.h +++ b/Telegram/SourceFiles/overviewwidget.h @@ -93,7 +93,7 @@ public: Window::TopBarWidget::SelectedState getSelectionState() const; void clearSelectedItems(bool onlyTextSelection = false); - void fillSelectedItems(SelectedItemSet &sel, bool forDelete = true); + SelectedItemSet getSelectedItems() const; // AbstractTooltipShower interface QString tooltipText() const override; @@ -331,7 +331,7 @@ public: bool touchScroll(const QPoint &delta); - void fillSelectedItems(SelectedItemSet &sel, bool forDelete); + SelectedItemSet getSelectedItems() const; void updateAfterDrag();