2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-31 06:35:14 +00:00

Display channels promoted by proxy on top.

This commit is contained in:
John Preston
2018-05-11 17:03:53 +03:00
parent df9ec4b466
commit d3f85b4c4e
25 changed files with 392 additions and 387 deletions

View File

@@ -26,6 +26,10 @@ uint64 DialogPosFromDate(const QDateTime &date) {
return (uint64(date.toTime_t()) << 32) | (++DialogsPosToTopShift);
}
uint64 ProxyPromotedDialogPos() {
return 0xFFFFFFFFFFFF0001ULL;
}
uint64 PinnedDialogPos(int pinnedIndex) {
return 0xFFFFFFFF00000000ULL + pinnedIndex;
}
@@ -49,12 +53,22 @@ void Entry::cachePinnedIndex(int index) {
}
}
void Entry::cacheProxyPromoted(bool promoted) {
if (_isProxyPromoted != promoted) {
_isProxyPromoted = promoted;
updateChatListSortPosition();
updateChatListEntry();
}
}
bool Entry::needUpdateInChatList() const {
return inChatList(Dialogs::Mode::All) || shouldBeInChatList();
}
void Entry::updateChatListSortPosition() {
_sortKeyInChatList = isPinnedDialog()
_sortKeyInChatList = useProxyPromotion()
? ProxyPromotedDialogPos()
: isPinnedDialog()
? PinnedDialogPos(_pinnedIndex)
: DialogPosFromDate(adjustChatListDate());
if (needUpdateInChatList()) {

View File

@@ -56,6 +56,11 @@ public:
return _pinnedIndex > 0;
}
void cachePinnedIndex(int index);
bool isProxyPromoted() const {
return _isProxyPromoted;
}
virtual bool useProxyPromotion() const = 0;
void cacheProxyPromoted(bool promoted);
uint64 sortKeyInChatList() const {
return _sortKeyInChatList;
}
@@ -111,6 +116,7 @@ private:
RowsByLetter _chatListLinks[2];
uint64 _sortKeyInChatList = 0;
int _pinnedIndex = 0;
bool _isProxyPromoted = false;
QDateTime _lastMessageDate;
};

View File

@@ -165,6 +165,22 @@ int DialogsInner::dialogsOffset() const {
return _dialogsImportant ? st::dialogsImportantBarHeight : 0;
}
int DialogsInner::proxyPromotedCount() const {
auto result = 0;
for_const (auto row, *shownDialogs()) {
if (row->entry()->useProxyPromotion()) {
++result;
} else {
break;
}
}
return result;
}
int DialogsInner::pinnedOffset() const {
return dialogsOffset() + proxyPromotedCount() * st::dialogsRowHeight;
}
int DialogsInner::filteredOffset() const {
return _hashtagResults.size() * st::mentionHeight;
}
@@ -231,13 +247,39 @@ void DialogsInner::paintRegion(Painter &p, const QRegion &region, bool paintingO
dialogsClip = dialogsClip.marginsAdded(QMargins(0, st::dialogsRowHeight, 0, st::dialogsRowHeight));
}
const auto promoted = proxyPromotedCount();
const auto paintDialog = [&](not_null<Dialogs::Row*> row) {
const auto pinned = row->pos() - promoted;
const auto count = _pinnedRows.size();
const auto xadd = 0;
const auto yadd = base::in_range(pinned, 0, count)
? qRound(_pinnedRows[pinned].yadd.current())
: 0;
if (xadd || yadd) {
p.translate(xadd, yadd);
}
const auto isActive = (row->key() == active);
const auto isSelected = (row->key() == selected);
Dialogs::Layout::RowPainter::paint(
p,
row,
fullWidth,
isActive,
isSelected,
paintingOther,
ms);
if (xadd || yadd) {
p.translate(-xadd, -yadd);
}
};
auto i = list.cfind(dialogsClip.top(), st::dialogsRowHeight);
if (i != list.cend()) {
auto lastPaintedPos = (*i)->pos();
// If we're reordering pinned chats we need to fill this area background first.
if (reorderingPinned) {
p.fillRect(0, 0, fullWidth, st::dialogsRowHeight * _pinnedRows.size(), st::dialogsBg);
p.fillRect(0, promoted * st::dialogsRowHeight, fullWidth, st::dialogsRowHeight * _pinnedRows.size(), st::dialogsBg);
}
p.translate(0, lastPaintedPos * st::dialogsRowHeight);
@@ -248,15 +290,9 @@ void DialogsInner::paintRegion(Painter &p, const QRegion &region, bool paintingO
}
// Skip currently dragged chat to paint it above others after.
if (lastPaintedPos != _aboveIndex) {
paintDialog(
p,
row,
fullWidth,
active,
selected,
paintingOther,
ms);
if (lastPaintedPos != promoted + _aboveIndex
|| _aboveIndex < 0) {
paintDialog(row);
}
p.translate(0, st::dialogsRowHeight);
@@ -265,11 +301,11 @@ void DialogsInner::paintRegion(Painter &p, const QRegion &region, bool paintingO
// Paint the dragged chat above all others.
if (_aboveIndex >= 0) {
auto i = list.cfind(_aboveIndex, 1);
auto i = list.cfind(promoted + _aboveIndex, 1);
auto pos = (i == list.cend()) ? -1 : (*i)->pos();
if (pos == _aboveIndex) {
if (pos == promoted + _aboveIndex) {
p.translate(0, (pos - lastPaintedPos) * st::dialogsRowHeight);
paintDialog(p, *i, fullWidth, active, selected, paintingOther, ms);
paintDialog(*i);
p.translate(0, (lastPaintedPos - pos) * st::dialogsRowHeight);
}
}
@@ -459,33 +495,6 @@ void DialogsInner::paintRegion(Painter &p, const QRegion &region, bool paintingO
}
}
void DialogsInner::paintDialog(
Painter &p,
not_null<Dialogs::Row*> row,
int fullWidth,
Dialogs::Key active,
Dialogs::Key selected,
bool onlyBackground,
TimeMs ms) {
auto pos = row->pos();
auto xadd = 0, yadd = 0;
if (pos < _pinnedRows.size()) {
yadd = qRound(_pinnedRows[pos].yadd.current());
}
if (xadd || yadd) p.translate(xadd, yadd);
const auto isActive = (row->key() == active);
const auto isSelected = (row->key() == selected);
Dialogs::Layout::RowPainter::paint(
p,
row,
fullWidth,
isActive,
isSelected,
onlyBackground,
ms);
if (xadd || yadd) p.translate(-xadd, -yadd);
}
void DialogsInner::paintPeerSearchResult(
Painter &p,
not_null<const PeerSearchResult*> result,
@@ -846,7 +855,9 @@ void DialogsInner::checkReorderPinnedStart(QPoint localPosition) {
int DialogsInner::shownPinnedCount() const {
auto result = 0;
for_const (auto row, *shownDialogs()) {
if (!row->entry()->isPinnedDialog()) {
if (row->entry()->useProxyPromotion()) {
continue;
} else if (!row->entry()->isPinnedDialog()) {
break;
}
++result;
@@ -860,7 +871,9 @@ int DialogsInner::countPinnedIndex(Dialogs::Row *ofRow) {
}
auto result = 0;
for_const (auto row, *shownDialogs()) {
if (!row->entry()->isPinnedDialog()) {
if (row->entry()->useProxyPromotion()) {
continue;
} else if (!row->entry()->isPinnedDialog()) {
break;
} else if (row == ofRow) {
return result;
@@ -1013,7 +1026,7 @@ void DialogsInner::step_pinnedShifting(TimeMs ms, bool timer) {
if (updateMax < _draggingIndex) updateMax = _draggingIndex;
}
if (updateMin >= 0) {
auto top = _dialogsImportant ? st::dialogsImportantBarHeight : 0;
auto top = pinnedOffset();
auto updateFrom = top + st::dialogsRowHeight * (updateMin - 1);
auto updateHeight = st::dialogsRowHeight * (updateMax - updateMin + 3);
if (base::in_range(_aboveIndex, 0, _pinnedRows.size())) {
@@ -1770,7 +1783,7 @@ void DialogsInner::applyDialog(const MTPDdialog &dialog) {
const auto history = App::history(peerId);
history->applyDialog(dialog);
if (!history->isPinnedDialog()) {
if (!history->useProxyPromotion() && !history->isPinnedDialog()) {
const auto date = history->chatsListDate();
if (!date.isNull()) {
addSavedPeersAfter(date);
@@ -1793,7 +1806,7 @@ void DialogsInner::applyDialog(const MTPDdialog &dialog) {
// const auto feed = Auth().data().feed(feedId);
// feed->applyDialog(dialog);
//
// if (!feed->isPinnedDialog()) {
// if (!feed->useProxyPromotion() && !feed->isPinnedDialog()) {
// const auto date = feed->chatsListDate();
// if (!date.isNull()) {
// addSavedPeersAfter(date);

View File

@@ -213,19 +213,13 @@ private:
UpdateRowSections sections = UpdateRowSection::All);
int dialogsOffset() const;
int proxyPromotedCount() const;
int pinnedOffset() const;
int filteredOffset() const;
int peerSearchOffset() const;
int searchedOffset() const;
int searchInChatSkip() const;
void paintDialog(
Painter &p,
not_null<Dialogs::Row*> row,
int fullWidth,
Dialogs::Key active,
Dialogs::Key selected,
bool onlyBackground,
TimeMs ms);
void paintPeerSearchResult(
Painter &p,
not_null<const PeerSearchResult*> result,

View File

@@ -25,6 +25,14 @@ namespace {
// Show all dates that are in the last 20 hours in time format.
constexpr int kRecentlyInSeconds = 20 * 3600;
void paintRowTopRight(Painter &p, const QString &text, QRect &rectForName, bool active, bool selected) {
const auto width = st::dialogsDateFont->width(text);
rectForName.setWidth(rectForName.width() - width - st::dialogsDateSkip);
p.setFont(st::dialogsDateFont);
p.setPen(active ? st::dialogsDateFgActive : (selected ? st::dialogsDateFgOver : st::dialogsDateFg));
p.drawText(rectForName.left() + rectForName.width() + st::dialogsDateSkip, rectForName.top() + st::msgNameFont->height - st::msgDateFont->descent, text);
}
void paintRowDate(Painter &p, QDateTime date, QRect &rectForName, bool active, bool selected) {
auto now = QDateTime::currentDateTime();
auto lastTime = date;
@@ -41,11 +49,7 @@ void paintRowDate(Painter &p, QDateTime date, QRect &rectForName, bool active, b
} else {
dt = lastDate.toString(qsl("d.MM.yy"));
}
int32 dtWidth = st::dialogsDateFont->width(dt);
rectForName.setWidth(rectForName.width() - dtWidth - st::dialogsDateSkip);
p.setFont(st::dialogsDateFont);
p.setPen(active ? st::dialogsDateFgActive : (selected ? st::dialogsDateFgOver : st::dialogsDateFg));
p.drawText(rectForName.left() + rectForName.width() + st::dialogsDateSkip, rectForName.top() + st::msgNameFont->height - st::msgDateFont->descent, dt);
paintRowTopRight(p, dt, rectForName, active, selected);
}
enum class Flag {
@@ -132,7 +136,11 @@ void paintRow(
namewidth,
st::msgNameFont->height);
if (from && !(flags & Flag::FeedSearchResult)) {
const auto promoted = chat.entry()->useProxyPromotion();
if (promoted) {
const auto text = QString("Proxy sponsor");
paintRowTopRight(p, text, rectForName, active, selected);
} else if (from && !(flags & Flag::FeedSearchResult)) {
if (const auto chatTypeIcon = ChatTypeIcon(from, active, selected)) {
chatTypeIcon->paint(p, rectForName.topLeft(), fullWidth);
rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip);
@@ -147,7 +155,9 @@ void paintRow(
+ st::msgNameFont->height
+ st::dialogsSkip;
if (draft) {
paintRowDate(p, date, rectForName, active, selected);
if (!promoted) {
paintRowDate(p, date, rectForName, active, selected);
}
auto availableWidth = namewidth;
if (entry->isPinnedDialog()) {
@@ -183,7 +193,9 @@ void paintRow(
// Empty history
}
} else if (!item->isEmpty()) {
paintRowDate(p, date, rectForName, active, selected);
if (!promoted) {
paintRowDate(p, date, rectForName, active, selected);
}
paintItemCallback(nameleft, namewidth);
} else if (entry->isPinnedDialog()) {