mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Show forum messages search results with topics.
This commit is contained in:
parent
88d1a502a5
commit
d6ee5b3456
9 changed files with 235 additions and 177 deletions
|
@ -712,9 +712,9 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
p.translate(0, st::searchedBarHeight);
|
||||
|
||||
auto skip = searchedOffset();
|
||||
auto from = floorclamp(r.y() - skip, st::dialogsRowHeight, 0, _searchResults.size());
|
||||
auto to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _searchResults.size());
|
||||
p.translate(0, from * st::dialogsRowHeight);
|
||||
auto from = floorclamp(r.y() - skip, _st->height, 0, _searchResults.size());
|
||||
auto to = ceilclamp(r.y() + r.height() - skip, _st->height, 0, _searchResults.size());
|
||||
p.translate(0, from * _st->height);
|
||||
if (from < _searchResults.size()) {
|
||||
for (; from < to; ++from) {
|
||||
const auto &result = _searchResults[from];
|
||||
|
@ -725,7 +725,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
? _searchedPressed
|
||||
: _searchedSelected));
|
||||
Ui::RowPainter::Paint(p, result.get(), {
|
||||
.st = &st::defaultDialogRow,
|
||||
.st = _st,
|
||||
.folder = _openedFolder,
|
||||
.forum = _openedForum,
|
||||
.filter = _filterId,
|
||||
|
@ -738,7 +738,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
.narrow = (fullWidth < st::columnMinimalWidthLeft),
|
||||
.displayUnreadInfo = showUnreadInSearchResults,
|
||||
});
|
||||
p.translate(0, st::dialogsRowHeight);
|
||||
p.translate(0, _st->height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1141,7 +1141,7 @@ void InnerWidget::selectByMouse(QPoint globalPosition) {
|
|||
}
|
||||
if (!_waitingForSearch && !_searchResults.empty()) {
|
||||
auto skip = searchedOffset();
|
||||
auto searchedSelected = (mouseY >= skip) ? ((mouseY - skip) / st::dialogsRowHeight) : -1;
|
||||
auto searchedSelected = (mouseY >= skip) ? ((mouseY - skip) / _st->height) : -1;
|
||||
if (searchedSelected < 0 || searchedSelected >= _searchResults.size()) {
|
||||
searchedSelected = -1;
|
||||
}
|
||||
|
@ -1205,7 +1205,7 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) {
|
|||
[this, peer = result->peer] { updateSearchResult(peer); });
|
||||
} else if (base::in_range(_searchedPressed, 0, _searchResults.size())) {
|
||||
auto &row = _searchResults[_searchedPressed];
|
||||
row->addRipple(e->pos() - QPoint(0, searchedOffset() + _searchedPressed * st::dialogsRowHeight), QSize(width(), st::dialogsRowHeight), row->repaint());
|
||||
row->addRipple(e->pos() - QPoint(0, searchedOffset() + _searchedPressed * _st->height), QSize(width(), _st->height), row->repaint());
|
||||
}
|
||||
if (anim::Disabled()
|
||||
&& (!_pressed || !_pressed->entry()->isPinnedDialog(_filterId))) {
|
||||
|
@ -1789,8 +1789,8 @@ void InnerWidget::updateDialogRow(
|
|||
for (const auto &result : _searchResults) {
|
||||
if (isSearchResultActive(result.get(), row)) {
|
||||
updateRow(
|
||||
add + index * st::dialogsRowHeight,
|
||||
st::dialogsRowHeight);
|
||||
add + index * _st->height,
|
||||
_st->height);
|
||||
break;
|
||||
}
|
||||
++index;
|
||||
|
@ -1836,7 +1836,7 @@ void InnerWidget::updateSelectedRow(Key key) {
|
|||
} else if (_peerSearchSelected >= 0) {
|
||||
update(0, peerSearchOffset() + _peerSearchSelected * st::dialogsRowHeight, width(), st::dialogsRowHeight);
|
||||
} else if (_searchedSelected >= 0) {
|
||||
update(0, searchedOffset() + _searchedSelected * st::dialogsRowHeight, width(), st::dialogsRowHeight);
|
||||
update(0, searchedOffset() + _searchedSelected * _st->height, width(), _st->height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2068,10 +2068,43 @@ InnerWidget::~InnerWidget() {
|
|||
void InnerWidget::clearSearchResults(bool clearPeerSearchResults) {
|
||||
if (clearPeerSearchResults) _peerSearchResults.clear();
|
||||
_searchResults.clear();
|
||||
_searchResultsLifetime.destroy();
|
||||
_searchedCount = _searchedMigratedCount = 0;
|
||||
_lastSearchDate = 0;
|
||||
_lastSearchPeer = nullptr;
|
||||
_lastSearchId = _lastSearchMigratedId = 0;
|
||||
}
|
||||
|
||||
void InnerWidget::trackSearchResultsHistory(not_null<History*> history) {
|
||||
const auto channel = history->peer->asChannel();
|
||||
if (!channel || channel->isBroadcast()) {
|
||||
return;
|
||||
}
|
||||
channel->flagsValue(
|
||||
) | rpl::skip(
|
||||
1
|
||||
) | rpl::filter([=](const ChannelData::Flags::Change &change) {
|
||||
return (change.diff & ChannelDataFlag::Forum);
|
||||
}) | rpl::start_with_next([=] {
|
||||
for (const auto &row : _searchResults) {
|
||||
if (row->item()->history()->peer == channel) {
|
||||
row->invalidateTopic();
|
||||
}
|
||||
}
|
||||
update();
|
||||
}, _searchResultsLifetime);
|
||||
|
||||
if (const auto forum = channel->forum()) {
|
||||
forum->topicDestroyed(
|
||||
) | rpl::start_with_next([=](not_null<Data::ForumTopic*> topic) {
|
||||
const auto from = ranges::remove(
|
||||
_searchResults,
|
||||
topic.get(),
|
||||
&FakeRow::topic);
|
||||
if (from != end(_searchResults)) {
|
||||
_searchResults.erase(from, end(_searchResults));
|
||||
refresh(true);
|
||||
clearMouseSelection(true);
|
||||
}
|
||||
}, _searchResultsLifetime);
|
||||
}
|
||||
}
|
||||
|
||||
PeerData *InnerWidget::updateFromParentDrag(QPoint globalPosition) {
|
||||
|
@ -2210,8 +2243,8 @@ bool InnerWidget::hasHistoryInResults(not_null<History*> history) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool InnerWidget::searchReceived(
|
||||
const QVector<MTPMessage> &messages,
|
||||
void InnerWidget::searchReceived(
|
||||
std::vector<not_null<HistoryItem*>> messages,
|
||||
HistoryItem *inject,
|
||||
SearchRequestType type,
|
||||
int fullCount) {
|
||||
|
@ -2219,10 +2252,12 @@ bool InnerWidget::searchReceived(
|
|||
if (type == SearchRequestType::FromStart || type == SearchRequestType::PeerFromStart) {
|
||||
clearSearchResults(false);
|
||||
}
|
||||
auto isGlobalSearch = (type == SearchRequestType::FromStart || type == SearchRequestType::FromOffset);
|
||||
auto isMigratedSearch = (type == SearchRequestType::MigratedFromStart || type == SearchRequestType::MigratedFromOffset);
|
||||
const auto isMigratedSearch = (type == SearchRequestType::MigratedFromStart)
|
||||
|| (type == SearchRequestType::MigratedFromOffset);
|
||||
|
||||
TimeId lastDateFound = 0;
|
||||
const auto key = _openedForum
|
||||
? Key(_openedForum->history())
|
||||
: _searchInChat;
|
||||
if (inject
|
||||
&& (!_searchInChat
|
||||
|| inject->history() == _searchInChat.history())) {
|
||||
|
@ -2230,49 +2265,25 @@ bool InnerWidget::searchReceived(
|
|||
const auto index = int(_searchResults.size());
|
||||
_searchResults.push_back(
|
||||
std::make_unique<FakeRow>(
|
||||
_searchInChat,
|
||||
key,
|
||||
inject,
|
||||
[=] { repaintSearchResult(index); }));
|
||||
trackSearchResultsHistory(inject->history());
|
||||
++fullCount;
|
||||
}
|
||||
for (const auto &message : messages) {
|
||||
auto msgId = IdFromMessage(message);
|
||||
auto peerId = PeerFromMessage(message);
|
||||
auto lastDate = DateFromMessage(message);
|
||||
if (const auto peer = session().data().peerLoaded(peerId)) {
|
||||
if (lastDate) {
|
||||
const auto item = session().data().addNewMessage(
|
||||
message,
|
||||
MessageFlags(),
|
||||
NewMessageType::Existing);
|
||||
const auto history = item->history();
|
||||
if (!uniquePeers || !hasHistoryInResults(history)) {
|
||||
const auto index = int(_searchResults.size());
|
||||
_searchResults.push_back(
|
||||
std::make_unique<FakeRow>(
|
||||
_searchInChat,
|
||||
item,
|
||||
[=] { repaintSearchResult(index); }));
|
||||
if (uniquePeers && !history->unreadCountKnown()) {
|
||||
history->owner().histories().requestDialogEntry(history);
|
||||
}
|
||||
}
|
||||
lastDateFound = lastDate;
|
||||
if (isGlobalSearch) {
|
||||
_lastSearchDate = lastDateFound;
|
||||
}
|
||||
for (const auto &item : messages) {
|
||||
const auto history = item->history();
|
||||
if (!uniquePeers || !hasHistoryInResults(history)) {
|
||||
const auto index = int(_searchResults.size());
|
||||
_searchResults.push_back(
|
||||
std::make_unique<FakeRow>(
|
||||
key,
|
||||
item,
|
||||
[=] { repaintSearchResult(index); }));
|
||||
trackSearchResultsHistory(history);
|
||||
if (uniquePeers && !history->unreadCountKnown()) {
|
||||
history->owner().histories().requestDialogEntry(history);
|
||||
}
|
||||
if (isGlobalSearch) {
|
||||
_lastSearchPeer = peer;
|
||||
}
|
||||
} else {
|
||||
LOG(("API Error: a search results with not loaded peer %1"
|
||||
).arg(peerId.value));
|
||||
}
|
||||
if (isMigratedSearch) {
|
||||
_lastSearchMigratedId = msgId;
|
||||
} else {
|
||||
_lastSearchId = msgId;
|
||||
}
|
||||
}
|
||||
if (isMigratedSearch) {
|
||||
|
@ -2289,8 +2300,6 @@ bool InnerWidget::searchReceived(
|
|||
}
|
||||
|
||||
refresh();
|
||||
|
||||
return lastDateFound != 0;
|
||||
}
|
||||
|
||||
void InnerWidget::peerSearchReceived(
|
||||
|
@ -2397,9 +2406,9 @@ void InnerWidget::refresh(bool toTop) {
|
|||
}
|
||||
} else if (_state == WidgetState::Filtered) {
|
||||
if (_waitingForSearch) {
|
||||
h = searchedOffset() + (_searchResults.size() * st::dialogsRowHeight) + ((_searchResults.empty() && !_searchInChat) ? -st::searchedBarHeight : 0);
|
||||
h = searchedOffset() + (_searchResults.size() * _st->height) + ((_searchResults.empty() && !_searchInChat) ? -st::searchedBarHeight : 0);
|
||||
} else {
|
||||
h = searchedOffset() + (_searchResults.size() * st::dialogsRowHeight);
|
||||
h = searchedOffset() + (_searchResults.size() * _st->height);
|
||||
}
|
||||
}
|
||||
resize(width(), h);
|
||||
|
@ -2585,9 +2594,9 @@ void InnerWidget::refreshSearchInChatLabel() {
|
|||
void InnerWidget::repaintSearchResult(int index) {
|
||||
rtlupdate(
|
||||
0,
|
||||
searchedOffset() + index * st::dialogsRowHeight,
|
||||
searchedOffset() + index * _st->height,
|
||||
width(),
|
||||
st::dialogsRowHeight);
|
||||
_st->height);
|
||||
}
|
||||
|
||||
void InnerWidget::clearFilter() {
|
||||
|
@ -2603,9 +2612,6 @@ void InnerWidget::clearFilter() {
|
|||
_filterResultsGlobal.clear();
|
||||
_peerSearchResults.clear();
|
||||
_searchResults.clear();
|
||||
_lastSearchDate = 0;
|
||||
_lastSearchPeer = nullptr;
|
||||
_lastSearchId = _lastSearchMigratedId = 0;
|
||||
_filter = QString();
|
||||
refresh(true);
|
||||
}
|
||||
|
@ -2718,10 +2724,10 @@ void InnerWidget::selectSkip(int32 direction) {
|
|||
} else {
|
||||
_mustScrollTo.fire({
|
||||
searchedOffset()
|
||||
+ _searchedSelected * st::dialogsRowHeight
|
||||
+ _searchedSelected * _st->height
|
||||
+ (_searchedSelected ? 0 : -st::searchedBarHeight),
|
||||
searchedOffset()
|
||||
+ (_searchedSelected + 1) * st::dialogsRowHeight,
|
||||
+ (_searchedSelected + 1) * _st->height,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -2738,8 +2744,8 @@ void InnerWidget::scrollToEntry(const RowDescriptor &entry) {
|
|||
} else if (_state == WidgetState::Filtered) {
|
||||
for (int32 i = 0, c = _searchResults.size(); i < c; ++i) {
|
||||
if (isSearchResultActive(_searchResults[i].get(), entry)) {
|
||||
fromY = searchedOffset() + i * st::dialogsRowHeight;
|
||||
rowHeight = st::dialogsRowHeight;
|
||||
fromY = searchedOffset() + i * _st->height;
|
||||
rowHeight = _st->height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2936,9 +2942,11 @@ ChosenRow InnerWidget::computeChosenRow() const {
|
|||
};
|
||||
} else if (base::in_range(_searchedSelected, 0, _searchResults.size())) {
|
||||
const auto result = _searchResults[_searchedSelected].get();
|
||||
const auto topic = result->topic();
|
||||
const auto item = result->item();
|
||||
return {
|
||||
result->item()->history(),
|
||||
result->item()->position()
|
||||
(topic ? (Entry*)topic : (Entry*)item->history()),
|
||||
item->position()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -3168,22 +3176,6 @@ RowDescriptor InnerWidget::chatListEntryLast() const {
|
|||
return RowDescriptor();
|
||||
}
|
||||
|
||||
int32 InnerWidget::lastSearchDate() const {
|
||||
return _lastSearchDate;
|
||||
}
|
||||
|
||||
PeerData *InnerWidget::lastSearchPeer() const {
|
||||
return _lastSearchPeer;
|
||||
}
|
||||
|
||||
MsgId InnerWidget::lastSearchId() const {
|
||||
return _lastSearchId;
|
||||
}
|
||||
|
||||
MsgId InnerWidget::lastSearchMigratedId() const {
|
||||
return _lastSearchMigratedId;
|
||||
}
|
||||
|
||||
void InnerWidget::setupOnlineStatusCheck() {
|
||||
session().changes().peerUpdates(
|
||||
Data::PeerUpdate::Flag::OnlineStatus
|
||||
|
|
|
@ -85,8 +85,8 @@ public:
|
|||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller);
|
||||
|
||||
bool searchReceived(
|
||||
const QVector<MTPMessage> &result,
|
||||
void searchReceived(
|
||||
std::vector<not_null<HistoryItem*>> result,
|
||||
HistoryItem *inject,
|
||||
SearchRequestType type,
|
||||
int fullCount);
|
||||
|
@ -117,10 +117,6 @@ public:
|
|||
|
||||
[[nodiscard]] Data::Folder *shownFolder() const;
|
||||
[[nodiscard]] Data::Forum *shownForum() const;
|
||||
[[nodiscard]] int32 lastSearchDate() const;
|
||||
[[nodiscard]] PeerData *lastSearchPeer() const;
|
||||
[[nodiscard]] MsgId lastSearchId() const;
|
||||
[[nodiscard]] MsgId lastSearchMigratedId() const;
|
||||
|
||||
[[nodiscard]] WidgetState state() const;
|
||||
[[nodiscard]] not_null<const style::DialogRow*> st() const {
|
||||
|
@ -333,6 +329,8 @@ private:
|
|||
|
||||
void clearSearchResults(bool clearPeerSearchResults = true);
|
||||
void updateSelectedRow(Key key = Key());
|
||||
void trackSearchResultsHistory(not_null<History*> history);
|
||||
void trackSearchResultsForum(Data::Forum *forum);
|
||||
|
||||
[[nodiscard]] not_null<IndexedList*> shownDialogs() const;
|
||||
|
||||
|
@ -406,16 +404,12 @@ private:
|
|||
int _peerSearchPressed = -1;
|
||||
|
||||
std::vector<std::unique_ptr<FakeRow>> _searchResults;
|
||||
rpl::lifetime _searchResultsLifetime;
|
||||
int _searchedCount = 0;
|
||||
int _searchedMigratedCount = 0;
|
||||
int _searchedSelected = -1;
|
||||
int _searchedPressed = -1;
|
||||
|
||||
int _lastSearchDate = 0;
|
||||
PeerData *_lastSearchPeer = nullptr;
|
||||
MsgId _lastSearchId = 0;
|
||||
MsgId _lastSearchMigratedId = 0;
|
||||
|
||||
WidgetState _state = WidgetState::Default;
|
||||
|
||||
object_ptr<Ui::FlatLabel> _empty = { nullptr };
|
||||
|
|
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "dialogs/ui/dialogs_video_userpic.h"
|
||||
#include "dialogs/ui/dialogs_layout.h"
|
||||
#include "data/data_folder.h"
|
||||
#include "data/data_forum.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_peer_values.h"
|
||||
#include "history/history.h"
|
||||
|
@ -351,6 +352,25 @@ FakeRow::FakeRow(
|
|||
: _searchInChat(searchInChat)
|
||||
, _item(item)
|
||||
, _repaint(std::move(repaint)) {
|
||||
invalidateTopic();
|
||||
}
|
||||
|
||||
void FakeRow::invalidateTopic() {
|
||||
_topic = _item->topic();
|
||||
if (_topic) {
|
||||
return;
|
||||
} else if (const auto rootId = _item->topicRootId()) {
|
||||
if (const auto forum = _item->history()->peer->forum()) {
|
||||
if (!forum->topicDeleted(rootId)) {
|
||||
forum->requestTopic(rootId, crl::guard(this, [=] {
|
||||
_topic = _item->topic();
|
||||
if (_topic) {
|
||||
_repaint();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Ui::Text::String &FakeRow::name() const {
|
||||
|
|
|
@ -147,7 +147,7 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class FakeRow : public BasicRow {
|
||||
class FakeRow final : public BasicRow, public base::has_weak_ptr {
|
||||
public:
|
||||
FakeRow(
|
||||
Key searchInChat,
|
||||
|
@ -157,6 +157,9 @@ public:
|
|||
[[nodiscard]] Key searchInChat() const {
|
||||
return _searchInChat;
|
||||
}
|
||||
[[nodiscard]] Data::ForumTopic *topic() const {
|
||||
return _topic;
|
||||
}
|
||||
[[nodiscard]] not_null<HistoryItem*> item() const {
|
||||
return _item;
|
||||
}
|
||||
|
@ -171,11 +174,14 @@ public:
|
|||
}
|
||||
[[nodiscard]] const Ui::Text::String &name() const;
|
||||
|
||||
void invalidateTopic();
|
||||
|
||||
private:
|
||||
friend class Ui::RowPainter;
|
||||
|
||||
const Key _searchInChat;
|
||||
const not_null<HistoryItem*> _item;
|
||||
Data::ForumTopic *_topic = nullptr;
|
||||
const Fn<void()> _repaint;
|
||||
mutable Ui::MessageView _itemView;
|
||||
mutable Ui::PeerBadge _badge;
|
||||
|
|
|
@ -344,7 +344,9 @@ Widget::Widget(
|
|||
setupMainMenuToggle();
|
||||
setupShortcuts();
|
||||
|
||||
_searchForNarrowFilters->setClickedCallback([=] { Ui::showChatsList(&session()); });
|
||||
_searchForNarrowFilters->setClickedCallback([=] {
|
||||
Ui::showChatsList(&session());
|
||||
});
|
||||
|
||||
setAcceptDrops(true);
|
||||
|
||||
|
@ -446,7 +448,11 @@ void Widget::chosenRow(const ChosenRow &row) {
|
|||
controller()->openFolder(folder);
|
||||
}
|
||||
if (openSearchResult && !session().supportMode()) {
|
||||
escape();
|
||||
if (_subsectionTopBar) {
|
||||
_subsectionTopBar->toggleSearch(false, anim::type::instant);
|
||||
} else {
|
||||
escape();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1336,15 +1342,13 @@ void Widget::searchMore() {
|
|||
return;
|
||||
}
|
||||
if (!_searchFull) {
|
||||
auto offsetPeer = _inner->lastSearchPeer();
|
||||
auto offsetId = _inner->lastSearchId();
|
||||
if (const auto peer = searchInPeer()) {
|
||||
auto &histories = session().data().histories();
|
||||
const auto topic = searchInTopic();
|
||||
const auto type = Data::Histories::RequestType::History;
|
||||
const auto history = session().data().history(peer);
|
||||
_searchInHistoryRequest = histories.sendRequest(history, type, [=](Fn<void()> finish) {
|
||||
const auto type = offsetId
|
||||
const auto type = _lastSearchId
|
||||
? SearchRequestType::PeerFromOffset
|
||||
: SearchRequestType::PeerFromStart;
|
||||
using Flag = MTPmessages_Search::Flag;
|
||||
|
@ -1356,11 +1360,11 @@ void Widget::searchMore() {
|
|||
(_searchQueryFrom
|
||||
? _searchQueryFrom->input
|
||||
: MTP_inputPeerEmpty()),
|
||||
MTPint(), // top_msg_id
|
||||
MTP_int(topic ? topic->rootId() : 0),
|
||||
MTP_inputMessagesFilterEmpty(),
|
||||
MTP_int(0), // min_date
|
||||
MTP_int(0), // max_date
|
||||
MTP_int(offsetId),
|
||||
MTP_int(_lastSearchId),
|
||||
MTP_int(0), // add_offset
|
||||
MTP_int(kSearchPerPage),
|
||||
MTP_int(0), // max_id
|
||||
|
@ -1375,13 +1379,13 @@ void Widget::searchMore() {
|
|||
_searchInHistoryRequest = 0;
|
||||
finish();
|
||||
}).send();
|
||||
if (!offsetId) {
|
||||
if (!_lastSearchId) {
|
||||
_searchQueries.emplace(_searchRequest, _searchQuery);
|
||||
}
|
||||
return _searchRequest;
|
||||
});
|
||||
} else {
|
||||
const auto type = offsetId
|
||||
const auto type = _lastSearchId
|
||||
? SearchRequestType::FromOffset
|
||||
: SearchRequestType::FromStart;
|
||||
const auto flags = session().settings().skipArchiveInSearch()
|
||||
|
@ -1396,27 +1400,26 @@ void Widget::searchMore() {
|
|||
MTP_int(0), // min_date
|
||||
MTP_int(0), // max_date
|
||||
MTP_int(_searchNextRate),
|
||||
offsetPeer
|
||||
? offsetPeer->input
|
||||
: MTP_inputPeerEmpty(),
|
||||
MTP_int(offsetId),
|
||||
(_lastSearchPeer
|
||||
? _lastSearchPeer->input
|
||||
: MTP_inputPeerEmpty()),
|
||||
MTP_int(_lastSearchId),
|
||||
MTP_int(kSearchPerPage)
|
||||
)).done([=](const MTPmessages_Messages &result) {
|
||||
searchReceived(type, result, _searchRequest);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
searchFailed(type, error, _searchRequest);
|
||||
}).send();
|
||||
if (!offsetId) {
|
||||
if (!_lastSearchId) {
|
||||
_searchQueries.emplace(_searchRequest, _searchQuery);
|
||||
}
|
||||
}
|
||||
} else if (_searchInMigrated && !_searchFullMigrated) {
|
||||
auto offsetMigratedId = _inner->lastSearchMigratedId();
|
||||
auto &histories = session().data().histories();
|
||||
const auto type = Data::Histories::RequestType::History;
|
||||
const auto history = _searchInMigrated;
|
||||
_searchInHistoryRequest = histories.sendRequest(history, type, [=](Fn<void()> finish) {
|
||||
const auto type = offsetMigratedId
|
||||
const auto type = _lastSearchMigratedId
|
||||
? SearchRequestType::MigratedFromOffset
|
||||
: SearchRequestType::MigratedFromStart;
|
||||
const auto flags = _searchQueryFrom
|
||||
|
@ -1433,7 +1436,7 @@ void Widget::searchMore() {
|
|||
MTP_inputMessagesFilterEmpty(),
|
||||
MTP_int(0), // min_date
|
||||
MTP_int(0), // max_date
|
||||
MTP_int(offsetMigratedId),
|
||||
MTP_int(_lastSearchMigratedId),
|
||||
MTP_int(0), // add_offset
|
||||
MTP_int(kSearchPerPage),
|
||||
MTP_int(0), // max_id
|
||||
|
@ -1475,37 +1478,69 @@ void Widget::searchReceived(
|
|||
if (_searchRequest != requestId) {
|
||||
return;
|
||||
}
|
||||
switch (result.type()) {
|
||||
case mtpc_messages_messages: {
|
||||
auto &d = result.c_messages_messages();
|
||||
if (type == SearchRequestType::FromStart
|
||||
|| type == SearchRequestType::PeerFromStart) {
|
||||
_lastSearchPeer = nullptr;
|
||||
_lastSearchId = _lastSearchMigratedId = 0;
|
||||
}
|
||||
const auto isGlobalSearch = (type == SearchRequestType::FromStart)
|
||||
|| (type == SearchRequestType::FromOffset);
|
||||
const auto isMigratedSearch = (type == SearchRequestType::MigratedFromStart)
|
||||
|| (type == SearchRequestType::MigratedFromOffset);
|
||||
const auto process = [&](const MTPVector<MTPMessage> &messages) {
|
||||
auto result = std::vector<not_null<HistoryItem*>>();
|
||||
for (const auto &message : messages.v) {
|
||||
const auto msgId = IdFromMessage(message);
|
||||
const auto peerId = PeerFromMessage(message);
|
||||
const auto lastDate = DateFromMessage(message);
|
||||
if (const auto peer = session().data().peerLoaded(peerId)) {
|
||||
if (lastDate) {
|
||||
const auto item = session().data().addNewMessage(
|
||||
message,
|
||||
MessageFlags(),
|
||||
NewMessageType::Existing);
|
||||
result.push_back(item);
|
||||
}
|
||||
_lastSearchPeer = peer;
|
||||
} else {
|
||||
LOG(("API Error: a search results with not loaded peer %1"
|
||||
).arg(peerId.value));
|
||||
}
|
||||
if (isMigratedSearch) {
|
||||
_lastSearchMigratedId = msgId;
|
||||
} else {
|
||||
_lastSearchId = msgId;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
auto fullCount = 0;
|
||||
auto messages = result.match([&](const MTPDmessages_messages &data) {
|
||||
if (_searchRequest != 0) {
|
||||
// Don't apply cached data!
|
||||
session().data().processUsers(d.vusers());
|
||||
session().data().processChats(d.vchats());
|
||||
session().data().processUsers(data.vusers());
|
||||
session().data().processChats(data.vchats());
|
||||
}
|
||||
auto &msgs = d.vmessages().v;
|
||||
_inner->searchReceived(msgs, inject, type, msgs.size());
|
||||
if (type == SearchRequestType::MigratedFromStart || type == SearchRequestType::MigratedFromOffset) {
|
||||
_searchFullMigrated = true;
|
||||
} else {
|
||||
_searchFull = true;
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_messages_messagesSlice: {
|
||||
auto &d = result.c_messages_messagesSlice();
|
||||
auto list = process(data.vmessages());
|
||||
fullCount = list.size();
|
||||
return list;
|
||||
}, [&](const MTPDmessages_messagesSlice &data) {
|
||||
if (_searchRequest != 0) {
|
||||
// Don't apply cached data!
|
||||
session().data().processUsers(d.vusers());
|
||||
session().data().processChats(d.vchats());
|
||||
session().data().processUsers(data.vusers());
|
||||
session().data().processChats(data.vchats());
|
||||
}
|
||||
auto &msgs = d.vmessages().v;
|
||||
const auto someAdded = _inner->searchReceived(msgs, inject, type, d.vcount().v);
|
||||
const auto nextRate = d.vnext_rate();
|
||||
auto list = process(data.vmessages());
|
||||
const auto nextRate = data.vnext_rate();
|
||||
const auto rateUpdated = nextRate && (nextRate->v != _searchNextRate);
|
||||
const auto finished = (type == SearchRequestType::FromStart || type == SearchRequestType::FromOffset)
|
||||
? !rateUpdated
|
||||
: !someAdded;
|
||||
: list.empty();
|
||||
if (rateUpdated) {
|
||||
_searchNextRate = nextRate->v;
|
||||
}
|
||||
|
@ -1516,13 +1551,12 @@ void Widget::searchReceived(
|
|||
_searchFull = true;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_messages_channelMessages: {
|
||||
auto &d = result.c_messages_channelMessages();
|
||||
if (const auto peer = _openedForum ? _openedForum : _searchInChat.peer()) {
|
||||
fullCount = data.vcount().v;
|
||||
return list;
|
||||
}, [&](const MTPDmessages_channelMessages &data) {
|
||||
if (const auto peer = searchInPeer()) {
|
||||
if (const auto channel = peer->asChannel()) {
|
||||
channel->ptsReceived(d.vpts().v);
|
||||
channel->ptsReceived(data.vpts().v);
|
||||
} else {
|
||||
LOG(("API Error: "
|
||||
"received messages.channelMessages when no channel "
|
||||
|
@ -1535,28 +1569,29 @@ void Widget::searchReceived(
|
|||
}
|
||||
if (_searchRequest != 0) {
|
||||
// Don't apply cached data!
|
||||
session().data().processUsers(d.vusers());
|
||||
session().data().processChats(d.vchats());
|
||||
session().data().processUsers(data.vusers());
|
||||
session().data().processChats(data.vchats());
|
||||
}
|
||||
auto &msgs = d.vmessages().v;
|
||||
if (!_inner->searchReceived(msgs, inject, type, d.vcount().v)) {
|
||||
auto list = process(data.vmessages());
|
||||
if (list.empty()) {
|
||||
if (type == SearchRequestType::MigratedFromStart || type == SearchRequestType::MigratedFromOffset) {
|
||||
_searchFullMigrated = true;
|
||||
} else {
|
||||
_searchFull = true;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_messages_messagesNotModified: {
|
||||
fullCount = data.vcount().v;
|
||||
return list;
|
||||
}, [&](const MTPDmessages_messagesNotModified &) {
|
||||
LOG(("API Error: received messages.messagesNotModified! (Widget::searchReceived)"));
|
||||
if (type == SearchRequestType::MigratedFromStart || type == SearchRequestType::MigratedFromOffset) {
|
||||
_searchFullMigrated = true;
|
||||
} else {
|
||||
_searchFull = true;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
return std::vector<not_null<HistoryItem*>>();
|
||||
});
|
||||
_inner->searchReceived(messages, inject, type, fullCount);
|
||||
|
||||
_searchRequest = 0;
|
||||
listScrollUpdated();
|
||||
|
@ -1808,8 +1843,10 @@ void Widget::showCalendar() {
|
|||
}
|
||||
|
||||
void Widget::showSearchFrom() {
|
||||
if (const auto peer = _searchInChat.peer()) {
|
||||
const auto chat = _searchInChat;
|
||||
if (const auto peer = searchInPeer()) {
|
||||
const auto chat = _openedForum
|
||||
? Key(_openedForum->forum()->history())
|
||||
: _searchInChat;
|
||||
auto box = SearchFromBox(
|
||||
peer,
|
||||
crl::guard(this, [=](not_null<PeerData*> from) {
|
||||
|
@ -1914,7 +1951,7 @@ void Widget::updateJumpToDateVisibility(bool fast) {
|
|||
|
||||
void Widget::updateSearchFromVisibility(bool fast) {
|
||||
auto visible = [&] {
|
||||
if (const auto peer = _searchInChat.peer()) {
|
||||
if (const auto peer = searchInPeer()) {
|
||||
if (peer->isChat() || peer->isMegagroup()) {
|
||||
return !_searchFromAuthor;
|
||||
}
|
||||
|
@ -2197,6 +2234,8 @@ bool Widget::cancelSearch() {
|
|||
setFocus();
|
||||
return true;
|
||||
}
|
||||
_lastSearchPeer = nullptr;
|
||||
_lastSearchId = _lastSearchMigratedId = 0;
|
||||
_inner->clearFilter();
|
||||
clearSearchField();
|
||||
applyFilterUpdate();
|
||||
|
|
|
@ -252,6 +252,10 @@ private:
|
|||
int _searchInHistoryRequest = 0; // Not real mtpRequestId.
|
||||
mtpRequestId _searchRequest = 0;
|
||||
|
||||
PeerData *_lastSearchPeer = nullptr;
|
||||
MsgId _lastSearchId = 0;
|
||||
MsgId _lastSearchMigratedId = 0;
|
||||
|
||||
base::flat_map<QString, MTPmessages_Messages> _searchCache;
|
||||
Api::SingleMessageSearch _singleMessageSearch;
|
||||
base::flat_map<mtpRequestId, QString> _searchQueries;
|
||||
|
|
|
@ -243,7 +243,6 @@ void PaintRow(
|
|||
Painter &p,
|
||||
not_null<const BasicRow*> row,
|
||||
not_null<Entry*> entry,
|
||||
Dialogs::Key chat,
|
||||
VideoUserpic *videoUserpic,
|
||||
PeerData *from,
|
||||
Ui::PeerBadge &fromBadge,
|
||||
|
@ -274,8 +273,8 @@ void PaintRow(
|
|||
p.fillRect(fullRect, bg);
|
||||
row->paintRipple(p, 0, 0, context.width, &ripple->c);
|
||||
|
||||
const auto history = chat.history();
|
||||
const auto thread = chat.thread();
|
||||
const auto history = entry->asHistory();
|
||||
const auto thread = entry->asThread();
|
||||
|
||||
if (flags & Flag::SavedMessages) {
|
||||
EmptyUserpic::PaintSavedMessages(
|
||||
|
@ -512,7 +511,7 @@ void PaintRow(
|
|||
if (!thread) {
|
||||
return nullptr;
|
||||
} else if (const auto topic = thread->asTopic()
|
||||
; topic && topic->closed()) {
|
||||
; !context.search && topic && topic->closed()) {
|
||||
return &(context.active
|
||||
? st::dialogsLockIconActive
|
||||
: context.selected
|
||||
|
@ -927,11 +926,10 @@ void RowPainter::Paint(
|
|||
p,
|
||||
row,
|
||||
entry,
|
||||
row->key(),
|
||||
videoUserpic,
|
||||
from,
|
||||
entry->chatListPeerBadge(),
|
||||
[=] { history->updateChatListEntry(); },
|
||||
[=] { entry->updateChatListEntry(); },
|
||||
entry->chatListNameText(),
|
||||
nullptr,
|
||||
item,
|
||||
|
@ -947,14 +945,17 @@ void RowPainter::Paint(
|
|||
Painter &p,
|
||||
not_null<const FakeRow*> row,
|
||||
const PaintContext &context) {
|
||||
auto item = row->item();
|
||||
auto history = item->history();
|
||||
const auto item = row->item();
|
||||
const auto topic = context.forum ? row->topic() : nullptr;
|
||||
const auto history = topic ? nullptr : item->history().get();
|
||||
const auto entry = topic ? (Entry*)topic : (Entry*)history;
|
||||
auto cloudDraft = nullptr;
|
||||
const auto from = [&] {
|
||||
if (row->searchInChat()) {
|
||||
return item->displayFrom();
|
||||
}
|
||||
return history->peer->migrateTo()
|
||||
return topic
|
||||
? nullptr
|
||||
: row->searchInChat()
|
||||
? item->displayFrom()
|
||||
: history->peer->migrateTo()
|
||||
? history->peer->migrateTo()
|
||||
: history->peer.get();
|
||||
}();
|
||||
|
@ -971,7 +972,9 @@ void RowPainter::Paint(
|
|||
return nullptr;
|
||||
}();
|
||||
const auto previewOptions = [&]() -> HistoryView::ToPreviewOptions {
|
||||
if (const auto searchChat = row->searchInChat()) {
|
||||
if (topic) {
|
||||
return {};
|
||||
} else if (const auto searchChat = row->searchInChat()) {
|
||||
if (const auto peer = searchChat.peer()) {
|
||||
if (!peer->isChannel() || peer->isMegagroup()) {
|
||||
return { .hideSender = true };
|
||||
|
@ -982,7 +985,7 @@ void RowPainter::Paint(
|
|||
}();
|
||||
|
||||
const auto badgesState = context.displayUnreadInfo
|
||||
? history->chatListBadgesState()
|
||||
? entry->chatListBadgesState()
|
||||
: BadgesState();
|
||||
const auto displayPinnedIcon = false;
|
||||
|
||||
|
@ -1007,17 +1010,18 @@ void RowPainter::Paint(
|
|||
}
|
||||
row->itemView().paint(p, itemRect, context);
|
||||
};
|
||||
const auto showSavedMessages = history->peer->isSelf()
|
||||
const auto showSavedMessages = history
|
||||
&& history->peer->isSelf()
|
||||
&& !row->searchInChat();
|
||||
const auto showRepliesMessages = history->peer->isRepliesChat()
|
||||
const auto showRepliesMessages = history
|
||||
&& history->peer->isRepliesChat()
|
||||
&& !row->searchInChat();
|
||||
const auto flags = (showSavedMessages ? Flag::SavedMessages : Flag(0))
|
||||
| (showRepliesMessages ? Flag::RepliesMessages : Flag(0));
|
||||
PaintRow(
|
||||
p,
|
||||
row,
|
||||
history,
|
||||
history,
|
||||
entry,
|
||||
nullptr,
|
||||
from,
|
||||
row->badge(),
|
||||
|
|
|
@ -334,8 +334,7 @@ HistoryMessage::HistoryMessage(
|
|||
config.replyTo = data.is_reply_to_scheduled()
|
||||
? history->owner().scheduledMessages().localMessageId(id)
|
||||
: id;
|
||||
config.replyToTop = data.vreply_to_top_id().value_or(
|
||||
data.vreply_to_msg_id().v);
|
||||
config.replyToTop = data.vreply_to_top_id().value_or(id);
|
||||
config.replyIsTopicPost = data.is_forum_topic();
|
||||
});
|
||||
}
|
||||
|
@ -385,9 +384,9 @@ HistoryMessage::HistoryMessage(
|
|||
? peerFromMTP(*data.vreply_to_peer_id())
|
||||
: history->peer->id;
|
||||
if (!peer || peer == history->peer->id) {
|
||||
config.replyTo = data.vreply_to_msg_id().v;
|
||||
config.replyToTop = data.vreply_to_top_id().value_or(
|
||||
data.vreply_to_msg_id().v);
|
||||
const auto id = data.vreply_to_msg_id().v;
|
||||
config.replyTo = id;
|
||||
config.replyToTop = data.vreply_to_top_id().value_or(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1607,9 +1607,9 @@ void HistoryService::createFromMtp(const MTPDmessageService &message) {
|
|||
dependent->peerId = (peerId != history()->peer->id)
|
||||
? peerId
|
||||
: 0;
|
||||
dependent->msgId = data.vreply_to_msg_id().v;
|
||||
dependent->topId = data.vreply_to_top_id().value_or(
|
||||
data.vreply_to_msg_id().v);
|
||||
const auto id = data.vreply_to_msg_id().v;
|
||||
dependent->msgId = id;
|
||||
dependent->topId = data.vreply_to_top_id().value_or(id);
|
||||
dependent->topicPost = data.is_forum_topic()
|
||||
|| Has<HistoryServiceTopicInfo>();
|
||||
if (!updateDependent()) {
|
||||
|
|
Loading…
Add table
Reference in a new issue