mirror of https://github.com/procxx/kepka.git
Support feeds search display in dialogs list.
This commit is contained in:
parent
98fb874b29
commit
0f775e1e66
|
@ -12,6 +12,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_session.h"
|
||||
|
||||
namespace Data {
|
||||
namespace {
|
||||
|
||||
constexpr auto kMaxItemsInGroup = 10;
|
||||
|
||||
} // namespace
|
||||
|
||||
Groups::Groups(not_null<Session*> data) : _data(data) {
|
||||
}
|
||||
|
@ -30,9 +35,11 @@ void Groups::registerMessage(not_null<HistoryItem*> item) {
|
|||
}
|
||||
const auto i = _groups.emplace(item->groupId(), Group()).first;
|
||||
auto &items = i->second.items;
|
||||
items.insert(findPositionForItem(items, item), item);
|
||||
if (items.size() > 1) {
|
||||
refreshViews(items);
|
||||
if (items.size() < kMaxItemsInGroup) {
|
||||
items.insert(findPositionForItem(items, item), item);
|
||||
if (items.size() > 1) {
|
||||
refreshViews(items);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,9 @@ PeerClickHandler::PeerClickHandler(not_null<PeerData*> peer)
|
|||
void PeerClickHandler::onClick(Qt::MouseButton button) const {
|
||||
if (button == Qt::LeftButton && App::wnd()) {
|
||||
auto controller = App::wnd()->controller();
|
||||
if (_peer && _peer->isChannel() && controller->historyPeer.current() != _peer) {
|
||||
if (_peer
|
||||
&& _peer->isChannel()
|
||||
&& controller->activeChatCurrent().peer() != _peer) {
|
||||
if (!_peer->asChannel()->isPublic() && !_peer->asChannel()->amIn()) {
|
||||
Ui::show(Box<InformBox>(lang(_peer->isMegagroup()
|
||||
? lng_group_not_accessible
|
||||
|
|
|
@ -69,7 +69,7 @@ DialogsInner::DialogsInner(QWidget *parent, not_null<Window::Controller*> contro
|
|||
, _contacts(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
||||
, _a_pinnedShifting(animation(this, &DialogsInner::step_pinnedShifting))
|
||||
, _addContactLnk(this, lang(lng_add_contact_button))
|
||||
, _cancelSearchInPeer(this, st::dialogsCancelSearchInPeer)
|
||||
, _cancelSearchInChat(this, st::dialogsCancelSearchInPeer)
|
||||
, _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer) {
|
||||
|
||||
#ifdef OS_MAC_OLD
|
||||
|
@ -83,8 +83,8 @@ DialogsInner::DialogsInner(QWidget *parent, not_null<Window::Controller*> contro
|
|||
}
|
||||
connect(main, SIGNAL(dialogRowReplaced(Dialogs::Row*, Dialogs::Row*)), this, SLOT(onDialogRowReplaced(Dialogs::Row*, Dialogs::Row*)));
|
||||
connect(_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact()));
|
||||
_cancelSearchInPeer->setClickedCallback([this] { cancelSearchInPeer(); });
|
||||
_cancelSearchInPeer->hide();
|
||||
_cancelSearchInChat->setClickedCallback([this] { cancelSearchInChat(); });
|
||||
_cancelSearchInChat->hide();
|
||||
_cancelSearchFromUser->setClickedCallback([this] { searchFromUserChanged.notify(nullptr); });
|
||||
_cancelSearchFromUser->hide();
|
||||
|
||||
|
@ -175,13 +175,13 @@ int DialogsInner::peerSearchOffset() const {
|
|||
|
||||
int DialogsInner::searchedOffset() const {
|
||||
auto result = peerSearchOffset() + (_peerSearchResults.empty() ? 0 : ((_peerSearchResults.size() * st::dialogsRowHeight) + st::searchedBarHeight));
|
||||
if (_searchInPeer) {
|
||||
result += searchInPeerSkip();
|
||||
if (_searchInChat) {
|
||||
result += searchInChatSkip();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int DialogsInner::searchInPeerSkip() const {
|
||||
int DialogsInner::searchInChatSkip() const {
|
||||
auto result = st::searchedBarHeight + st::dialogsSearchInHeight;
|
||||
if (_searchFromUser) {
|
||||
result += st::lineWidth + st::dialogsSearchInHeight;
|
||||
|
@ -390,15 +390,24 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
|||
}
|
||||
}
|
||||
|
||||
if (_searchInPeer) {
|
||||
paintSearchInPeer(p, fullWidth, paintingOther, ms);
|
||||
p.translate(0, searchInPeerSkip());
|
||||
if (_searchInChat) {
|
||||
paintSearchInChat(p, fullWidth, paintingOther, ms);
|
||||
p.translate(0, searchInChatSkip());
|
||||
if (_waitingForSearch && _searchResults.empty()) {
|
||||
p.fillRect(0, 0, fullWidth, st::searchedBarHeight, st::searchedBarBg);
|
||||
p.fillRect(
|
||||
0,
|
||||
0,
|
||||
fullWidth,
|
||||
st::searchedBarHeight,
|
||||
st::searchedBarBg);
|
||||
if (!paintingOther) {
|
||||
p.setFont(st::searchedBarFont);
|
||||
p.setPen(st::searchedBarFg);
|
||||
p.drawTextLeft(st::searchedBarPosition.x(), st::searchedBarPosition.y(), width(), lang(lng_dlg_search_for_messages));
|
||||
p.drawTextLeft(
|
||||
st::searchedBarPosition.x(),
|
||||
st::searchedBarPosition.y(),
|
||||
width(),
|
||||
lang(lng_dlg_search_for_messages));
|
||||
}
|
||||
p.translate(0, st::searchedBarHeight);
|
||||
}
|
||||
|
@ -537,12 +546,12 @@ void DialogsInner::paintPeerSearchResult(
|
|||
peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
|
||||
}
|
||||
|
||||
void DialogsInner::paintSearchInPeer(
|
||||
void DialogsInner::paintSearchInChat(
|
||||
Painter &p,
|
||||
int fullWidth,
|
||||
bool onlyBackground,
|
||||
TimeMs ms) const {
|
||||
auto height = searchInPeerSkip();
|
||||
auto height = searchInChatSkip();
|
||||
|
||||
auto top = st::searchedBarHeight;
|
||||
p.fillRect(0, 0, fullWidth, top, st::searchedBarBg);
|
||||
|
@ -560,44 +569,39 @@ void DialogsInner::paintSearchInPeer(
|
|||
if (onlyBackground) return;
|
||||
|
||||
p.setPen(st::dialogsNameFg);
|
||||
if (_searchInPeer->isSelf()) {
|
||||
paintSearchInFilter(p, nullptr, top, fullWidth, _searchInSavedText);
|
||||
if (const auto peer = _searchInChat.peer()) {
|
||||
if (peer->isSelf()) {
|
||||
paintSearchInSaved(p, top, fullWidth, _searchInChatText);
|
||||
} else {
|
||||
paintSearchInPeer(p, peer, top, fullWidth, _searchInChatText);
|
||||
}
|
||||
} else if (const auto feed = _searchInChat.feed()) {
|
||||
paintSearchInFeed(p, feed, top, fullWidth, _searchInChatText);
|
||||
} else {
|
||||
paintSearchInFilter(p, _searchInPeer, top, fullWidth, _searchInPeer->nameText);
|
||||
Unexpected("Empty Dialogs::Key in paintSearchInChat.");
|
||||
}
|
||||
if (_searchFromUser) {
|
||||
if (const auto from = _searchFromUser) {
|
||||
top += st::dialogsSearchInHeight + st::lineWidth;
|
||||
p.setPen(st::dialogsTextFg);
|
||||
p.setTextPalette(st::dialogsSearchFromPalette);
|
||||
paintSearchInFilter(p, _searchFromUser, top, fullWidth, _searchFromUserText);
|
||||
paintSearchInPeer(p, from, top, fullWidth, _searchFromUserText);
|
||||
p.restoreTextPalette();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename PaintUserpic>
|
||||
void DialogsInner::paintSearchInFilter(
|
||||
Painter &p,
|
||||
PeerData *peer,
|
||||
PaintUserpic paintUserpic,
|
||||
int top,
|
||||
int fullWidth,
|
||||
const style::icon *icon,
|
||||
const Text &text) const {
|
||||
const auto savedPen = p.pen();
|
||||
const auto userpicLeft = st::dialogsPadding.x();
|
||||
const auto userpicTop = top
|
||||
+ (st::dialogsSearchInHeight - st::dialogsSearchInPhotoSize) / 2;
|
||||
if (peer) {
|
||||
peer->paintUserpicLeft(
|
||||
p,
|
||||
st::dialogsPadding.x(),
|
||||
userpicTop,
|
||||
getFullWidth(),
|
||||
st::dialogsSearchInPhotoSize);
|
||||
} else {
|
||||
Ui::EmptyUserpic::PaintSavedMessages(
|
||||
p,
|
||||
st::dialogsPadding.x(),
|
||||
userpicTop,
|
||||
getFullWidth(),
|
||||
st::dialogsSearchInPhotoSize);
|
||||
}
|
||||
paintUserpic(p, userpicLeft, userpicTop, st::dialogsSearchInPhotoSize);
|
||||
|
||||
const auto nameleft = st::dialogsPadding.x()
|
||||
+ st::dialogsSearchInPhotoSize
|
||||
+ st::dialogsSearchInPhotoPadding;
|
||||
|
@ -610,7 +614,7 @@ void DialogsInner::paintSearchInFilter(
|
|||
top + (st::dialogsSearchInHeight - st::msgNameFont->height) / 2,
|
||||
namewidth,
|
||||
st::msgNameFont->height);
|
||||
if (auto icon = Dialogs::Layout::ChatTypeIcon(peer, false, false)) {
|
||||
if (icon) {
|
||||
icon->paint(p, rectForName.topLeft(), fullWidth);
|
||||
rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip);
|
||||
}
|
||||
|
@ -623,6 +627,44 @@ void DialogsInner::paintSearchInFilter(
|
|||
getFullWidth());
|
||||
}
|
||||
|
||||
void DialogsInner::paintSearchInPeer(
|
||||
Painter &p,
|
||||
not_null<PeerData*> peer,
|
||||
int top,
|
||||
int fullWidth,
|
||||
const Text &text) const {
|
||||
const auto paintUserpic = [&](Painter &p, int x, int y, int size) {
|
||||
peer->paintUserpicLeft(p, x, y, fullWidth, size);
|
||||
};
|
||||
const auto icon = Dialogs::Layout::ChatTypeIcon(peer, false, false);
|
||||
paintSearchInFilter(p, paintUserpic, top, fullWidth, icon, text);
|
||||
}
|
||||
|
||||
void DialogsInner::paintSearchInSaved(
|
||||
Painter &p,
|
||||
int top,
|
||||
int fullWidth,
|
||||
const Text &text) const {
|
||||
const auto paintUserpic = [&](Painter &p, int x, int y, int size) {
|
||||
Ui::EmptyUserpic::PaintSavedMessages(p, x, y, fullWidth, size);
|
||||
};
|
||||
paintSearchInFilter(p, paintUserpic, top, fullWidth, nullptr, text);
|
||||
}
|
||||
|
||||
void DialogsInner::paintSearchInFeed(
|
||||
Painter &p,
|
||||
not_null<Data::Feed*> feed,
|
||||
int top,
|
||||
int fullWidth,
|
||||
const Text &text) const {
|
||||
const auto paintUserpic = [&](Painter &p, int x, int y, int size) {
|
||||
feed->paintUserpicLeft(p, x, y, fullWidth, size);
|
||||
};
|
||||
const auto icon = nullptr;
|
||||
paintSearchInFilter(p, paintUserpic, top, fullWidth, icon, text);
|
||||
}
|
||||
|
||||
|
||||
void DialogsInner::activate() {
|
||||
}
|
||||
|
||||
|
@ -1095,7 +1137,7 @@ void DialogsInner::setSearchedPressed(int pressed) {
|
|||
void DialogsInner::resizeEvent(QResizeEvent *e) {
|
||||
_addContactLnk->move((width() - _addContactLnk->width()) / 2, (st::noContactsHeight + st::noContactsFont->height) / 2);
|
||||
auto widthForCancelButton = qMax(width() + otherWidth(), st::columnMinimalWidthLeft);
|
||||
_cancelSearchInPeer->moveToLeft(widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchInPeer->width(), st::searchedBarHeight + (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2);
|
||||
_cancelSearchInChat->moveToLeft(widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchInChat->width(), st::searchedBarHeight + (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2);
|
||||
_cancelSearchFromUser->moveToLeft(widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchFromUser->width(), st::searchedBarHeight + st::dialogsSearchInHeight + st::lineWidth + (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2);
|
||||
}
|
||||
|
||||
|
@ -1532,7 +1574,7 @@ void DialogsInner::onFilterUpdate(QString newFilter, bool force) {
|
|||
_waitingForSearch = true;
|
||||
_filterResults.clear();
|
||||
_filterResultsGlobal.clear();
|
||||
if (!_searchInPeer && !words.isEmpty()) {
|
||||
if (!_searchInChat && !words.isEmpty()) {
|
||||
const Dialogs::List *toFilter = nullptr;
|
||||
if (!_dialogs->isEmpty()) {
|
||||
for (fi = fb; fi != fe; ++fi) {
|
||||
|
@ -1612,7 +1654,7 @@ void DialogsInner::onFilterUpdate(QString newFilter, bool force) {
|
|||
}
|
||||
|
||||
void DialogsInner::onHashtagFilterUpdate(QStringRef newFilter) {
|
||||
if (newFilter.isEmpty() || newFilter.at(0) != '#' || _searchInPeer) {
|
||||
if (newFilter.isEmpty() || newFilter.at(0) != '#' || _searchInChat) {
|
||||
_hashtagFilter = QString();
|
||||
if (!_hashtagResults.empty()) {
|
||||
_hashtagResults.clear();
|
||||
|
@ -1694,7 +1736,7 @@ void DialogsInner::itemRemoved(not_null<const HistoryItem*> item) {
|
|||
for (auto i = _searchResults.begin(); i != _searchResults.end();) {
|
||||
if ((*i)->item() == item) {
|
||||
i = _searchResults.erase(i);
|
||||
if (item->history()->peer == _searchInMigrated) {
|
||||
if (item->history() == _searchInMigrated) {
|
||||
if (_searchedMigratedCount > 0) --_searchedMigratedCount;
|
||||
} else {
|
||||
if (_searchedCount > 0) --_searchedCount;
|
||||
|
@ -1791,7 +1833,10 @@ bool DialogsInner::searchReceived(
|
|||
if (auto peer = App::peerLoaded(peerId)) {
|
||||
if (lastDate) {
|
||||
auto item = App::histories().addNewMessage(message, NewMessageExisting);
|
||||
_searchResults.push_back(std::make_unique<Dialogs::FakeRow>(_searchInPeer, item));
|
||||
_searchResults.push_back(
|
||||
std::make_unique<Dialogs::FakeRow>(
|
||||
_searchInChat,
|
||||
item));
|
||||
lastDateFound = lastDate;
|
||||
if (isGlobalSearch) {
|
||||
_lastSearchDate = lastDateFound;
|
||||
|
@ -1973,7 +2018,7 @@ void DialogsInner::refresh(bool toTop) {
|
|||
} else if (_state == State::Filtered) {
|
||||
if (!_addContactLnk->isHidden()) _addContactLnk->hide();
|
||||
if (_waitingForSearch) {
|
||||
h = searchedOffset() + (_searchResults.size() * st::dialogsRowHeight) + ((_searchResults.empty() && !_searchInPeer) ? -st::searchedBarHeight : 0);
|
||||
h = searchedOffset() + (_searchResults.size() * st::dialogsRowHeight) + ((_searchResults.empty() && !_searchInChat) ? -st::searchedBarHeight : 0);
|
||||
} else {
|
||||
h = searchedOffset() + (_searchResults.size() * st::dialogsRowHeight);
|
||||
}
|
||||
|
@ -1984,7 +2029,9 @@ void DialogsInner::refresh(bool toTop) {
|
|||
emit mustScrollTo(0, 0);
|
||||
loadPeerPhotos();
|
||||
}
|
||||
_controller->dialogsListDisplayForced().set(_searchInPeer || !_filter.isEmpty(), true);
|
||||
_controller->dialogsListDisplayForced().set(
|
||||
_searchInChat || !_filter.isEmpty(),
|
||||
true);
|
||||
update();
|
||||
}
|
||||
|
||||
|
@ -2012,40 +2059,72 @@ bool DialogsInner::hasFilteredResults() const {
|
|||
return !_filterResults.isEmpty() && _hashtagResults.empty();
|
||||
}
|
||||
|
||||
void DialogsInner::searchInPeer(PeerData *peer, UserData *from) {
|
||||
_searchInPeer = peer ? (peer->migrateTo() ? peer->migrateTo() : peer) : nullptr;
|
||||
_searchInMigrated = _searchInPeer ? _searchInPeer->migrateFrom() : nullptr;
|
||||
_searchFromUser = from;
|
||||
if (_searchInPeer) {
|
||||
onHashtagFilterUpdate(QStringRef());
|
||||
_cancelSearchInPeer->show();
|
||||
if (_searchInPeer->isSelf()) {
|
||||
_searchInSavedText.setText(
|
||||
st::msgNameStyle,
|
||||
lang(lng_saved_messages),
|
||||
Ui::DialogTextOptions());
|
||||
void DialogsInner::searchInChat(Dialogs::Key key, UserData *from) {
|
||||
_searchInMigrated = nullptr;
|
||||
if (const auto peer = key.peer()) {
|
||||
if (const auto migrateTo = peer->migrateTo()) {
|
||||
return searchInChat(App::history(migrateTo), from);
|
||||
} else if (const auto migrateFrom = peer->migrateFrom()) {
|
||||
_searchInMigrated = App::history(migrateFrom);
|
||||
}
|
||||
}
|
||||
_searchInChat = key;
|
||||
_searchFromUser = from;
|
||||
if (_searchInChat) {
|
||||
onHashtagFilterUpdate(QStringRef());
|
||||
_cancelSearchInChat->show();
|
||||
refreshSearchInChatLabel();
|
||||
} else {
|
||||
_cancelSearchInPeer->hide();
|
||||
_cancelSearchInChat->hide();
|
||||
}
|
||||
if (_searchFromUser) {
|
||||
auto fromUserText = lng_dlg_search_from(
|
||||
lt_user,
|
||||
textcmdLink(1, App::peerName(_searchFromUser)));
|
||||
_searchFromUserText.setText(
|
||||
st::dialogsSearchFromStyle,
|
||||
fromUserText,
|
||||
Ui::DialogTextOptions());
|
||||
_cancelSearchFromUser->show();
|
||||
} else {
|
||||
_cancelSearchFromUser->hide();
|
||||
}
|
||||
_controller->dialogsListDisplayForced().set(_searchInPeer || !_filter.isEmpty(), true);
|
||||
_controller->dialogsListDisplayForced().set(
|
||||
_searchInChat || !_filter.isEmpty(),
|
||||
true);
|
||||
}
|
||||
|
||||
void DialogsInner::refreshSearchInChatLabel() {
|
||||
const auto dialog = [&] {
|
||||
if (const auto peer = _searchInChat.peer()) {
|
||||
if (peer->isSelf()) {
|
||||
return lang(lng_saved_messages);
|
||||
}
|
||||
return peer->name;
|
||||
} else if (const auto feed = _searchInChat.feed()) {
|
||||
return feed->chatsListName();
|
||||
}
|
||||
return QString();
|
||||
}();
|
||||
if (!dialog.isEmpty()) {
|
||||
_searchInChatText.setText(
|
||||
st::msgNameStyle,
|
||||
dialog,
|
||||
Ui::DialogTextOptions());
|
||||
}
|
||||
const auto from = [&] {
|
||||
if (const auto from = _searchFromUser) {
|
||||
return App::peerName(from);
|
||||
}
|
||||
return QString();
|
||||
}();
|
||||
if (!from.isEmpty()) {
|
||||
const auto fromUserText = lng_dlg_search_from(
|
||||
lt_user,
|
||||
textcmdLink(1, from));
|
||||
_searchFromUserText.setText(
|
||||
st::dialogsSearchFromStyle,
|
||||
fromUserText,
|
||||
Ui::DialogTextOptions());
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsInner::clearFilter() {
|
||||
if (_state == State::Filtered || _searchInPeer) {
|
||||
if (_searchInPeer) {
|
||||
if (_state == State::Filtered || _searchInChat) {
|
||||
if (_searchInChat) {
|
||||
_state = State::Filtered;
|
||||
_waitingForSearch = true;
|
||||
} else {
|
||||
|
|
|
@ -94,7 +94,7 @@ public:
|
|||
}
|
||||
bool hasFilteredResults() const;
|
||||
|
||||
void searchInPeer(PeerData *peer, UserData *from);
|
||||
void searchInChat(Dialogs::Key key, UserData *from);
|
||||
|
||||
void onFilterUpdate(QString newFilter, bool force = false);
|
||||
void onHashtagFilterUpdate(QStringRef newFilter);
|
||||
|
@ -121,7 +121,7 @@ signals:
|
|||
void dialogMoved(int movedFrom, int movedTo);
|
||||
void searchMessages();
|
||||
void searchResultChosen();
|
||||
void cancelSearchInPeer();
|
||||
void cancelSearchInChat();
|
||||
void completeHashtag(QString tag);
|
||||
void refreshHashtags();
|
||||
|
||||
|
@ -215,7 +215,7 @@ private:
|
|||
int filteredOffset() const;
|
||||
int peerSearchOffset() const;
|
||||
int searchedOffset() const;
|
||||
int searchInPeerSkip() const;
|
||||
int searchInChatSkip() const;
|
||||
|
||||
void paintDialog(
|
||||
Painter &p,
|
||||
|
@ -233,17 +233,37 @@ private:
|
|||
bool selected,
|
||||
bool onlyBackground,
|
||||
TimeMs ms) const;
|
||||
void paintSearchInPeer(
|
||||
void paintSearchInChat(
|
||||
Painter &p,
|
||||
int fullWidth,
|
||||
bool onlyBackground,
|
||||
TimeMs ms) const;
|
||||
void paintSearchInFilter(
|
||||
void paintSearchInPeer(
|
||||
Painter &p,
|
||||
PeerData *peer,
|
||||
not_null<PeerData*> peer,
|
||||
int top,
|
||||
int fullWidth,
|
||||
const Text &text) const;
|
||||
void paintSearchInSaved(
|
||||
Painter &p,
|
||||
int top,
|
||||
int fullWidth,
|
||||
const Text &text) const;
|
||||
void paintSearchInFeed(
|
||||
Painter &p,
|
||||
not_null<Data::Feed*> feed,
|
||||
int top,
|
||||
int fullWidth,
|
||||
const Text &text) const;
|
||||
template <typename PaintUserpic>
|
||||
void paintSearchInFilter(
|
||||
Painter &p,
|
||||
PaintUserpic paintUserpic,
|
||||
int top,
|
||||
int fullWidth,
|
||||
const style::icon *icon,
|
||||
const Text &text) const;
|
||||
void refreshSearchInChatLabel();
|
||||
|
||||
void clearSelection();
|
||||
void clearSearchResults(bool clearPeerSearchResults = true);
|
||||
|
@ -332,14 +352,14 @@ private:
|
|||
State _state = State::Default;
|
||||
|
||||
object_ptr<Ui::LinkButton> _addContactLnk;
|
||||
object_ptr<Ui::IconButton> _cancelSearchInPeer;
|
||||
object_ptr<Ui::IconButton> _cancelSearchInChat;
|
||||
object_ptr<Ui::IconButton> _cancelSearchFromUser;
|
||||
|
||||
PeerData *_searchInPeer = nullptr;
|
||||
PeerData *_searchInMigrated = nullptr;
|
||||
Dialogs::Key _searchInChat;
|
||||
History *_searchInMigrated = nullptr;
|
||||
UserData *_searchFromUser = nullptr;
|
||||
Text _searchInChatText;
|
||||
Text _searchFromUserText;
|
||||
Text _searchInSavedText;
|
||||
Dialogs::Key _menuKey;
|
||||
|
||||
base::lambda<void()> _loadMoreCallback;
|
||||
|
|
|
@ -49,11 +49,12 @@ void paintRowDate(Painter &p, QDateTime date, QRect &rectForName, bool active, b
|
|||
}
|
||||
|
||||
enum class Flag {
|
||||
Active = 0x01,
|
||||
Selected = 0x02,
|
||||
OnlyBackground = 0x04,
|
||||
SearchResult = 0x08,
|
||||
SavedMessages = 0x10,
|
||||
Active = 0x01,
|
||||
Selected = 0x02,
|
||||
OnlyBackground = 0x04,
|
||||
SearchResult = 0x08,
|
||||
SavedMessages = 0x10,
|
||||
FeedSearchResult = 0x20,
|
||||
};
|
||||
inline constexpr bool is_flag_type(Flag) { return true; }
|
||||
|
||||
|
@ -130,7 +131,7 @@ void paintRow(
|
|||
namewidth,
|
||||
st::msgNameFont->height);
|
||||
|
||||
if (from) {
|
||||
if (from && !(flags & Flag::FeedSearchResult)) {
|
||||
if (auto chatTypeIcon = ChatTypeIcon(from, active, selected)) {
|
||||
chatTypeIcon->paint(p, rectForName.topLeft(), fullWidth);
|
||||
rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip);
|
||||
|
@ -534,11 +535,13 @@ void RowPainter::paint(
|
|||
auto history = item->history();
|
||||
auto cloudDraft = nullptr;
|
||||
const auto from = [&] {
|
||||
if (auto searchPeer = row->searchInPeer()) {
|
||||
if (searchPeer->isSelf()) {
|
||||
return item->senderOriginal().get();
|
||||
} else if (!searchPeer->isChannel() || searchPeer->isMegagroup()) {
|
||||
return item->from().get();
|
||||
if (const auto searchChat = row->searchInChat()) {
|
||||
if (const auto peer = searchChat.peer()) {
|
||||
if (peer->isSelf()) {
|
||||
return item->senderOriginal().get();
|
||||
} else if (!peer->isChannel() || peer->isMegagroup()) {
|
||||
return item->from().get();
|
||||
}
|
||||
}
|
||||
}
|
||||
return history->peer->migrateTo()
|
||||
|
@ -546,9 +549,11 @@ void RowPainter::paint(
|
|||
: history->peer.get();
|
||||
}();
|
||||
const auto drawInDialogWay = [&] {
|
||||
if (auto searchPeer = row->searchInPeer()) {
|
||||
if (!searchPeer->isChannel() || searchPeer->isMegagroup()) {
|
||||
return HistoryItem::DrawInDialog::WithoutSender;
|
||||
if (const auto searchChat = row->searchInChat()) {
|
||||
if (const auto peer = searchChat.peer()) {
|
||||
if (!peer->isChannel() || peer->isMegagroup()) {
|
||||
return HistoryItem::DrawInDialog::WithoutSender;
|
||||
}
|
||||
}
|
||||
}
|
||||
return HistoryItem::DrawInDialog::Normal;
|
||||
|
@ -567,12 +572,13 @@ void RowPainter::paint(
|
|||
};
|
||||
const auto paintCounterCallback = [] {};
|
||||
const auto showSavedMessages = history->peer->isSelf()
|
||||
&& !row->searchInPeer();
|
||||
&& !row->searchInChat();
|
||||
const auto flags = (active ? Flag::Active : Flag(0))
|
||||
| (selected ? Flag::Selected : Flag(0))
|
||||
| (onlyBackground ? Flag::OnlyBackground : Flag(0))
|
||||
| Flag::SearchResult
|
||||
| (showSavedMessages ? Flag::SavedMessages : Flag(0));
|
||||
| (showSavedMessages ? Flag::SavedMessages : Flag(0))
|
||||
| (row->searchInChat().feed() ? Flag::FeedSearchResult : Flag(0));
|
||||
paintRow(
|
||||
p,
|
||||
row,
|
||||
|
|
|
@ -44,8 +44,8 @@ uint64 Row::sortKey() const {
|
|||
return _id.entry()->sortKeyInChatList();
|
||||
}
|
||||
|
||||
FakeRow::FakeRow(PeerData *searchInPeer, not_null<HistoryItem*> item)
|
||||
: _searchInPeer(searchInPeer)
|
||||
FakeRow::FakeRow(Key searchInChat, not_null<HistoryItem*> item)
|
||||
: _searchInChat(searchInChat)
|
||||
, _item(item)
|
||||
, _cache(st::dialogsTextWidthMin) {
|
||||
}
|
||||
|
|
|
@ -81,10 +81,10 @@ private:
|
|||
|
||||
class FakeRow : public RippleRow {
|
||||
public:
|
||||
FakeRow(PeerData *searchInPeer, not_null<HistoryItem*> item);
|
||||
FakeRow(Key searchInChat, not_null<HistoryItem*> item);
|
||||
|
||||
PeerData *searchInPeer() const {
|
||||
return _searchInPeer;
|
||||
Key searchInChat() const {
|
||||
return _searchInChat;
|
||||
}
|
||||
not_null<HistoryItem*> item() const {
|
||||
return _item;
|
||||
|
@ -93,7 +93,7 @@ public:
|
|||
private:
|
||||
friend class Layout::RowPainter;
|
||||
|
||||
PeerData *_searchInPeer = nullptr;
|
||||
Key _searchInChat;
|
||||
not_null<HistoryItem*> _item;
|
||||
mutable const HistoryItem *_cacheFor = nullptr;
|
||||
mutable Text _cache;
|
||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "dialogs/dialogs_key.h"
|
||||
#include "dialogs/dialogs_entry.h"
|
||||
#include "history/history.h"
|
||||
#include "history/feed/history_feed_section.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
|
@ -106,9 +107,9 @@ DialogsWidget::DialogsWidget(QWidget *parent, not_null<Window::Controller*> cont
|
|||
connect(_inner, SIGNAL(searchResultChosen()), this, SLOT(onCancel()));
|
||||
connect(_inner, SIGNAL(completeHashtag(QString)), this, SLOT(onCompleteHashtag(QString)));
|
||||
connect(_inner, SIGNAL(refreshHashtags()), this, SLOT(onFilterCursorMoved()));
|
||||
connect(_inner, SIGNAL(cancelSearchInPeer()), this, SLOT(onCancelSearchInPeer()));
|
||||
connect(_inner, SIGNAL(cancelSearchInChat()), this, SLOT(onCancelSearchInChat()));
|
||||
subscribe(_inner->searchFromUserChanged, [this](UserData *user) {
|
||||
setSearchInPeer(_searchInPeer, user);
|
||||
setSearchInChat(_searchInChat, user);
|
||||
onFilterUpdate(true);
|
||||
});
|
||||
connect(_scroll, SIGNAL(geometryChanged()), _inner, SLOT(onParentGeometryChanged()));
|
||||
|
@ -127,7 +128,11 @@ DialogsWidget::DialogsWidget(QWidget *parent, not_null<Window::Controller*> cont
|
|||
subscribe(Adaptive::Changed(), [this] { updateForwardBar(); });
|
||||
|
||||
_cancelSearch->setClickedCallback([this] { onCancelSearch(); });
|
||||
_jumpToDate->entity()->setClickedCallback([this] { if (_searchInPeer) this->controller()->showJumpToDate(_searchInPeer, QDate()); });
|
||||
_jumpToDate->entity()->setClickedCallback([this] {
|
||||
if (const auto peer = _searchInChat.peer()) {
|
||||
this->controller()->showJumpToDate(peer, QDate());
|
||||
}
|
||||
});
|
||||
_chooseFromUser->entity()->setClickedCallback([this] { showSearchFrom(); });
|
||||
_lockUnlock->setVisible(Global::LocalPasscode());
|
||||
subscribe(Global::RefLocalPasscodeChanged(), [this] { updateLockUnlockVisibility(); });
|
||||
|
@ -310,7 +315,7 @@ void DialogsWidget::animationCallback() {
|
|||
}
|
||||
|
||||
void DialogsWidget::onCancel() {
|
||||
if (!onCancelSearch() || (!_searchInPeer && !App::main()->selectingPeer())) {
|
||||
if (!onCancelSearch() || (!_searchInChat && !App::main()->selectingPeer())) {
|
||||
emit cancelled();
|
||||
}
|
||||
}
|
||||
|
@ -481,7 +486,7 @@ bool DialogsWidget::onSearchMessages(bool searchCache) {
|
|||
_searchFull = _searchFullMigrated = false;
|
||||
MTP::cancel(base::take(_searchRequest));
|
||||
searchReceived(
|
||||
_searchInPeer
|
||||
_searchInChat
|
||||
? DialogsSearchPeerFromStart
|
||||
: DialogsSearchFromStart,
|
||||
i.value(),
|
||||
|
@ -493,14 +498,14 @@ bool DialogsWidget::onSearchMessages(bool searchCache) {
|
|||
_searchQueryFrom = _searchFromUser;
|
||||
_searchFull = _searchFullMigrated = false;
|
||||
MTP::cancel(base::take(_searchRequest));
|
||||
if (_searchInPeer) {
|
||||
if (const auto peer = _searchInChat.peer()) {
|
||||
const auto flags = _searchQueryFrom
|
||||
? MTP_flags(MTPmessages_Search::Flag::f_from_id)
|
||||
: MTP_flags(0);
|
||||
_searchRequest = MTP::send(
|
||||
MTPmessages_Search(
|
||||
flags,
|
||||
_searchInPeer->input,
|
||||
peer->input,
|
||||
MTP_string(_searchQuery),
|
||||
_searchQueryFrom
|
||||
? _searchQueryFrom->inputUser
|
||||
|
@ -516,6 +521,17 @@ bool DialogsWidget::onSearchMessages(bool searchCache) {
|
|||
MTP_int(0)),
|
||||
rpcDone(&DialogsWidget::searchReceived, DialogsSearchPeerFromStart),
|
||||
rpcFail(&DialogsWidget::searchFailed, DialogsSearchPeerFromStart));
|
||||
} else if (const auto feed = _searchInChat.feed()) {
|
||||
_searchRequest = MTP::send(
|
||||
MTPchannels_SearchFeed(
|
||||
MTP_int(feed->id()),
|
||||
MTP_string(_searchQuery),
|
||||
MTP_int(0),
|
||||
MTP_inputPeerEmpty(),
|
||||
MTP_int(0),
|
||||
MTP_int(SearchPerPage)),
|
||||
rpcDone(&DialogsWidget::searchReceived, DialogsSearchFromStart),
|
||||
rpcFail(&DialogsWidget::searchFailed, DialogsSearchFromStart));
|
||||
} else {
|
||||
_searchRequest = MTP::send(
|
||||
MTPmessages_SearchGlobal(
|
||||
|
@ -529,7 +545,7 @@ bool DialogsWidget::onSearchMessages(bool searchCache) {
|
|||
}
|
||||
_searchQueries.insert(_searchRequest, _searchQuery);
|
||||
}
|
||||
if (!_searchInPeer && !q.isEmpty()) {
|
||||
if (!_searchInChat && !q.isEmpty()) {
|
||||
if (searchCache) {
|
||||
auto i = _peerSearchCache.constFind(q);
|
||||
if (i != _peerSearchCache.cend()) {
|
||||
|
@ -567,11 +583,23 @@ void DialogsWidget::showMainMenu() {
|
|||
App::wnd()->showMainMenu();
|
||||
}
|
||||
|
||||
void DialogsWidget::searchMessages(const QString &query, PeerData *inPeer) {
|
||||
if ((_filter->getLastText() != query) || (inPeer && inPeer != _searchInPeer && inPeer->migrateTo() != _searchInPeer)) {
|
||||
if (inPeer) {
|
||||
void DialogsWidget::searchMessages(
|
||||
const QString &query,
|
||||
Dialogs::Key inChat) {
|
||||
auto inChatChanged = [&] {
|
||||
if (inChat == _searchInChat) {
|
||||
return false;
|
||||
} else if (const auto inPeer = inChat.peer()) {
|
||||
if (inPeer->migrateTo() == _searchInChat.peer()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}();
|
||||
if ((_filter->getLastText() != query) || inChatChanged) {
|
||||
if (inChat) {
|
||||
onCancelSearch();
|
||||
setSearchInPeer(inPeer);
|
||||
setSearchInChat(inChat);
|
||||
}
|
||||
_filter->setText(query);
|
||||
_filter->updatePlaceholder();
|
||||
|
@ -589,12 +617,14 @@ void DialogsWidget::onSearchMore() {
|
|||
auto offsetDate = _inner->lastSearchDate();
|
||||
auto offsetPeer = _inner->lastSearchPeer();
|
||||
auto offsetId = _inner->lastSearchId();
|
||||
if (_searchInPeer) {
|
||||
auto flags = _searchQueryFrom ? MTP_flags(MTPmessages_Search::Flag::f_from_id) : MTP_flags(0);
|
||||
if (const auto peer = _searchInChat.peer()) {
|
||||
auto flags = _searchQueryFrom
|
||||
? MTP_flags(MTPmessages_Search::Flag::f_from_id)
|
||||
: MTP_flags(0);
|
||||
_searchRequest = MTP::send(
|
||||
MTPmessages_Search(
|
||||
flags,
|
||||
_searchInPeer->input,
|
||||
peer->input,
|
||||
MTP_string(_searchQuery),
|
||||
_searchQueryFrom
|
||||
? _searchQueryFrom->inputUser
|
||||
|
@ -610,6 +640,19 @@ void DialogsWidget::onSearchMore() {
|
|||
MTP_int(0)),
|
||||
rpcDone(&DialogsWidget::searchReceived, offsetId ? DialogsSearchPeerFromOffset : DialogsSearchPeerFromStart),
|
||||
rpcFail(&DialogsWidget::searchFailed, offsetId ? DialogsSearchPeerFromOffset : DialogsSearchPeerFromStart));
|
||||
} else if (const auto feed = _searchInChat.feed()) {
|
||||
_searchRequest = MTP::send(
|
||||
MTPchannels_SearchFeed(
|
||||
MTP_int(feed->id()),
|
||||
MTP_string(_searchQuery),
|
||||
MTP_int(offsetDate),
|
||||
offsetPeer
|
||||
? offsetPeer->input
|
||||
: MTP_inputPeerEmpty(),
|
||||
MTP_int(offsetId),
|
||||
MTP_int(SearchPerPage)),
|
||||
rpcDone(&DialogsWidget::searchReceived, offsetId ? DialogsSearchFromOffset : DialogsSearchFromStart),
|
||||
rpcFail(&DialogsWidget::searchFailed, offsetId ? DialogsSearchFromOffset : DialogsSearchFromStart));
|
||||
} else {
|
||||
_searchRequest = MTP::send(
|
||||
MTPmessages_SearchGlobal(
|
||||
|
@ -628,11 +671,13 @@ void DialogsWidget::onSearchMore() {
|
|||
}
|
||||
} else if (_searchInMigrated && !_searchFullMigrated) {
|
||||
auto offsetMigratedId = _inner->lastSearchMigratedId();
|
||||
auto flags = _searchQueryFrom ? MTP_flags(MTPmessages_Search::Flag::f_from_id) : MTP_flags(0);
|
||||
auto flags = _searchQueryFrom
|
||||
? MTP_flags(MTPmessages_Search::Flag::f_from_id)
|
||||
: MTP_flags(0);
|
||||
_searchRequest = MTP::send(
|
||||
MTPmessages_Search(
|
||||
flags,
|
||||
_searchInMigrated->input,
|
||||
_searchInMigrated->peer->input,
|
||||
MTP_string(_searchQuery),
|
||||
_searchQueryFrom
|
||||
? _searchQueryFrom->inputUser
|
||||
|
@ -741,10 +786,18 @@ void DialogsWidget::searchReceived(
|
|||
|
||||
case mtpc_messages_channelMessages: {
|
||||
auto &d = result.c_messages_channelMessages();
|
||||
if (_searchInPeer && _searchInPeer->isChannel()) {
|
||||
_searchInPeer->asChannel()->ptsReceived(d.vpts.v);
|
||||
if (const auto peer = _searchInChat.peer()) {
|
||||
if (const auto channel = peer->asChannel()) {
|
||||
channel->ptsReceived(d.vpts.v);
|
||||
} else {
|
||||
LOG(("API Error: "
|
||||
"received messages.channelMessages when no channel "
|
||||
"was passed! (DialogsWidget::searchReceived)"));
|
||||
}
|
||||
} else {
|
||||
LOG(("API Error: received messages.channelMessages when no channel was passed! (DialogsWidget::searchReceived)"));
|
||||
LOG(("API Error: "
|
||||
"received messages.channelMessages when no channel "
|
||||
"was passed! (DialogsWidget::searchReceived)"));
|
||||
}
|
||||
if (_searchRequest != 0) {
|
||||
// Don't apply cached data!
|
||||
|
@ -941,26 +994,26 @@ void DialogsWidget::onFilterUpdate(bool force) {
|
|||
|
||||
void DialogsWidget::searchInChat(Dialogs::Key chat) {
|
||||
onCancelSearch();
|
||||
if (const auto peer = chat.peer()) {
|
||||
setSearchInPeer(peer);
|
||||
} else {
|
||||
// #TODO feeds search
|
||||
setSearchInPeer(nullptr);
|
||||
}
|
||||
setSearchInChat(chat);
|
||||
onFilterUpdate(true);
|
||||
}
|
||||
|
||||
void DialogsWidget::setSearchInPeer(PeerData *peer, UserData *from) {
|
||||
auto searchInPeerUpdated = false;
|
||||
auto newSearchInPeer = peer ? (peer->migrateTo() ? peer->migrateTo() : peer) : nullptr;
|
||||
_searchInMigrated = newSearchInPeer ? newSearchInPeer->migrateFrom() : nullptr;
|
||||
searchInPeerUpdated = (newSearchInPeer != _searchInPeer);
|
||||
void DialogsWidget::setSearchInChat(Dialogs::Key chat, UserData *from) {
|
||||
_searchInMigrated = nullptr;
|
||||
if (const auto peer = chat.peer()) {
|
||||
if (const auto migrateTo = peer->migrateTo()) {
|
||||
return setSearchInChat(App::history(migrateTo), from);
|
||||
} else if (const auto migrateFrom = peer->migrateFrom()) {
|
||||
_searchInMigrated = App::history(migrateFrom);
|
||||
}
|
||||
}
|
||||
const auto searchInPeerUpdated = (_searchInChat != chat);
|
||||
if (searchInPeerUpdated) {
|
||||
_searchInPeer = newSearchInPeer;
|
||||
_searchInChat = chat;
|
||||
from = nullptr;
|
||||
controller()->searchInPeer = _searchInPeer;
|
||||
controller()->searchInChat = _searchInChat;
|
||||
updateJumpToDateVisibility();
|
||||
} else if (!_searchInPeer) {
|
||||
} else if (!_searchInChat) {
|
||||
from = nullptr;
|
||||
}
|
||||
if (_searchFromUser != from || searchInPeerUpdated) {
|
||||
|
@ -968,7 +1021,7 @@ void DialogsWidget::setSearchInPeer(PeerData *peer, UserData *from) {
|
|||
updateSearchFromVisibility();
|
||||
clearSearchCache();
|
||||
}
|
||||
_inner->searchInPeer(_searchInPeer, _searchFromUser);
|
||||
_inner->searchInChat(_searchInChat, _searchFromUser);
|
||||
if (_searchFromUser && _lastFilterText == SwitchToChooseFromQuery()) {
|
||||
onCancelSearch();
|
||||
}
|
||||
|
@ -984,20 +1037,19 @@ void DialogsWidget::clearSearchCache() {
|
|||
}
|
||||
|
||||
void DialogsWidget::showSearchFrom() {
|
||||
if (!_searchInPeer) {
|
||||
return;
|
||||
if (const auto peer = _searchInChat.peer()) {
|
||||
const auto chat = _searchInChat;
|
||||
Dialogs::ShowSearchFromBox(
|
||||
controller(),
|
||||
peer,
|
||||
base::lambda_guarded(this, [=](
|
||||
not_null<UserData*> user) {
|
||||
Ui::hideLayer();
|
||||
setSearchInChat(chat, user);
|
||||
onFilterUpdate(true);
|
||||
}),
|
||||
base::lambda_guarded(this, [this] { _filter->setFocus(); }));
|
||||
}
|
||||
auto peer = _searchInPeer;
|
||||
Dialogs::ShowSearchFromBox(
|
||||
controller(),
|
||||
peer,
|
||||
base::lambda_guarded(this, [this, peer](
|
||||
not_null<UserData*> user) {
|
||||
Ui::hideLayer();
|
||||
setSearchInPeer(peer, user);
|
||||
onFilterUpdate(true);
|
||||
}),
|
||||
base::lambda_guarded(this, [this] { _filter->setFocus(); }));
|
||||
}
|
||||
|
||||
void DialogsWidget::onFilterCursorMoved(int from, int to) {
|
||||
|
@ -1058,12 +1110,19 @@ void DialogsWidget::updateJumpToDateVisibility(bool fast) {
|
|||
if (_a_show.animating()) return;
|
||||
|
||||
_jumpToDate->toggle(
|
||||
(_searchInPeer && _filter->getLastText().isEmpty()),
|
||||
(_searchInChat && _filter->getLastText().isEmpty()),
|
||||
fast ? anim::type::instant : anim::type::normal);
|
||||
}
|
||||
|
||||
void DialogsWidget::updateSearchFromVisibility(bool fast) {
|
||||
auto visible = _searchInPeer && (_searchInPeer->isChat() || _searchInPeer->isMegagroup()) && !_searchFromUser;
|
||||
auto visible = [&] {
|
||||
if (const auto peer = _searchInChat.peer()) {
|
||||
if (peer->isChat() || peer->isMegagroup()) {
|
||||
return !_searchFromUser;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
auto changed = (visible == !_chooseFromUser->toggled());
|
||||
_chooseFromUser->toggle(
|
||||
visible,
|
||||
|
@ -1263,11 +1322,17 @@ bool DialogsWidget::onCancelSearch() {
|
|||
MTP::cancel(_searchRequest);
|
||||
_searchRequest = 0;
|
||||
}
|
||||
if (_searchInPeer && !clearing) {
|
||||
if (_searchInChat && !clearing) {
|
||||
if (Adaptive::OneColumn()) {
|
||||
Ui::showPeerHistory(_searchInPeer, ShowAtUnreadMsgId);
|
||||
if (const auto peer = _searchInChat.peer()) {
|
||||
Ui::showPeerHistory(peer, ShowAtUnreadMsgId);
|
||||
} else if (const auto feed = _searchInChat.feed()) {
|
||||
controller()->showSection(HistoryFeed::Memento(feed));
|
||||
} else {
|
||||
Unexpected("Empty key in onCancelSearch().");
|
||||
}
|
||||
}
|
||||
setSearchInPeer(nullptr);
|
||||
setSearchInChat(Dialogs::Key());
|
||||
clearing = true;
|
||||
}
|
||||
_inner->clearFilter();
|
||||
|
@ -1277,16 +1342,22 @@ bool DialogsWidget::onCancelSearch() {
|
|||
return clearing;
|
||||
}
|
||||
|
||||
void DialogsWidget::onCancelSearchInPeer() {
|
||||
void DialogsWidget::onCancelSearchInChat() {
|
||||
if (_searchRequest) {
|
||||
MTP::cancel(_searchRequest);
|
||||
_searchRequest = 0;
|
||||
}
|
||||
if (_searchInPeer) {
|
||||
if (_searchInChat) {
|
||||
if (Adaptive::OneColumn() && !App::main()->selectingPeer()) {
|
||||
Ui::showPeerHistory(_searchInPeer, ShowAtUnreadMsgId);
|
||||
if (const auto peer = _searchInChat.peer()) {
|
||||
Ui::showPeerHistory(peer, ShowAtUnreadMsgId);
|
||||
} else if (const auto feed = _searchInChat.feed()) {
|
||||
controller()->showSection(HistoryFeed::Memento(feed));
|
||||
} else {
|
||||
Unexpected("Empty key in onCancelSearchInPeer().");
|
||||
}
|
||||
}
|
||||
setSearchInPeer(nullptr);
|
||||
setSearchInChat(Dialogs::Key());
|
||||
}
|
||||
_inner->clearFilter();
|
||||
_filter->clear();
|
||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "window/section_widget.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "dialogs/dialogs_key.h"
|
||||
|
||||
class DialogsInner;
|
||||
|
||||
|
@ -85,7 +86,7 @@ public:
|
|||
Dialogs::IndexedList *dialogsList();
|
||||
Dialogs::IndexedList *contactsNoDialogsList();
|
||||
|
||||
void searchMessages(const QString &query, PeerData *inPeer = 0);
|
||||
void searchMessages(const QString &query, Dialogs::Key inChat = {});
|
||||
void onSearchMore();
|
||||
|
||||
// Float player interface.
|
||||
|
@ -105,7 +106,7 @@ public slots:
|
|||
void activate();
|
||||
void onFilterUpdate(bool force = false);
|
||||
bool onCancelSearch();
|
||||
void onCancelSearchInPeer();
|
||||
void onCancelSearchInChat();
|
||||
|
||||
void onFilterCursorMoved(int from = -1, int to = -1);
|
||||
void onCompleteHashtag(QString tag);
|
||||
|
@ -154,7 +155,7 @@ private:
|
|||
const QVector<MTPDialog> &dialogs,
|
||||
const QVector<MTPMessage> &messages);
|
||||
|
||||
void setSearchInPeer(PeerData *peer, UserData *from = nullptr);
|
||||
void setSearchInChat(Dialogs::Key chat, UserData *from = nullptr);
|
||||
void showSearchFrom();
|
||||
void showMainMenu();
|
||||
void clearSearchCache();
|
||||
|
@ -196,8 +197,8 @@ private:
|
|||
Window::SlideDirection _showDirection;
|
||||
QPixmap _cacheUnder, _cacheOver;
|
||||
|
||||
PeerData *_searchInPeer = nullptr;
|
||||
PeerData *_searchInMigrated = nullptr;
|
||||
Dialogs::Key _searchInChat;
|
||||
History *_searchInMigrated = nullptr;
|
||||
UserData *_searchFromUser = nullptr;
|
||||
QString _lastFilterText;
|
||||
|
||||
|
|
|
@ -149,13 +149,17 @@ void activateBotCommand(
|
|||
}
|
||||
|
||||
void searchByHashtag(const QString &tag, PeerData *inPeer) {
|
||||
if (MainWidget *m = main()) {
|
||||
if (const auto m = main()) {
|
||||
Ui::hideSettingsAndLayer();
|
||||
Messenger::Instance().hideMediaView();
|
||||
if (inPeer && (!inPeer->isChannel() || inPeer->isMegagroup())) {
|
||||
inPeer = nullptr;
|
||||
}
|
||||
m->searchMessages(tag + ' ', inPeer);
|
||||
m->searchMessages(
|
||||
tag + ' ',
|
||||
(inPeer
|
||||
? App::history(inPeer).get()
|
||||
: nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1839,13 +1839,12 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
|||
updateForwarding();
|
||||
updateOverStates(mapFromGlobal(QCursor::pos()));
|
||||
|
||||
crl::on_main(App::wnd(), [] { App::wnd()->setInnerFocus(); });
|
||||
|
||||
controller()->historyPeer = _peer;
|
||||
if (_history) {
|
||||
controller()->setActiveChatEntry({ _history, _showAtMsgId });
|
||||
}
|
||||
update();
|
||||
|
||||
crl::on_main(App::wnd(), [] { App::wnd()->setInnerFocus(); });
|
||||
}
|
||||
|
||||
void HistoryWidget::clearDelayedShowAt() {
|
||||
|
|
|
@ -67,26 +67,26 @@ TopBarWidget::TopBarWidget(
|
|||
_back->addClickHandler([this] { backClicked(); });
|
||||
|
||||
rpl::combine(
|
||||
_controller->historyPeer.value(),
|
||||
_controller->searchInPeer.value()
|
||||
_controller->activeChatValue(),
|
||||
_controller->searchInChat.value()
|
||||
) | rpl::combine_previous(
|
||||
std::make_tuple(nullptr, nullptr)
|
||||
std::make_tuple(Dialogs::Key(), Dialogs::Key())
|
||||
) | rpl::map([](
|
||||
const std::tuple<PeerData*, PeerData*> &previous,
|
||||
const std::tuple<PeerData*, PeerData*> ¤t) {
|
||||
auto peer = std::get<0>(current);
|
||||
auto searchPeer = std::get<1>(current);
|
||||
auto peerChanged = (peer != std::get<0>(previous));
|
||||
auto searchInPeer
|
||||
= (peer != nullptr) && (peer == searchPeer);
|
||||
return std::make_tuple(searchInPeer, peerChanged);
|
||||
const std::tuple<Dialogs::Key, Dialogs::Key> &previous,
|
||||
const std::tuple<Dialogs::Key, Dialogs::Key> ¤t) {
|
||||
auto active = std::get<0>(current);
|
||||
auto search = std::get<1>(current);
|
||||
auto activeChanged = (active != std::get<0>(previous));
|
||||
auto searchInChat
|
||||
= search && (active == search);
|
||||
return std::make_tuple(searchInChat, activeChanged);
|
||||
}) | rpl::start_with_next([this](
|
||||
bool searchInHistoryPeer,
|
||||
bool peerChanged) {
|
||||
auto animated = peerChanged
|
||||
bool searchInActiveChat,
|
||||
bool activeChanged) {
|
||||
auto animated = activeChanged
|
||||
? anim::type::instant
|
||||
: anim::type::normal;
|
||||
_search->setForceRippled(searchInHistoryPeer, animated);
|
||||
_search->setForceRippled(searchInActiveChat, animated);
|
||||
}, lifetime());
|
||||
|
||||
subscribe(Adaptive::Changed(), [this] { updateAdaptiveLayout(); });
|
||||
|
|
|
@ -349,9 +349,13 @@ Ui::MultiSlideTracker DetailsFiller::fillUserButtons(
|
|||
auto window = _controller->parentController();
|
||||
|
||||
auto addSendMessageButton = [&] {
|
||||
auto activePeerValue = window->activeChatValue(
|
||||
) | rpl::map([](Dialogs::Key key) {
|
||||
return key.peer();
|
||||
});
|
||||
auto sendMessageVisible = rpl::combine(
|
||||
_controller->wrapValue(),
|
||||
window->historyPeer.value(),
|
||||
std::move(activePeerValue),
|
||||
(_1 != Wrap::Side) || (_2 != user));
|
||||
auto sendMessage = [window, user] {
|
||||
window->showPeerHistory(
|
||||
|
@ -399,9 +403,13 @@ Ui::MultiSlideTracker DetailsFiller::fillChannelButtons(
|
|||
|
||||
Ui::MultiSlideTracker tracker;
|
||||
auto window = _controller->parentController();
|
||||
auto activePeerValue = window->activeChatValue(
|
||||
) | rpl::map([](Dialogs::Key key) {
|
||||
return key.peer();
|
||||
});
|
||||
auto viewChannelVisible = rpl::combine(
|
||||
_controller->wrapValue(),
|
||||
window->historyPeer.value(),
|
||||
std::move(activePeerValue),
|
||||
(_1 != Wrap::Side) || (_2 != channel));
|
||||
auto viewChannel = [=] {
|
||||
window->showPeerHistory(
|
||||
|
|
|
@ -1406,8 +1406,8 @@ bool MainWidget::insertBotCommand(const QString &cmd) {
|
|||
return _history->insertBotCommand(cmd);
|
||||
}
|
||||
|
||||
void MainWidget::searchMessages(const QString &query, PeerData *inPeer) {
|
||||
_dialogs->searchMessages(query, inPeer);
|
||||
void MainWidget::searchMessages(const QString &query, Dialogs::Key inChat) {
|
||||
_dialogs->searchMessages(query, inChat);
|
||||
if (Adaptive::OneColumn()) {
|
||||
Ui::showChatsList();
|
||||
} else {
|
||||
|
@ -2018,9 +2018,11 @@ void MainWidget::ui_showPeerHistory(
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (auto historyPeer = _controller->historyPeer.current()) {
|
||||
if (way == Way::Forward && historyPeer->id == peerId) {
|
||||
way = Way::ClearStack;
|
||||
if (const auto activeChat = _controller->activeChatCurrent()) {
|
||||
if (const auto peer = activeChat.peer()) {
|
||||
if (way == Way::Forward && peer->id == peerId) {
|
||||
way = Way::ClearStack;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -243,7 +243,7 @@ public:
|
|||
bool insertBotCommand(const QString &cmd);
|
||||
|
||||
void jumpToDate(not_null<PeerData*> peer, const QDate &date);
|
||||
void searchMessages(const QString &query, PeerData *inPeer);
|
||||
void searchMessages(const QString &query, Dialogs::Key inChat);
|
||||
void itemEdited(not_null<HistoryItem*> item);
|
||||
|
||||
void checkLastUpdate(bool afterSleep);
|
||||
|
|
|
@ -108,16 +108,9 @@ public:
|
|||
return _window;
|
||||
}
|
||||
|
||||
// This is needed for History TopBar updating when searchInPeer
|
||||
// This is needed for History TopBar updating when searchInChat
|
||||
// is changed in the DialogsWidget of the current window.
|
||||
rpl::variable<PeerData*> searchInPeer;
|
||||
|
||||
// This is needed while we have one HistoryWidget and one TopBarWidget
|
||||
// for all histories we show in a window. Once each history is shown
|
||||
// in its own HistoryWidget with its own TopBarWidget this can be removed.
|
||||
//
|
||||
// Also used in the Info::Profile to toggle Send Message button.
|
||||
rpl::variable<PeerData*> historyPeer;
|
||||
rpl::variable<Dialogs::Key> searchInChat;
|
||||
|
||||
void setActiveChatEntry(Dialogs::RowDescriptor row);
|
||||
void setActiveChatEntry(Dialogs::Key key);
|
||||
|
|
Loading…
Reference in New Issue