mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Improve archive chat list entry layout.
This commit is contained in:
parent
2d1dcb36cb
commit
9ff02707bf
13 changed files with 291 additions and 50 deletions
|
@ -304,7 +304,7 @@ historyPeer8NameFgSelected: historyPeer8NameFg; // orange group member name in a
|
|||
historyPeer8UserpicBg: #faa774; // orange userpic background
|
||||
historyPeerUserpicFg: windowFgActive; // default userpic initials
|
||||
historyPeerSavedMessagesBg: historyPeer4UserpicBg; // saved messages userpic background
|
||||
historyPeerArchiveUserpicBg: historyPeer2UserpicBg; // archive folder userpic background
|
||||
historyPeerArchiveUserpicBg: dialogsUnreadBgMuted; // archive folder userpic background
|
||||
|
||||
// Some values are marked as (adjusted), it means they're adjusted by
|
||||
// hue and saturation of the average background color if user chooses
|
||||
|
|
|
@ -1195,11 +1195,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_saved_short" = "Save";
|
||||
"lng_saved_forward_here" = "Forward messages here for quick access";
|
||||
|
||||
"lng_archived_chats" = "Archived chats";
|
||||
"lng_archived_name" = "Archived chats";
|
||||
"lng_archived_add" = "Archive";
|
||||
"lng_archived_remove" = "Unarchive";
|
||||
"lng_chat_archived" = "Chat archived.\nMuted chats will stay archived after new messages arrive.";
|
||||
"lng_chat_unarchived" = "Chat restored from your archive.";
|
||||
"lng_archived_added" = "Chat archived.\nMuted chats will stay archived after new messages arrive.";
|
||||
"lng_archived_removed" = "Chat restored from your archive.";
|
||||
"lng_archived_chats#one" = "{count} chat";
|
||||
"lng_archived_chats#other" = "{count} chats";
|
||||
"lng_archived_unread_two" = "{chat}, {second_chat}";
|
||||
"lng_archived_unread#one" = "{chat}, {second_chat} and {count} more unread chat";
|
||||
"lng_archived_unread#other" = "{chat}, {second_chat} and {count} more unread chats";
|
||||
|
||||
"lng_dialogs_text_with_from" = "{from_part} {message}";
|
||||
"lng_dialogs_text_from_wrapped" = "{from}:";
|
||||
|
|
|
@ -744,26 +744,33 @@ void ApiWrap::requestMoreDialogs(Data::Folder *folder) {
|
|||
MTP_int(hash)
|
||||
)).done([=](const MTPmessages_Dialogs &result) {
|
||||
const auto state = dialogsLoadState(folder);
|
||||
const auto count = result.match([](
|
||||
const MTPDmessages_dialogsNotModified &) {
|
||||
LOG(("API Error: not-modified received for requested dialogs."));
|
||||
return 0;
|
||||
}, [&](const MTPDmessages_dialogs &data) {
|
||||
if (state) {
|
||||
state->listReceived = true;
|
||||
dialogsLoadFinish(folder); // may kill 'state'.
|
||||
}
|
||||
return int(data.vdialogs.v.size());
|
||||
}, [&](const MTPDmessages_dialogsSlice &data) {
|
||||
updateDialogsOffset(
|
||||
folder,
|
||||
data.vdialogs.v,
|
||||
data.vmessages.v);
|
||||
return data.vcount.v;
|
||||
});
|
||||
result.match([](const MTPDmessages_dialogsNotModified & data) {
|
||||
LOG(("API Error: not-modified received for requested dialogs."));
|
||||
}, [&](const auto &data) {
|
||||
if constexpr (data.Is<MTPDmessages_dialogs>()) {
|
||||
if (state) {
|
||||
state->listReceived = true;
|
||||
dialogsLoadFinish(folder); // may kill 'state'.
|
||||
}
|
||||
} else {
|
||||
updateDialogsOffset(
|
||||
folder,
|
||||
data.vdialogs.v,
|
||||
data.vmessages.v);
|
||||
}
|
||||
_session->data().processUsers(data.vusers);
|
||||
_session->data().processChats(data.vchats);
|
||||
_session->data().applyDialogs(
|
||||
folder,
|
||||
data.vmessages.v,
|
||||
data.vdialogs.v);
|
||||
data.vdialogs.v,
|
||||
count);
|
||||
});
|
||||
|
||||
if (!folder) {
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace Data {
|
|||
namespace {
|
||||
|
||||
constexpr auto kLoadedChatsMinCount = 20;
|
||||
constexpr auto kShowChatNamesCount = 2;
|
||||
|
||||
rpl::producer<int> PinnedDialogsInFolderMaxValue() {
|
||||
return rpl::single(
|
||||
|
@ -52,7 +53,7 @@ Folder::Folder(not_null<Data::Session*> owner, FolderId id)
|
|||
: Entry(owner, this)
|
||||
, _id(id)
|
||||
, _chatsList(PinnedDialogsInFolderMaxValue())
|
||||
, _name(lang(lng_archived_chats)) {
|
||||
, _name(lang(lng_archived_name)) {
|
||||
indexNameParts();
|
||||
}
|
||||
|
||||
|
@ -89,6 +90,9 @@ void Folder::indexNameParts() {
|
|||
void Folder::registerOne(not_null<History*> history) {
|
||||
if (_chatsList.indexed()->size() == 1) {
|
||||
updateChatListSortPosition();
|
||||
} else {
|
||||
++_chatListViewVersion;
|
||||
updateChatListEntry();
|
||||
}
|
||||
applyChatListMessage(history->chatListMessage());
|
||||
}
|
||||
|
@ -96,6 +100,9 @@ void Folder::registerOne(not_null<History*> history) {
|
|||
void Folder::unregisterOne(not_null<History*> history) {
|
||||
if (_chatsList.empty()) {
|
||||
updateChatListExistence();
|
||||
} else {
|
||||
++_chatListViewVersion;
|
||||
updateChatListEntry();
|
||||
}
|
||||
if (_chatListMessage && _chatListMessage->history() == history) {
|
||||
computeChatListMessage();
|
||||
|
@ -106,6 +113,12 @@ void Folder::oneListMessageChanged(HistoryItem *from, HistoryItem *to) {
|
|||
if (!applyChatListMessage(to) && _chatListMessage == from) {
|
||||
computeChatListMessage();
|
||||
}
|
||||
if (from || to) {
|
||||
const auto history = from ? from->history() : to->history();
|
||||
if (!history->chatListUnreadState().empty()) {
|
||||
reorderUnreadHistories();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Folder::applyChatListMessage(HistoryItem *item) {
|
||||
|
@ -141,6 +154,55 @@ void Folder::computeChatListMessage() {
|
|||
updateChatListEntry();
|
||||
}
|
||||
|
||||
void Folder::addUnreadHistory(not_null<History*> history) {
|
||||
const auto i = ranges::find(_unreadHistories, history);
|
||||
if (i == end(_unreadHistories)) {
|
||||
_unreadHistories.push_back(history);
|
||||
reorderUnreadHistories();
|
||||
}
|
||||
}
|
||||
|
||||
void Folder::removeUnreadHistory(not_null<History*> history) {
|
||||
const auto i = ranges::find(_unreadHistories, history);
|
||||
if (i != end(_unreadHistories)) {
|
||||
_unreadHistories.erase(i);
|
||||
reorderUnreadHistories();
|
||||
}
|
||||
}
|
||||
|
||||
void Folder::reorderUnreadHistories() {
|
||||
// We want first kShowChatNamesCount histories, by last message date.
|
||||
const auto predicate = [](not_null<History*> a, not_null<History*> b) {
|
||||
const auto aItem = a->chatListMessage();
|
||||
const auto bItem = b->chatListMessage();
|
||||
const auto aDate = aItem ? aItem->date() : TimeId(0);
|
||||
const auto bDate = bItem ? bItem->date() : TimeId(0);
|
||||
return aDate > bDate;
|
||||
};
|
||||
if (size(_unreadHistories) <= kShowChatNamesCount) {
|
||||
ranges::sort(_unreadHistories, predicate);
|
||||
if (!ranges::equal(_unreadHistories, _unreadHistoriesLast)) {
|
||||
_unreadHistoriesLast = _unreadHistories;
|
||||
}
|
||||
} else {
|
||||
const auto till = begin(_unreadHistories) + kShowChatNamesCount - 1;
|
||||
ranges::nth_element(_unreadHistories, till, predicate);
|
||||
if constexpr (kShowChatNamesCount > 2) {
|
||||
ranges::sort(begin(_unreadHistories), till, predicate);
|
||||
}
|
||||
auto &&head = ranges::view::all(
|
||||
_unreadHistories
|
||||
) | ranges::view::take_exactly(
|
||||
kShowChatNamesCount
|
||||
);
|
||||
if (!ranges::equal(head, _unreadHistoriesLast)) {
|
||||
_unreadHistoriesLast = head | ranges::to_vector;
|
||||
}
|
||||
}
|
||||
++_chatListViewVersion;
|
||||
updateChatListEntry();
|
||||
}
|
||||
|
||||
not_null<Dialogs::MainList*> Folder::chatsList() {
|
||||
return &_chatsList;
|
||||
}
|
||||
|
@ -194,6 +256,29 @@ void Folder::setChatsListLoaded(bool loaded) {
|
|||
_chatsList.setLoaded(loaded);
|
||||
}
|
||||
|
||||
void Folder::setCloudChatsListSize(int size) {
|
||||
_cloudChatsListSize = size;
|
||||
updateChatListEntry();
|
||||
}
|
||||
|
||||
int Folder::chatsListSize() const {
|
||||
return std::max(
|
||||
_chatsList.indexed()->size(),
|
||||
_chatsList.loaded() ? 0 : _cloudChatsListSize);
|
||||
}
|
||||
|
||||
int Folder::unreadHistoriesCount() const {
|
||||
return _unreadHistories.size();
|
||||
}
|
||||
|
||||
const std::vector<not_null<History*>> &Folder::lastUnreadHistories() const {
|
||||
return _unreadHistoriesLast;
|
||||
}
|
||||
|
||||
uint32 Folder::chatListViewVersion() const {
|
||||
return _chatListViewVersion;
|
||||
}
|
||||
|
||||
void Folder::requestChatListMessage() {
|
||||
if (!chatListMessageKnown()) {
|
||||
session().api().requestDialogEntry(this);
|
||||
|
@ -252,8 +337,17 @@ void Folder::applyPinnedUpdate(const MTPDupdateDialogPinned &data) {
|
|||
}
|
||||
|
||||
void Folder::unreadStateChanged(
|
||||
const Dialogs::Key &key,
|
||||
const Dialogs::UnreadState &wasState,
|
||||
const Dialogs::UnreadState &nowState) {
|
||||
if (const auto history = key.history()) {
|
||||
if (!wasState.empty() && nowState.empty()) {
|
||||
removeUnreadHistory(history);
|
||||
} else if (wasState.empty() && !nowState.empty()) {
|
||||
addUnreadHistory(history);
|
||||
}
|
||||
}
|
||||
|
||||
const auto updateCloudUnread = _cloudUnread.messagesCount.has_value()
|
||||
&& wasState.messagesCount.has_value();
|
||||
const auto notify = _chatsList.loaded() || updateCloudUnread;
|
||||
|
@ -276,8 +370,19 @@ void Folder::unreadStateChanged(
|
|||
}
|
||||
|
||||
void Folder::unreadEntryChanged(
|
||||
const Dialogs::Key &key,
|
||||
const Dialogs::UnreadState &state,
|
||||
bool added) {
|
||||
if (const auto history = key.history()) {
|
||||
if (!state.empty()) {
|
||||
if (added) {
|
||||
addUnreadHistory(history);
|
||||
} else {
|
||||
removeUnreadHistory(history);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto updateCloudUnread = _cloudUnread.messagesCount.has_value()
|
||||
&& state.messagesCount.has_value();
|
||||
const auto notify = _chatsList.loaded() || updateCloudUnread;
|
||||
|
|
|
@ -44,9 +44,13 @@ public:
|
|||
|
||||
void updateCloudUnread(const MTPDdialogFolder &data);
|
||||
void unreadStateChanged(
|
||||
const Dialogs::Key &key,
|
||||
const Dialogs::UnreadState &wasState,
|
||||
const Dialogs::UnreadState &nowState);
|
||||
void unreadEntryChanged(const Dialogs::UnreadState &state, bool added);
|
||||
void unreadEntryChanged(
|
||||
const Dialogs::Key &key,
|
||||
const Dialogs::UnreadState &state,
|
||||
bool added);
|
||||
|
||||
TimeId adjustedChatListTimeId() const override;
|
||||
|
||||
|
@ -73,12 +77,22 @@ public:
|
|||
|
||||
bool chatsListLoaded() const;
|
||||
void setChatsListLoaded(bool loaded = true);
|
||||
void setCloudChatsListSize(int size);
|
||||
|
||||
int chatsListSize() const;
|
||||
int unreadHistoriesCount() const;
|
||||
const std::vector<not_null<History*>> &lastUnreadHistories() const;
|
||||
uint32 chatListViewVersion() const;
|
||||
|
||||
private:
|
||||
void indexNameParts();
|
||||
bool applyChatListMessage(HistoryItem *item);
|
||||
void computeChatListMessage();
|
||||
|
||||
void addUnreadHistory(not_null<History*> history);
|
||||
void removeUnreadHistory(not_null<History*> history);
|
||||
void reorderUnreadHistories();
|
||||
|
||||
FolderId _id = 0;
|
||||
Dialogs::MainList _chatsList;
|
||||
|
||||
|
@ -87,7 +101,11 @@ private:
|
|||
base::flat_set<QChar> _nameFirstLetters;
|
||||
|
||||
Dialogs::UnreadState _cloudUnread;
|
||||
int _cloudChatsListSize = 0;
|
||||
std::vector<not_null<History*>> _unreadHistories;
|
||||
std::vector<not_null<History*>> _unreadHistoriesLast;
|
||||
HistoryItem *_chatListMessage = nullptr;
|
||||
uint32 _chatListViewVersion = 0;
|
||||
//rpl::variable<MessagePosition> _unreadPosition;
|
||||
|
||||
};
|
||||
|
|
|
@ -1375,13 +1375,17 @@ void Session::applyPinnedChats(
|
|||
void Session::applyDialogs(
|
||||
Data::Folder *requestFolder,
|
||||
const QVector<MTPMessage> &messages,
|
||||
const QVector<MTPDialog> &dialogs) {
|
||||
const QVector<MTPDialog> &dialogs,
|
||||
std::optional<int> count) {
|
||||
App::feedMsgs(messages, NewMessageLast);
|
||||
for (const auto &dialog : dialogs) {
|
||||
dialog.match([&](const auto &data) {
|
||||
applyDialog(requestFolder, data);
|
||||
});
|
||||
}
|
||||
if (requestFolder && count) {
|
||||
requestFolder->setCloudChatsListSize(*count);
|
||||
}
|
||||
}
|
||||
|
||||
void Session::applyDialog(
|
||||
|
@ -1663,7 +1667,7 @@ void Session::unreadStateChanged(
|
|||
|
||||
const auto nowState = key.entry()->chatListUnreadState();
|
||||
if (const auto folder = key.entry()->folder()) {
|
||||
folder->unreadStateChanged(wasState, nowState);
|
||||
folder->unreadStateChanged(key, wasState, nowState);
|
||||
} else {
|
||||
_chatsList.unreadStateChanged(wasState, nowState);
|
||||
}
|
||||
|
@ -1674,10 +1678,12 @@ void Session::unreadEntryChanged(const Dialogs::Key &key, bool added) {
|
|||
Expects(key.entry()->folderKnown());
|
||||
|
||||
const auto state = key.entry()->chatListUnreadState();
|
||||
if (const auto folder = key.entry()->folder()) {
|
||||
folder->unreadEntryChanged(state, added);
|
||||
} else {
|
||||
_chatsList.unreadEntryChanged(state, added);
|
||||
if (!state.empty()) {
|
||||
if (const auto folder = key.entry()->folder()) {
|
||||
folder->unreadEntryChanged(key, state, added);
|
||||
} else {
|
||||
_chatsList.unreadEntryChanged(state, added);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -296,7 +296,8 @@ public:
|
|||
void applyDialogs(
|
||||
Data::Folder *requestFolder,
|
||||
const QVector<MTPMessage> &messages,
|
||||
const QVector<MTPDialog> &dialogs);
|
||||
const QVector<MTPDialog> &dialogs,
|
||||
std::optional<int> count = std::nullopt);
|
||||
void addSavedPeersAfter(const QDateTime &date);
|
||||
void addAllSavedPeers();
|
||||
|
||||
|
|
|
@ -47,6 +47,10 @@ struct UnreadState {
|
|||
int chatsCountMuted = 0;
|
||||
bool mark = false;
|
||||
bool markMuted = false;
|
||||
|
||||
bool empty() const {
|
||||
return !messagesCount.value_or(0) && !chatsCount && !mark;
|
||||
}
|
||||
};
|
||||
|
||||
class Entry {
|
||||
|
|
|
@ -34,7 +34,7 @@ bool ShowUserBotIcon(not_null<UserData*> user) {
|
|||
return user->isBot() && !user->isSupport();
|
||||
}
|
||||
|
||||
void paintRowTopRight(Painter &p, const QString &text, QRect &rectForName, bool active, bool selected) {
|
||||
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);
|
||||
|
@ -42,7 +42,7 @@ void paintRowTopRight(Painter &p, const QString &text, QRect &rectForName, bool
|
|||
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) {
|
||||
void PaintRowDate(Painter &p, QDateTime date, QRect &rectForName, bool active, bool selected) {
|
||||
const auto now = QDateTime::currentDateTime();
|
||||
const auto &lastTime = date;
|
||||
const auto nowDate = now.date();
|
||||
|
@ -60,7 +60,7 @@ void paintRowDate(Painter &p, QDateTime date, QRect &rectForName, bool active, b
|
|||
return lastDate.toString(qsl("d.MM.yy"));
|
||||
}
|
||||
}();
|
||||
paintRowTopRight(p, dt, rectForName, active, selected);
|
||||
PaintRowTopRight(p, dt, rectForName, active, selected);
|
||||
}
|
||||
|
||||
void PaintNarrowCounter(
|
||||
|
@ -159,6 +159,38 @@ int PaintWideCounter(
|
|||
return availableWidth;
|
||||
}
|
||||
|
||||
void PaintListEntryText(
|
||||
Painter &p,
|
||||
QRect rect,
|
||||
bool active,
|
||||
bool selected,
|
||||
not_null<const Row*> row) {
|
||||
if (rect.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
row->validateListEntryCache();
|
||||
const auto &palette = active
|
||||
? st::dialogsTextPaletteActive
|
||||
: selected
|
||||
? st::dialogsTextPaletteOver
|
||||
: st::dialogsTextPalette;
|
||||
const auto &color = active
|
||||
? st::dialogsTextFgActive
|
||||
: selected
|
||||
? st::dialogsTextFgOver
|
||||
: st::dialogsTextFg;
|
||||
p.setTextPalette(palette);
|
||||
p.setFont(st::dialogsTextFont);
|
||||
p.setPen(color);
|
||||
row->listEntryCache().drawElided(
|
||||
p,
|
||||
rect.left(),
|
||||
rect.top(),
|
||||
rect.width(),
|
||||
rect.height() / st::dialogsTextFont->height);
|
||||
p.restoreTextPalette();
|
||||
}
|
||||
|
||||
enum class Flag {
|
||||
Active = 0x01,
|
||||
Selected = 0x02,
|
||||
|
@ -255,7 +287,7 @@ void paintRow(
|
|||
&& !(flags & (Flag::SearchResult/* | Flag::FeedSearchResult*/)); // #feed
|
||||
if (promoted) {
|
||||
const auto text = lang(lng_proxy_sponsor);
|
||||
paintRowTopRight(p, text, rectForName, active, selected);
|
||||
PaintRowTopRight(p, text, rectForName, active, selected);
|
||||
} else if (from/* && !(flags & Flag::FeedSearchResult)*/) { // #feed
|
||||
if (const auto chatTypeIcon = ChatTypeIcon(from, active, selected)) {
|
||||
chatTypeIcon->paint(p, rectForName.topLeft(), fullWidth);
|
||||
|
@ -274,7 +306,7 @@ void paintRow(
|
|||
|| (supportMode
|
||||
&& Auth().supportHelper().isOccupiedBySomeone(history))) {
|
||||
if (!promoted) {
|
||||
paintRowDate(p, date, rectForName, active, selected);
|
||||
PaintRowDate(p, date, rectForName, active, selected);
|
||||
}
|
||||
|
||||
auto availableWidth = namewidth;
|
||||
|
@ -318,7 +350,7 @@ void paintRow(
|
|||
}
|
||||
} else if (!item->isEmpty()) {
|
||||
if (!promoted) {
|
||||
paintRowDate(p, date, rectForName, active, selected);
|
||||
PaintRowDate(p, date, rectForName, active, selected);
|
||||
}
|
||||
|
||||
paintItemCallback(nameleft, namewidth);
|
||||
|
@ -560,7 +592,7 @@ void RowPainter::paint(
|
|||
}
|
||||
return nullptr;
|
||||
}();
|
||||
const auto displayDate = [item, cloudDraft] {
|
||||
const auto displayDate = [&] {
|
||||
if (item) {
|
||||
if (cloudDraft) {
|
||||
return (item->date() > cloudDraft->date)
|
||||
|
@ -623,20 +655,22 @@ void RowPainter::paint(
|
|||
: (selected
|
||||
? st::dialogsTextFgServiceOver
|
||||
: st::dialogsTextFgService);
|
||||
const auto actionWasPainted = history ? history->paintSendAction(
|
||||
p,
|
||||
const auto itemRect = QRect(
|
||||
nameleft,
|
||||
texttop,
|
||||
availableWidth,
|
||||
st::dialogsTextFont->height);
|
||||
const auto actionWasPainted = history ? history->paintSendAction(
|
||||
p,
|
||||
itemRect.x(),
|
||||
itemRect.y(),
|
||||
itemRect.width(),
|
||||
fullWidth,
|
||||
color,
|
||||
ms) : false;
|
||||
if (!actionWasPainted) {
|
||||
const auto itemRect = QRect(
|
||||
nameleft,
|
||||
texttop,
|
||||
availableWidth,
|
||||
st::dialogsTextFont->height);
|
||||
if (const auto folder = row->folder()) {
|
||||
PaintListEntryText(p, itemRect, active, selected, row);
|
||||
} else if (!actionWasPainted) {
|
||||
item->drawInDialog(
|
||||
p,
|
||||
itemRect,
|
||||
|
|
|
@ -7,12 +7,49 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "dialogs/dialogs_row.h"
|
||||
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/text_options.h"
|
||||
#include "dialogs/dialogs_entry.h"
|
||||
#include "data/data_folder.h"
|
||||
#include "history/history.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "mainwidget.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
|
||||
namespace Dialogs {
|
||||
namespace {
|
||||
|
||||
QString ComposeFolderListEntryText(not_null<Data::Folder*> folder) {
|
||||
const auto &list = folder->lastUnreadHistories();
|
||||
if (list.empty()) {
|
||||
const auto count = folder->chatsListSize();
|
||||
if (!count) {
|
||||
return QString();
|
||||
}
|
||||
return lng_archived_chats(lt_count, count);
|
||||
}
|
||||
const auto count = std::max(
|
||||
int(list.size()),
|
||||
folder->unreadHistoriesCount());
|
||||
if (list.size() == 1) {
|
||||
return App::peerName(list[0]->peer);
|
||||
} else if (count == 2) {
|
||||
return lng_archived_unread_two(
|
||||
lt_chat,
|
||||
App::peerName(list[0]->peer),
|
||||
lt_second_chat,
|
||||
App::peerName(list[1]->peer));
|
||||
}
|
||||
return lng_archived_unread(
|
||||
lt_count,
|
||||
count - 2,
|
||||
lt_chat,
|
||||
App::peerName(list[0]->peer),
|
||||
lt_second_chat,
|
||||
App::peerName(list[1]->peer));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
RippleRow::RippleRow() = default;
|
||||
RippleRow::~RippleRow() = default;
|
||||
|
@ -44,6 +81,22 @@ uint64 Row::sortKey() const {
|
|||
return _id.entry()->sortKeyInChatList();
|
||||
}
|
||||
|
||||
void Row::validateListEntryCache() const {
|
||||
const auto folder = _id.folder();
|
||||
if (!folder) {
|
||||
return;
|
||||
}
|
||||
const auto version = folder->chatListViewVersion();
|
||||
if (_listEntryCacheVersion == version) {
|
||||
return;
|
||||
}
|
||||
_listEntryCacheVersion = version;
|
||||
_listEntryCache.setText(
|
||||
st::dialogsTextStyle,
|
||||
ComposeFolderListEntryText(folder),
|
||||
Ui::DialogTextOptions());
|
||||
}
|
||||
|
||||
FakeRow::FakeRow(Key searchInChat, not_null<HistoryItem*> item)
|
||||
: _searchInChat(searchInChat)
|
||||
, _item(item)
|
||||
|
|
|
@ -62,6 +62,11 @@ public:
|
|||
}
|
||||
uint64 sortKey() const;
|
||||
|
||||
void validateListEntryCache() const;
|
||||
const Text &listEntryCache() const {
|
||||
return _listEntryCache;
|
||||
}
|
||||
|
||||
// for any attached data, for example View in contacts list
|
||||
void *attached = nullptr;
|
||||
|
||||
|
@ -70,6 +75,8 @@ private:
|
|||
|
||||
Key _id;
|
||||
int _pos = 0;
|
||||
mutable uint32 _listEntryCacheVersion = 0;
|
||||
mutable Text _listEntryCache;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -742,17 +742,18 @@ void HistoryItem::drawInDialog(
|
|||
DrawInDialog way,
|
||||
const HistoryItem *&cacheFor,
|
||||
Text &cache) const {
|
||||
if (r.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (cacheFor != this) {
|
||||
cacheFor = this;
|
||||
cache.setText(st::dialogsTextStyle, inDialogsText(way), Ui::DialogTextOptions());
|
||||
}
|
||||
if (r.width()) {
|
||||
p.setTextPalette(active ? st::dialogsTextPaletteActive : (selected ? st::dialogsTextPaletteOver : st::dialogsTextPalette));
|
||||
p.setFont(st::dialogsTextFont);
|
||||
p.setPen(active ? st::dialogsTextFgActive : (selected ? st::dialogsTextFgOver : st::dialogsTextFg));
|
||||
cache.drawElided(p, r.left(), r.top(), r.width(), r.height() / st::dialogsTextFont->height);
|
||||
p.restoreTextPalette();
|
||||
}
|
||||
p.setTextPalette(active ? st::dialogsTextPaletteActive : (selected ? st::dialogsTextPaletteOver : st::dialogsTextPalette));
|
||||
p.setFont(st::dialogsTextFont);
|
||||
p.setPen(active ? st::dialogsTextFgActive : (selected ? st::dialogsTextFgOver : st::dialogsTextFg));
|
||||
cache.drawElided(p, r.left(), r.top(), r.width(), r.height() / st::dialogsTextFont->height);
|
||||
p.restoreTextPalette();
|
||||
}
|
||||
|
||||
HistoryItem::~HistoryItem() {
|
||||
|
|
|
@ -796,8 +796,8 @@ void PeerMenuAddMuteAction(
|
|||
void ToggleHistoryArchived(not_null<History*> history, bool archived) {
|
||||
const auto callback = [=] {
|
||||
Ui::Toast::Show(lang(archived
|
||||
? lng_chat_archived
|
||||
: lng_chat_unarchived));
|
||||
? lng_archived_added
|
||||
: lng_archived_removed));
|
||||
};
|
||||
history->session().api().toggleHistoryArchived(
|
||||
history,
|
||||
|
|
Loading…
Add table
Reference in a new issue