2018-01-05 15:57:18 +00:00
|
|
|
/*
|
|
|
|
This file is part of Telegram Desktop,
|
|
|
|
the official desktop application for the Telegram messaging service.
|
|
|
|
|
|
|
|
For license and copyright information please follow this link:
|
|
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
|
|
*/
|
|
|
|
#include "dialogs/dialogs_entry.h"
|
|
|
|
|
|
|
|
#include "dialogs/dialogs_key.h"
|
|
|
|
#include "dialogs/dialogs_indexed_list.h"
|
|
|
|
#include "mainwidget.h"
|
|
|
|
#include "styles/style_dialogs.h"
|
2018-01-11 19:33:26 +00:00
|
|
|
#include "history/history_item.h"
|
2018-01-13 12:45:11 +00:00
|
|
|
#include "history/history.h"
|
2018-01-05 15:57:18 +00:00
|
|
|
|
|
|
|
namespace Dialogs {
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
auto DialogsPosToTopShift = 0;
|
|
|
|
|
|
|
|
uint64 DialogPosFromDate(const QDateTime &date) {
|
|
|
|
if (date.isNull()) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return (uint64(date.toTime_t()) << 32) | (++DialogsPosToTopShift);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64 PinnedDialogPos(int pinnedIndex) {
|
|
|
|
return 0xFFFFFFFF00000000ULL + pinnedIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
bool MessageIsLess(not_null<HistoryItem*> a, not_null<HistoryItem*> b) {
|
|
|
|
if (a->date < b->date) {
|
|
|
|
return true;
|
|
|
|
} else if (b->date < a->date) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
const auto apeer = a->history()->peer->bareId();
|
|
|
|
const auto bpeer = b->history()->peer->bareId();
|
|
|
|
if (apeer < bpeer) {
|
|
|
|
return true;
|
|
|
|
} else if (bpeer < apeer) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return a->id < b->id;
|
|
|
|
}
|
|
|
|
|
|
|
|
Entry::Entry(const Key &key)
|
|
|
|
: lastItemTextCache(st::dialogsTextWidthMin)
|
|
|
|
, _key(key) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void Entry::cachePinnedIndex(int index) {
|
|
|
|
if (_pinnedIndex != index) {
|
|
|
|
const auto wasPinned = isPinnedDialog();
|
|
|
|
_pinnedIndex = index;
|
|
|
|
updateChatListSortPosition();
|
|
|
|
updateChatListEntry();
|
|
|
|
if (wasPinned != isPinnedDialog()) {
|
|
|
|
changedChatListPinHook();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-23 16:51:12 +00:00
|
|
|
bool Entry::needUpdateInChatList() const {
|
|
|
|
return inChatList(Dialogs::Mode::All) || shouldBeInChatList();
|
|
|
|
}
|
|
|
|
|
2018-01-05 15:57:18 +00:00
|
|
|
void Entry::updateChatListSortPosition() {
|
|
|
|
_sortKeyInChatList = isPinnedDialog()
|
|
|
|
? PinnedDialogPos(_pinnedIndex)
|
|
|
|
: DialogPosFromDate(adjustChatListDate());
|
2018-01-23 16:51:12 +00:00
|
|
|
if (needUpdateInChatList()) {
|
|
|
|
setChatListExistence(true);
|
2018-01-05 15:57:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-23 16:51:12 +00:00
|
|
|
void Entry::updateChatListExistence() {
|
|
|
|
setChatListExistence(shouldBeInChatList());
|
|
|
|
}
|
|
|
|
|
|
|
|
void Entry::setChatListExistence(bool exists) {
|
2018-01-05 15:57:18 +00:00
|
|
|
if (const auto main = App::main()) {
|
2018-01-23 16:51:12 +00:00
|
|
|
if (exists && _sortKeyInChatList) {
|
|
|
|
main->createDialog(_key);
|
|
|
|
updateChatListEntry();
|
|
|
|
} else {
|
|
|
|
main->removeDialog(_key);
|
|
|
|
}
|
2018-01-05 15:57:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-23 16:51:12 +00:00
|
|
|
QDateTime Entry::adjustChatListDate() const {
|
|
|
|
return chatsListDate();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Entry::changedInChatListHook(Dialogs::Mode list, bool added) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void Entry::changedChatListPinHook() {
|
|
|
|
}
|
|
|
|
|
|
|
|
RowsByLetter &Entry::chatListLinks(Mode list) {
|
|
|
|
return _chatListLinks[static_cast<int>(list)];
|
|
|
|
}
|
|
|
|
|
|
|
|
const RowsByLetter &Entry::chatListLinks(Mode list) const {
|
|
|
|
return _chatListLinks[static_cast<int>(list)];
|
|
|
|
}
|
|
|
|
|
|
|
|
Row *Entry::mainChatListLink(Mode list) const {
|
|
|
|
auto it = chatListLinks(list).find(0);
|
|
|
|
Assert(it != chatListLinks(list).cend());
|
|
|
|
return it->second;
|
|
|
|
}
|
|
|
|
|
2018-01-05 15:57:18 +00:00
|
|
|
PositionChange Entry::adjustByPosInChatList(
|
|
|
|
Mode list,
|
|
|
|
not_null<IndexedList*> indexed) {
|
|
|
|
const auto lnk = mainChatListLink(list);
|
|
|
|
const auto movedFrom = lnk->pos();
|
|
|
|
indexed->adjustByPos(chatListLinks(list));
|
|
|
|
const auto movedTo = lnk->pos();
|
|
|
|
return { movedFrom, movedTo };
|
|
|
|
}
|
|
|
|
|
|
|
|
void Entry::setChatsListDate(const QDateTime &date) {
|
|
|
|
if (!_lastMessageDate.isNull() && _lastMessageDate >= date) {
|
2018-01-23 16:51:12 +00:00
|
|
|
if (!inChatList(Dialogs::Mode::All)) {
|
2018-01-05 15:57:18 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_lastMessageDate = date;
|
|
|
|
updateChatListSortPosition();
|
|
|
|
}
|
|
|
|
|
|
|
|
int Entry::posInChatList(Dialogs::Mode list) const {
|
|
|
|
return mainChatListLink(list)->pos();
|
|
|
|
}
|
|
|
|
|
|
|
|
not_null<Row*> Entry::addToChatList(
|
|
|
|
Mode list,
|
|
|
|
not_null<IndexedList*> indexed) {
|
|
|
|
if (!inChatList(list)) {
|
|
|
|
chatListLinks(list) = indexed->addToEnd(_key);
|
|
|
|
changedInChatListHook(list, true);
|
|
|
|
}
|
|
|
|
return mainChatListLink(list);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Entry::removeFromChatList(
|
|
|
|
Dialogs::Mode list,
|
|
|
|
not_null<Dialogs::IndexedList*> indexed) {
|
|
|
|
if (inChatList(list)) {
|
|
|
|
indexed->del(_key);
|
|
|
|
chatListLinks(list).clear();
|
|
|
|
changedInChatListHook(list, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Entry::removeChatListEntryByLetter(Mode list, QChar letter) {
|
|
|
|
Expects(letter != 0);
|
|
|
|
|
|
|
|
if (inChatList(list)) {
|
|
|
|
chatListLinks(list).remove(letter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Entry::addChatListEntryByLetter(
|
|
|
|
Mode list,
|
|
|
|
QChar letter,
|
|
|
|
not_null<Row*> row) {
|
|
|
|
Expects(letter != 0);
|
|
|
|
|
|
|
|
if (inChatList(list)) {
|
|
|
|
chatListLinks(list).emplace(letter, row);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Entry::updateChatListEntry() const {
|
|
|
|
if (const auto main = App::main()) {
|
|
|
|
if (inChatList(Mode::All)) {
|
2018-01-22 17:39:20 +00:00
|
|
|
main->repaintDialogRow(
|
2018-01-05 15:57:18 +00:00
|
|
|
Mode::All,
|
|
|
|
mainChatListLink(Mode::All));
|
|
|
|
if (inChatList(Mode::Important)) {
|
2018-01-22 17:39:20 +00:00
|
|
|
main->repaintDialogRow(
|
2018-01-05 15:57:18 +00:00
|
|
|
Mode::Important,
|
|
|
|
mainChatListLink(Mode::Important));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Dialogs
|