mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Hashtag search results as dialogs (support).
This commit is contained in:
parent
81a9554caa
commit
631e51a493
6 changed files with 264 additions and 89 deletions
|
@ -641,6 +641,43 @@ void ApiWrap::requestDialogEntry(
|
|||
}).send();
|
||||
}
|
||||
|
||||
void ApiWrap::requestDialogEntries(
|
||||
std::vector<not_null<History*>> histories) {
|
||||
const auto already = [&](not_null<History*> history) {
|
||||
const auto [i, ok] = _dialogRequests.try_emplace(history);
|
||||
return !ok;
|
||||
};
|
||||
histories.erase(ranges::remove_if(histories, already), end(histories));
|
||||
if (histories.empty()) {
|
||||
return;
|
||||
}
|
||||
auto peers = QVector<MTPInputDialogPeer>();
|
||||
peers.reserve(histories.size());
|
||||
for (const auto history : histories) {
|
||||
peers.push_back(MTP_inputDialogPeer(history->peer->input));
|
||||
}
|
||||
const auto finalize = [=](std::vector<not_null<History*>> histories) {
|
||||
for (const auto history : histories) {
|
||||
if (const auto callbacks = _dialogRequests.take(history)) {
|
||||
for (const auto callback : *callbacks) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
request(MTPmessages_GetPeerDialogs(
|
||||
MTP_vector(std::move(peers))
|
||||
)).done([=](const MTPmessages_PeerDialogs &result) {
|
||||
applyPeerDialogs(result);
|
||||
for (const auto history : histories) {
|
||||
historyDialogEntryApplied(history);
|
||||
}
|
||||
finalize(histories);
|
||||
}).fail([=](const RPCError &error) {
|
||||
finalize(histories);
|
||||
}).send();
|
||||
}
|
||||
|
||||
void ApiWrap::applyPeerDialogs(const MTPmessages_PeerDialogs &dialogs) {
|
||||
Expects(dialogs.type() == mtpc_messages_peerDialogs);
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ public:
|
|||
void requestDialogEntry(
|
||||
not_null<History*> history,
|
||||
Fn<void()> callback = nullptr);
|
||||
void requestDialogEntries(std::vector<not_null<History*>> histories);
|
||||
//void applyFeedSources(const MTPDchannels_feedSources &data); // #feed
|
||||
//void setFeedChannels(
|
||||
// not_null<Data::Feed*> feed,
|
||||
|
|
|
@ -451,9 +451,12 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
|||
}
|
||||
}
|
||||
|
||||
const auto showUnreadInSearchResults = uniqueSearchResults();
|
||||
if (!_waitingForSearch || !_searchResults.empty()) {
|
||||
const auto text = _searchResults.empty()
|
||||
? lang(lng_search_no_results)
|
||||
: showUnreadInSearchResults
|
||||
? qsl("Search results")
|
||||
: lng_search_found_results(
|
||||
lt_count,
|
||||
_searchedMigratedCount + _searchedCount);
|
||||
|
@ -489,7 +492,8 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
|||
active,
|
||||
selected,
|
||||
paintingOther,
|
||||
ms);
|
||||
ms,
|
||||
showUnreadInSearchResults);
|
||||
p.translate(0, st::dialogsRowHeight);
|
||||
}
|
||||
}
|
||||
|
@ -674,7 +678,6 @@ void DialogsInner::paintSearchInFeed(
|
|||
paintSearchInFilter(p, paintUserpic, top, fullWidth, icon, text);
|
||||
}
|
||||
|
||||
|
||||
void DialogsInner::activate() {
|
||||
}
|
||||
|
||||
|
@ -1840,28 +1843,53 @@ void DialogsInner::addAllSavedPeers() {
|
|||
addSavedPeersAfter(QDateTime());
|
||||
}
|
||||
|
||||
bool DialogsInner::uniqueSearchResults() const {
|
||||
return Auth().supportMode()
|
||||
&& _filter.startsWith('#')
|
||||
&& !_searchInChat;
|
||||
}
|
||||
|
||||
bool DialogsInner::hasHistoryInSearchResults(not_null<History*> history) const {
|
||||
using Result = std::unique_ptr<Dialogs::FakeRow>;
|
||||
return ranges::find(
|
||||
_searchResults,
|
||||
history,
|
||||
[](const Result &result) { return result->item()->history(); }
|
||||
) != end(_searchResults);
|
||||
}
|
||||
|
||||
bool DialogsInner::searchReceived(
|
||||
const QVector<MTPMessage> &messages,
|
||||
DialogsSearchRequestType type,
|
||||
int fullCount) {
|
||||
const auto uniquePeers = uniqueSearchResults();
|
||||
if (type == DialogsSearchFromStart || type == DialogsSearchPeerFromStart) {
|
||||
clearSearchResults(false);
|
||||
}
|
||||
auto isGlobalSearch = (type == DialogsSearchFromStart || type == DialogsSearchFromOffset);
|
||||
auto isMigratedSearch = (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset);
|
||||
|
||||
auto unknownUnreadCounts = std::vector<not_null<History*>>();
|
||||
TimeId lastDateFound = 0;
|
||||
for_const (auto message, messages) {
|
||||
auto msgId = idFromMessage(message);
|
||||
auto peerId = peerFromMessage(message);
|
||||
auto lastDate = dateFromMessage(message);
|
||||
if (auto peer = App::peerLoaded(peerId)) {
|
||||
if (const auto peer = App::peerLoaded(peerId)) {
|
||||
if (lastDate) {
|
||||
auto item = App::histories().addNewMessage(message, NewMessageExisting);
|
||||
_searchResults.push_back(
|
||||
std::make_unique<Dialogs::FakeRow>(
|
||||
_searchInChat,
|
||||
item));
|
||||
const auto item = App::histories().addNewMessage(
|
||||
message,
|
||||
NewMessageExisting);
|
||||
const auto history = item->history();
|
||||
if (!uniquePeers || !hasHistoryInSearchResults(history)) {
|
||||
_searchResults.push_back(
|
||||
std::make_unique<Dialogs::FakeRow>(
|
||||
_searchInChat,
|
||||
item));
|
||||
if (uniquePeers && !history->unreadCountKnown()) {
|
||||
unknownUnreadCounts.push_back(history);
|
||||
}
|
||||
}
|
||||
lastDateFound = lastDate;
|
||||
if (isGlobalSearch) {
|
||||
_lastSearchDate = lastDateFound;
|
||||
|
@ -1891,7 +1919,12 @@ bool DialogsInner::searchReceived(
|
|||
|| type == DialogsSearchMigratedFromOffset)) {
|
||||
_waitingForSearch = false;
|
||||
}
|
||||
|
||||
refresh();
|
||||
|
||||
if (!unknownUnreadCounts.empty()) {
|
||||
Auth().api().requestDialogEntries(std::move(unknownUnreadCounts));
|
||||
}
|
||||
return lastDateFound != 0;
|
||||
}
|
||||
|
||||
|
@ -2476,7 +2509,9 @@ bool DialogsInner::chooseRow() {
|
|||
if (const auto history = chosen.key.history()) {
|
||||
App::main()->choosePeer(
|
||||
history->peer->id,
|
||||
chosen.message.fullId.msg);
|
||||
(uniqueSearchResults()
|
||||
? ShowAtUnreadMsgId
|
||||
: chosen.message.fullId.msg));
|
||||
} else if (const auto feed = chosen.key.feed()) {
|
||||
_controller->showSection(
|
||||
HistoryFeed::Memento(feed, chosen.message),
|
||||
|
|
|
@ -189,6 +189,8 @@ private:
|
|||
void handlePeerNameChange(
|
||||
not_null<PeerData*> peer,
|
||||
const base::flat_set<QChar> &oldLetters);
|
||||
bool uniqueSearchResults() const;
|
||||
bool hasHistoryInSearchResults(not_null<History*> history) const;
|
||||
|
||||
void applyDialog(const MTPDdialog &dialog);
|
||||
// void applyFeedDialog(const MTPDdialogFeed &dialog); // #feed
|
||||
|
|
|
@ -52,6 +52,102 @@ void paintRowDate(Painter &p, QDateTime date, QRect &rectForName, bool active, b
|
|||
paintRowTopRight(p, dt, rectForName, active, selected);
|
||||
}
|
||||
|
||||
void PaintNarrowCounter(
|
||||
Painter &p,
|
||||
bool displayUnreadCounter,
|
||||
bool displayUnreadMark,
|
||||
bool displayMentionBadge,
|
||||
int unreadCount,
|
||||
bool active,
|
||||
bool unreadMuted) {
|
||||
auto skipBeforeMention = 0;
|
||||
if (displayUnreadCounter || displayUnreadMark) {
|
||||
auto counter = (unreadCount > 0)
|
||||
? QString::number(unreadCount)
|
||||
: QString();
|
||||
const auto allowDigits = displayMentionBadge ? 1 : 3;
|
||||
if (counter.size() > allowDigits + 1) {
|
||||
counter = qsl("..") + counter.mid(counter.size() - allowDigits);
|
||||
}
|
||||
auto unreadRight = st::dialogsPadding.x() + st::dialogsPhotoSize;
|
||||
auto unreadTop = st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight;
|
||||
auto unreadWidth = 0;
|
||||
|
||||
UnreadBadgeStyle st;
|
||||
st.active = active;
|
||||
st.muted = unreadMuted;
|
||||
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth);
|
||||
skipBeforeMention += unreadWidth + st.padding;
|
||||
}
|
||||
if (displayMentionBadge) {
|
||||
auto counter = qsl("@");
|
||||
auto unreadRight = st::dialogsPadding.x() + st::dialogsPhotoSize - skipBeforeMention;
|
||||
auto unreadTop = st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight;
|
||||
auto unreadWidth = 0;
|
||||
|
||||
UnreadBadgeStyle st;
|
||||
st.active = active;
|
||||
st.muted = false;
|
||||
st.padding = 0;
|
||||
st.textTop = 0;
|
||||
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth);
|
||||
}
|
||||
}
|
||||
|
||||
int PaintWideCounter(
|
||||
Painter &p,
|
||||
int texttop,
|
||||
int availableWidth,
|
||||
int fullWidth,
|
||||
bool displayUnreadCounter,
|
||||
bool displayUnreadMark,
|
||||
bool displayMentionBadge,
|
||||
bool displayPinnedIcon,
|
||||
int unreadCount,
|
||||
bool active,
|
||||
bool selected,
|
||||
bool unreadMuted) {
|
||||
const auto initial = availableWidth;
|
||||
auto hadOneBadge = false;
|
||||
if (displayUnreadCounter || displayUnreadMark) {
|
||||
auto counter = (unreadCount > 0)
|
||||
? QString::number(unreadCount)
|
||||
: QString();
|
||||
auto unreadRight = fullWidth - st::dialogsPadding.x();
|
||||
auto unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2;
|
||||
auto unreadWidth = 0;
|
||||
|
||||
UnreadBadgeStyle st;
|
||||
st.active = active;
|
||||
st.muted = unreadMuted;
|
||||
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth);
|
||||
availableWidth -= unreadWidth + st.padding;
|
||||
|
||||
hadOneBadge = true;
|
||||
} else if (displayPinnedIcon) {
|
||||
auto &icon = (active ? st::dialogsPinnedIconActive : (selected ? st::dialogsPinnedIconOver : st::dialogsPinnedIcon));
|
||||
icon.paint(p, fullWidth - st::dialogsPadding.x() - icon.width(), texttop, fullWidth);
|
||||
availableWidth -= icon.width() + st::dialogsUnreadPadding;
|
||||
|
||||
hadOneBadge = true;
|
||||
}
|
||||
if (displayMentionBadge) {
|
||||
auto counter = qsl("@");
|
||||
auto unreadRight = fullWidth - st::dialogsPadding.x() - (initial - availableWidth);
|
||||
auto unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2;
|
||||
auto unreadWidth = 0;
|
||||
|
||||
UnreadBadgeStyle st;
|
||||
st.active = active;
|
||||
st.muted = false;
|
||||
st.padding = 0;
|
||||
st.textTop = 0;
|
||||
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth);
|
||||
availableWidth -= unreadWidth + st.padding + (hadOneBadge ? st::dialogsUnreadPadding : 0);
|
||||
}
|
||||
return availableWidth;
|
||||
}
|
||||
|
||||
enum class Flag {
|
||||
Active = 0x01,
|
||||
Selected = 0x02,
|
||||
|
@ -370,7 +466,13 @@ UnreadBadgeStyle::UnreadBadgeStyle()
|
|||
, font(st::dialogsUnreadFont) {
|
||||
}
|
||||
|
||||
void paintUnreadCount(Painter &p, const QString &text, int x, int y, const UnreadBadgeStyle &st, int *outUnreadWidth) {
|
||||
void paintUnreadCount(
|
||||
Painter &p,
|
||||
const QString &text,
|
||||
int x,
|
||||
int y,
|
||||
const UnreadBadgeStyle &st,
|
||||
int *outUnreadWidth) {
|
||||
int unreadWidth = st.font->width(text);
|
||||
int unreadRectWidth = unreadWidth + 2 * st.padding;
|
||||
int unreadRectHeight = st.size;
|
||||
|
@ -464,45 +566,22 @@ void RowPainter::paint(
|
|||
| (onlyBackground ? Flag::OnlyBackground : Flag(0))
|
||||
| (peer && peer->isSelf() ? Flag::SavedMessages : Flag(0));
|
||||
const auto paintItemCallback = [&](int nameleft, int namewidth) {
|
||||
auto availableWidth = namewidth;
|
||||
auto texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
|
||||
auto hadOneBadge = false;
|
||||
if (displayUnreadCounter || displayUnreadMark) {
|
||||
auto counter = (unreadCount > 0)
|
||||
? QString::number(unreadCount)
|
||||
: QString();
|
||||
auto unreadRight = fullWidth - st::dialogsPadding.x();
|
||||
auto unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2;
|
||||
auto unreadWidth = 0;
|
||||
|
||||
UnreadBadgeStyle st;
|
||||
st.active = active;
|
||||
st.muted = unreadMuted;
|
||||
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth);
|
||||
availableWidth -= unreadWidth + st.padding;
|
||||
|
||||
hadOneBadge = true;
|
||||
} else if (displayPinnedIcon) {
|
||||
auto &icon = (active ? st::dialogsPinnedIconActive : (selected ? st::dialogsPinnedIconOver : st::dialogsPinnedIcon));
|
||||
icon.paint(p, fullWidth - st::dialogsPadding.x() - icon.width(), texttop, fullWidth);
|
||||
availableWidth -= icon.width() + st::dialogsUnreadPadding;
|
||||
|
||||
hadOneBadge = true;
|
||||
}
|
||||
if (displayMentionBadge) {
|
||||
auto counter = qsl("@");
|
||||
auto unreadRight = fullWidth - st::dialogsPadding.x() - (namewidth - availableWidth);
|
||||
auto unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2;
|
||||
auto unreadWidth = 0;
|
||||
|
||||
UnreadBadgeStyle st;
|
||||
st.active = active;
|
||||
st.muted = false;
|
||||
st.padding = 0;
|
||||
st.textTop = 0;
|
||||
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth);
|
||||
availableWidth -= unreadWidth + st.padding + (hadOneBadge ? st::dialogsUnreadPadding : 0);
|
||||
}
|
||||
const auto texttop = st::dialogsPadding.y()
|
||||
+ st::msgNameFont->height
|
||||
+ st::dialogsSkip;
|
||||
const auto availableWidth = PaintWideCounter(
|
||||
p,
|
||||
texttop,
|
||||
namewidth,
|
||||
fullWidth,
|
||||
displayUnreadCounter,
|
||||
displayUnreadMark,
|
||||
displayMentionBadge,
|
||||
displayPinnedIcon,
|
||||
unreadCount,
|
||||
active,
|
||||
selected,
|
||||
unreadMuted);
|
||||
const auto &color = active
|
||||
? st::dialogsTextFgServiceActive
|
||||
: (selected
|
||||
|
@ -517,7 +596,7 @@ void RowPainter::paint(
|
|||
color,
|
||||
ms) : false;
|
||||
if (!actionWasPainted) {
|
||||
auto itemRect = QRect(
|
||||
const auto itemRect = QRect(
|
||||
nameleft,
|
||||
texttop,
|
||||
availableWidth,
|
||||
|
@ -533,39 +612,14 @@ void RowPainter::paint(
|
|||
}
|
||||
};
|
||||
const auto paintCounterCallback = [&] {
|
||||
auto hadOneBadge = false;
|
||||
auto skipBeforeMention = 0;
|
||||
if (displayUnreadCounter || displayUnreadMark) {
|
||||
auto counter = (unreadCount > 0)
|
||||
? QString::number(unreadCount)
|
||||
: QString();
|
||||
const auto allowDigits = displayMentionBadge ? 1 : 3;
|
||||
if (counter.size() > allowDigits + 1) {
|
||||
counter = qsl("..") + counter.mid(counter.size() - allowDigits);
|
||||
}
|
||||
auto unreadRight = st::dialogsPadding.x() + st::dialogsPhotoSize;
|
||||
auto unreadTop = st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight;
|
||||
auto unreadWidth = 0;
|
||||
|
||||
UnreadBadgeStyle st;
|
||||
st.active = active;
|
||||
st.muted = unreadMuted;
|
||||
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth);
|
||||
skipBeforeMention += unreadWidth + st.padding;
|
||||
}
|
||||
if (displayMentionBadge) {
|
||||
auto counter = qsl("@");
|
||||
auto unreadRight = st::dialogsPadding.x() + st::dialogsPhotoSize - skipBeforeMention;
|
||||
auto unreadTop = st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight;
|
||||
auto unreadWidth = 0;
|
||||
|
||||
UnreadBadgeStyle st;
|
||||
st.active = active;
|
||||
st.muted = false;
|
||||
st.padding = 0;
|
||||
st.textTop = 0;
|
||||
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth);
|
||||
}
|
||||
PaintNarrowCounter(
|
||||
p,
|
||||
displayUnreadCounter,
|
||||
displayUnreadMark,
|
||||
displayMentionBadge,
|
||||
unreadCount,
|
||||
active,
|
||||
unreadMuted);
|
||||
};
|
||||
paintRow(
|
||||
p,
|
||||
|
@ -590,7 +644,8 @@ void RowPainter::paint(
|
|||
bool active,
|
||||
bool selected,
|
||||
bool onlyBackground,
|
||||
TimeMs ms) {
|
||||
TimeMs ms,
|
||||
bool displayUnreadInfo) {
|
||||
auto item = row->item();
|
||||
auto history = item->history();
|
||||
auto cloudDraft = nullptr;
|
||||
|
@ -618,19 +673,63 @@ void RowPainter::paint(
|
|||
}
|
||||
return HistoryItem::DrawInDialog::Normal;
|
||||
}();
|
||||
|
||||
const auto unreadCount = displayUnreadInfo
|
||||
? history->chatListUnreadCount()
|
||||
: 0;
|
||||
const auto unreadMark = displayUnreadInfo
|
||||
&& history->chatListUnreadMark();
|
||||
const auto unreadMuted = history->chatListMutedBadge();
|
||||
const auto displayMentionBadge = displayUnreadInfo
|
||||
&& history->hasUnreadMentions();
|
||||
const auto displayUnreadCounter = (unreadCount > 0);
|
||||
const auto displayUnreadMark = !displayUnreadCounter
|
||||
&& !displayMentionBadge
|
||||
&& unreadMark;
|
||||
const auto displayPinnedIcon = false;
|
||||
|
||||
const auto paintItemCallback = [&](int nameleft, int namewidth) {
|
||||
auto lastWidth = namewidth;
|
||||
auto texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
|
||||
const auto texttop = st::dialogsPadding.y()
|
||||
+ st::msgNameFont->height
|
||||
+ st::dialogsSkip;
|
||||
const auto availableWidth = PaintWideCounter(
|
||||
p,
|
||||
texttop,
|
||||
namewidth,
|
||||
fullWidth,
|
||||
displayUnreadCounter,
|
||||
displayUnreadMark,
|
||||
displayMentionBadge,
|
||||
displayPinnedIcon,
|
||||
unreadCount,
|
||||
active,
|
||||
selected,
|
||||
unreadMuted);
|
||||
|
||||
const auto itemRect = QRect(
|
||||
nameleft,
|
||||
texttop,
|
||||
availableWidth,
|
||||
st::dialogsTextFont->height);
|
||||
item->drawInDialog(
|
||||
p,
|
||||
QRect(nameleft, texttop, lastWidth, st::dialogsTextFont->height),
|
||||
itemRect,
|
||||
active,
|
||||
selected,
|
||||
drawInDialogWay,
|
||||
row->_cacheFor,
|
||||
row->_cache);
|
||||
};
|
||||
const auto paintCounterCallback = [] {};
|
||||
const auto paintCounterCallback = [&] {
|
||||
PaintNarrowCounter(
|
||||
p,
|
||||
displayUnreadCounter,
|
||||
displayUnreadMark,
|
||||
displayMentionBadge,
|
||||
unreadCount,
|
||||
active,
|
||||
unreadMuted);
|
||||
};
|
||||
const auto showSavedMessages = history->peer->isSelf()
|
||||
&& !row->searchInChat();
|
||||
const auto flags = (active ? Flag::Active : Flag(0))
|
||||
|
|
|
@ -44,7 +44,8 @@ public:
|
|||
bool active,
|
||||
bool selected,
|
||||
bool onlyBackground,
|
||||
TimeMs ms);
|
||||
TimeMs ms,
|
||||
bool displayUnreadInfo);
|
||||
static QRect sendActionAnimationRect(
|
||||
int animationWidth,
|
||||
int animationHeight,
|
||||
|
|
Loading…
Add table
Reference in a new issue