Display author photo / name in search results.

This commit is contained in:
John Preston 2017-09-05 20:21:56 +03:00
parent def97b3f70
commit c09fbcfeb3
9 changed files with 84 additions and 25 deletions

View File

@ -1530,7 +1530,7 @@ bool DialogsInner::searchReceived(const QVector<MTPMessage> &messages, DialogsSe
if (auto peer = App::peerLoaded(peerId)) {
if (lastDate) {
auto item = App::histories().addNewMessage(message, NewMessageExisting);
_searchResults.push_back(std::make_unique<Dialogs::FakeRow>(item));
_searchResults.push_back(std::make_unique<Dialogs::FakeRow>(_searchInPeer, item));
lastDateFound = lastDate;
if (isGlobalSearch) {
_lastSearchDate = lastDateFound;

View File

@ -58,14 +58,13 @@ void paintRowDate(Painter &p, const QDateTime &date, QRect &rectForName, bool ac
}
template <typename PaintItemCallback, typename PaintCounterCallback>
void paintRow(Painter &p, const RippleRow *row, History *history, HistoryItem *item, Data::Draft *draft, QDateTime date, int fullWidth, bool active, bool selected, bool onlyBackground, TimeMs ms, PaintItemCallback paintItemCallback, PaintCounterCallback paintCounterCallback) {
void paintRow(Painter &p, const RippleRow *row, History *history, not_null<PeerData*> from, HistoryItem *item, Data::Draft *draft, QDateTime date, int fullWidth, bool active, bool selected, bool onlyBackground, TimeMs ms, PaintItemCallback paintItemCallback, PaintCounterCallback paintCounterCallback) {
QRect fullRect(0, 0, fullWidth, st::dialogsRowHeight);
p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg));
row->paintRipple(p, 0, 0, fullWidth, ms, &(active ? st::dialogsRippleBgActive : st::dialogsRippleBg)->c);
if (onlyBackground) return;
auto userpicPeer = (history->peer->migrateTo() ? history->peer->migrateTo() : history->peer);
userpicPeer->paintUserpicLeft(p, st::dialogsPadding.x(), st::dialogsPadding.y(), fullWidth, st::dialogsPhotoSize);
from->paintUserpicLeft(p, st::dialogsPadding.x(), st::dialogsPadding.y(), fullWidth, st::dialogsPhotoSize);
auto nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
if (fullWidth <= nameleft) {
@ -78,7 +77,7 @@ void paintRow(Painter &p, const RippleRow *row, History *history, HistoryItem *i
auto namewidth = fullWidth - nameleft - st::dialogsPadding.x();
QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height);
if (auto chatTypeIcon = ChatTypeIcon(history->peer, active, selected)) {
if (auto chatTypeIcon = ChatTypeIcon(from, active, selected)) {
chatTypeIcon->paint(p, rectForName.topLeft(), fullWidth);
rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip);
}
@ -151,14 +150,14 @@ void paintRow(Painter &p, const RippleRow *row, History *history, HistoryItem *i
sendStateIcon->paint(p, rectForName.topLeft() + QPoint(rectForName.width(), 0), fullWidth);
}
if (history->peer->isVerified()) {
if (from == history->peer && from->isVerified()) {
auto icon = &(active ? st::dialogsVerifiedIconActive : (selected ? st::dialogsVerifiedIconOver : st::dialogsVerifiedIcon));
rectForName.setWidth(rectForName.width() - icon->width());
icon->paint(p, rectForName.topLeft() + QPoint(qMin(history->peer->dialogName().maxWidth(), rectForName.width()), 0), fullWidth);
icon->paint(p, rectForName.topLeft() + QPoint(qMin(from->dialogName().maxWidth(), rectForName.width()), 0), fullWidth);
}
p.setPen(active ? st::dialogsNameFgActive : (selected ? st::dialogsNameFgOver : st::dialogsNameFg));
history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
from->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
}
struct UnreadBadgeSizeData {
@ -292,7 +291,8 @@ void RowPainter::paint(Painter &p, const Row *row, int fullWidth, bool active, b
if (item && cloudDraft && unreadCount > 0) {
cloudDraft = nullptr; // Draw item, if draft is older.
}
paintRow(p, row, history, item, cloudDraft, displayDate(), fullWidth, active, selected, onlyBackground, ms, [&p, fullWidth, active, selected, ms, history, unreadCount](int nameleft, int namewidth, HistoryItem *item) {
auto from = (history->peer->migrateTo() ? history->peer->migrateTo() : history->peer);
paintRow(p, row, history, from, item, cloudDraft, displayDate(), fullWidth, active, selected, onlyBackground, ms, [&p, fullWidth, active, selected, ms, history, unreadCount](int nameleft, int namewidth, HistoryItem *item) {
auto availableWidth = namewidth;
auto texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
auto hadOneBadge = false;
@ -343,7 +343,14 @@ void RowPainter::paint(Painter &p, const Row *row, int fullWidth, bool active, b
}
auto &color = active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService);
if (!history->paintSendAction(p, nameleft, texttop, availableWidth, fullWidth, color, ms)) {
item->drawInDialog(p, QRect(nameleft, texttop, availableWidth, st::dialogsTextFont->height), active, selected, history->textCachedFor, history->lastItemTextCache);
item->drawInDialog(
p,
QRect(nameleft, texttop, availableWidth, st::dialogsTextFont->height),
active,
selected,
HistoryItem::DrawInDialog::Normal,
history->textCachedFor,
history->lastItemTextCache);
}
}, [&p, fullWidth, active, selected, ms, history, unreadCount] {
if (unreadCount) {
@ -367,9 +374,24 @@ void RowPainter::paint(Painter &p, const Row *row, int fullWidth, bool active, b
void RowPainter::paint(Painter &p, const FakeRow *row, int fullWidth, bool active, bool selected, bool onlyBackground, TimeMs ms) {
auto item = row->item();
auto history = item->history();
paintRow(p, row, history, item, nullptr, item->date, fullWidth, active, selected, onlyBackground, ms, [&p, row, active, selected](int nameleft, int namewidth, HistoryItem *item) {
auto from = [&] {
if (auto searchPeer = row->searchInPeer()) {
if (!searchPeer->isChannel() || searchPeer->isMegagroup()) {
return item->from();
}
}
return (history->peer->migrateTo() ? history->peer->migrateTo() : history->peer);
}();
paintRow(p, row, history, from, item, nullptr, item->date, fullWidth, active, selected, onlyBackground, ms, [&p, row, active, selected](int nameleft, int namewidth, HistoryItem *item) {
int lastWidth = namewidth, texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
item->drawInDialog(p, QRect(nameleft, texttop, lastWidth, st::dialogsTextFont->height), active, selected, row->_cacheFor, row->_cache);
item->drawInDialog(
p,
QRect(nameleft, texttop, lastWidth, st::dialogsTextFont->height),
active,
selected,
HistoryItem::DrawInDialog::WithoutSender,
row->_cacheFor,
row->_cache);
}, [] {
});
}

View File

@ -52,7 +52,10 @@ void RippleRow::paintRipple(Painter &p, int x, int y, int outerWidth, TimeMs ms,
}
}
FakeRow::FakeRow(HistoryItem *item) : _item(item), _cache(st::dialogsTextWidthMin) {
FakeRow::FakeRow(PeerData *searchInPeer, not_null<HistoryItem*> item)
: _searchInPeer(searchInPeer)
, _item(item)
, _cache(st::dialogsTextWidthMin) {
}
} // namespace Dialogs

View File

@ -78,16 +78,20 @@ private:
class FakeRow : public RippleRow {
public:
FakeRow(HistoryItem *item);
FakeRow(PeerData *searchInPeer, not_null<HistoryItem*> item);
HistoryItem *item() const {
PeerData *searchInPeer() const {
return _searchInPeer;
}
not_null<HistoryItem*> item() const {
return _item;
}
private:
friend class Layout::RowPainter;
HistoryItem *_item;
PeerData *_searchInPeer = nullptr;
not_null<HistoryItem*> _item;
mutable const HistoryItem *_cacheFor = nullptr;
mutable Text _cache;

View File

@ -1166,7 +1166,7 @@ QString HistoryItem::notificationText() const {
return result;
}
QString HistoryItem::inDialogsText() const {
QString HistoryItem::inDialogsText(DrawInDialog way) const {
auto getText = [this]() {
if (emptyText()) {
return _media ? _media->inDialogsText() : QString();
@ -1174,7 +1174,10 @@ QString HistoryItem::inDialogsText() const {
return TextUtilities::Clean(_text.originalText());
};
auto plainText = getText();
if ((!_history->peer->isUser() || out()) && !isPost() && !isEmpty()) {
if ((!_history->peer->isUser() || out())
&& !isPost()
&& !isEmpty()
&& (way != DrawInDialog::WithoutSender)) {
auto fromText = author()->isSelf() ? lang(lng_from_you) : author()->shortName();
auto fromWrapped = textcmdLink(1, lng_dialogs_text_from_wrapped(lt_from, TextUtilities::Clean(fromText)));
return lng_dialogs_text_with_from(lt_from_part, fromWrapped, lt_message, plainText);
@ -1182,10 +1185,17 @@ QString HistoryItem::inDialogsText() const {
return plainText;
}
void HistoryItem::drawInDialog(Painter &p, const QRect &r, bool active, bool selected, const HistoryItem *&cacheFor, Text &cache) const {
void HistoryItem::drawInDialog(
Painter &p,
const QRect &r,
bool active,
bool selected,
DrawInDialog way,
const HistoryItem *&cacheFor,
Text &cache) const {
if (cacheFor != this) {
cacheFor = this;
cache.setText(st::dialogsTextStyle, inDialogsText(), _textDlgOptions);
cache.setText(st::dialogsTextStyle, inDialogsText(way), _textDlgOptions);
}
if (r.width()) {
p.setTextPalette(active ? st::dialogsTextPaletteActive : (selected ? st::dialogsTextPaletteOver : st::dialogsTextPalette));

View File

@ -686,9 +686,14 @@ public:
}
virtual QString notificationText() const;
enum class DrawInDialog {
Normal,
WithoutSender,
};
// Returns text with link-start and link-end commands for service-color highlighting.
// Example: "[link1-start]You:[link1-end] [link1-start]Photo,[link1-end] caption text"
virtual QString inDialogsText() const;
virtual QString inDialogsText(DrawInDialog way) const;
virtual QString inReplyText() const {
return notificationText();
}
@ -709,7 +714,15 @@ public:
virtual void setViewsCount(int32 count) {
}
virtual void setId(MsgId newId);
void drawInDialog(Painter &p, const QRect &r, bool active, bool selected, const HistoryItem *&cacheFor, Text &cache) const;
void drawInDialog(
Painter &p,
const QRect &r,
bool active,
bool selected,
DrawInDialog way,
const HistoryItem *&cacheFor,
Text &cache) const;
bool emptyText() const {
return _text.isEmpty();

View File

@ -445,7 +445,7 @@ TextWithEntities HistoryService::selectedText(TextSelection selection) const {
return _text.originalTextWithEntities((selection == FullSelection) ? AllTextSelection : selection);
}
QString HistoryService::inDialogsText() const {
QString HistoryService::inDialogsText(DrawInDialog way) const {
return textcmdLink(1, TextUtilities::Clean(notificationText()));
}

View File

@ -108,7 +108,7 @@ public:
return true;
}
TextWithEntities selectedText(TextSelection selection) const override;
QString inDialogsText() const override;
QString inDialogsText(DrawInDialog way) const override;
QString inReplyText() const override;
~HistoryService();

View File

@ -664,7 +664,14 @@ void Notification::updateNotifyDisplay() {
QRect r(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dialogsTextFont->height);
if (_item) {
auto active = false, selected = false;
_item->drawInDialog(p, r, active, selected, textCachedFor, itemTextCache);
_item->drawInDialog(
p,
r,
active,
selected,
HistoryItem::DrawInDialog::Normal,
textCachedFor,
itemTextCache);
} else if (_forwardedCount > 1) {
p.setFont(st::dialogsTextFont);
if (_author) {