mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-25 04:38:23 +00:00
Prepare dialogs to hold a history or a feed.
This commit is contained in:
parent
6a9556d42c
commit
a2891807f8
@ -441,7 +441,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
||||
h->clear(true);
|
||||
}
|
||||
if (hto->inChatList(Dialogs::Mode::All) && h->inChatList(Dialogs::Mode::All)) {
|
||||
App::removeDialog(h);
|
||||
App::main()->removeDialog(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -482,7 +482,7 @@ namespace {
|
||||
h->clear(true);
|
||||
}
|
||||
if (hto->inChatList(Dialogs::Mode::All) && h->inChatList(Dialogs::Mode::All)) {
|
||||
App::removeDialog(h);
|
||||
App::main()->removeDialog(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1047,7 +1047,9 @@ namespace {
|
||||
if (auto history = App::historyLoaded(peer)) {
|
||||
history->outboxRead(upTo);
|
||||
if (history->lastMsg && history->lastMsg->out() && history->lastMsg->id <= upTo) {
|
||||
if (App::main()) App::main()->dlgUpdated(history->peer, history->lastMsg->id);
|
||||
if (App::main()) {
|
||||
App::main()->dlgUpdated(history, history->lastMsg->id);
|
||||
}
|
||||
}
|
||||
history->updateChatListEntry();
|
||||
|
||||
@ -1801,7 +1803,7 @@ namespace {
|
||||
return ::histories.findOrInsert(peer);
|
||||
}
|
||||
|
||||
History *historyFromDialog(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead, int32 maxOutboxRead) {
|
||||
not_null<History*> historyFromDialog(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead, int32 maxOutboxRead) {
|
||||
return ::histories.findOrInsert(peer, unreadCnt, maxInboxRead, maxOutboxRead);
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ namespace App {
|
||||
|
||||
Histories &histories();
|
||||
not_null<History*> history(const PeerId &peer);
|
||||
History *historyFromDialog(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead, int32 maxOutboxRead);
|
||||
not_null<History*> historyFromDialog(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead, int32 maxOutboxRead);
|
||||
History *historyLoaded(const PeerId &peer);
|
||||
HistoryItem *histItemById(ChannelId channelId, MsgId itemId);
|
||||
inline not_null<History*> history(const PeerData *peer) {
|
||||
|
@ -238,6 +238,7 @@ void ChatsListBoxController::rebuildRows() {
|
||||
auto appendList = [this](auto chats) {
|
||||
auto count = 0;
|
||||
for_const (auto row, chats->all()) {
|
||||
// #TODO feeds list
|
||||
if (appendRow(row->history())) {
|
||||
++count;
|
||||
}
|
||||
@ -322,6 +323,7 @@ void ContactsBoxController::rebuildRows() {
|
||||
auto appendList = [this](auto chats) {
|
||||
auto count = 0;
|
||||
for_const (auto row, chats->all()) {
|
||||
// #TODO feeds list
|
||||
auto history = row->history();
|
||||
if (auto user = history->peer->asUser()) {
|
||||
if (appendRow(user)) {
|
||||
|
@ -280,7 +280,7 @@ ShareBox::Inner::Inner(QWidget *parent, ShareBox::FilterCallback &&filterCallbac
|
||||
}
|
||||
}
|
||||
for (const auto row : dialogs->all()) {
|
||||
// #TODO dialogs
|
||||
// #TODO feeds list
|
||||
if (const auto history = row->history()) {
|
||||
if (!history->peer->isSelf() && _filterCallback(history->peer)) {
|
||||
_chatsIndexed->addToEnd(history);
|
||||
@ -349,7 +349,9 @@ void ShareBox::Inner::activateSkipPage(int pageHeight, int direction) {
|
||||
|
||||
void ShareBox::Inner::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
||||
if (update.flags & Notify::PeerUpdate::Flag::NameChanged) {
|
||||
_chatsIndexed->peerNameChanged(update.peer, update.oldNameFirstChars);
|
||||
_chatsIndexed->peerNameChanged(
|
||||
update.peer,
|
||||
update.oldNameFirstChars);
|
||||
}
|
||||
|
||||
updateChat(update.peer);
|
||||
@ -405,6 +407,7 @@ int ShareBox::Inner::chatIndex(not_null<PeerData*> peer) const {
|
||||
int index = 0;
|
||||
if (_filter.isEmpty()) {
|
||||
for_const (auto row, _chatsIndexed->all()) {
|
||||
// #TODO feeds list
|
||||
if (row->history()->peer == peer) {
|
||||
return index;
|
||||
}
|
||||
@ -412,6 +415,7 @@ int ShareBox::Inner::chatIndex(not_null<PeerData*> peer) const {
|
||||
}
|
||||
} else {
|
||||
for_const (auto row, _filtered) {
|
||||
// #TODO feeds list
|
||||
if (row->history()->peer == peer) {
|
||||
return index;
|
||||
}
|
||||
@ -450,6 +454,7 @@ void ShareBox::Inner::loadProfilePhotos(int yFrom) {
|
||||
if (((*i)->pos() * _rowHeight) >= yTo) {
|
||||
break;
|
||||
}
|
||||
// #TODO feeds list
|
||||
(*i)->history()->peer->loadUserpic();
|
||||
}
|
||||
}
|
||||
@ -461,6 +466,7 @@ void ShareBox::Inner::loadProfilePhotos(int yFrom) {
|
||||
if (to > _filtered.size()) to = _filtered.size();
|
||||
|
||||
for (; from < to; ++from) {
|
||||
// #TODO feeds list
|
||||
_filtered[from]->history()->peer->loadUserpic();
|
||||
}
|
||||
}
|
||||
@ -470,6 +476,7 @@ void ShareBox::Inner::loadProfilePhotos(int yFrom) {
|
||||
ShareBox::Inner::Chat *ShareBox::Inner::getChat(Dialogs::Row *row) {
|
||||
auto data = static_cast<Chat*>(row->attached);
|
||||
if (!data) {
|
||||
// #TODO feeds list
|
||||
auto peer = row->history()->peer;
|
||||
auto i = _dataMap.constFind(peer);
|
||||
if (i == _dataMap.cend()) {
|
||||
@ -640,17 +647,17 @@ void ShareBox::Inner::changeCheckState(Chat *chat) {
|
||||
if (!chat) return;
|
||||
|
||||
if (!_filter.isEmpty()) {
|
||||
auto row = _chatsIndexed->getRow(chat->peer->id);
|
||||
const auto history = App::history(chat->peer);
|
||||
auto row = _chatsIndexed->getRow(history);
|
||||
if (!row) {
|
||||
const auto rowsByLetter = _chatsIndexed->addToEnd(
|
||||
App::history(chat->peer));
|
||||
const auto rowsByLetter = _chatsIndexed->addToEnd(history);
|
||||
const auto it = rowsByLetter.find(0);
|
||||
Assert(it != rowsByLetter.cend());
|
||||
row = it->second;
|
||||
}
|
||||
chat = getChat(row);
|
||||
if (!chat->checkbox.checked()) {
|
||||
_chatsIndexed->moveToTop(chat->peer);
|
||||
_chatsIndexed->moveToTop(history);
|
||||
}
|
||||
}
|
||||
|
||||
@ -725,6 +732,7 @@ void ShareBox::Inner::updateFilter(QString filter) {
|
||||
if (toFilter) {
|
||||
_filtered.reserve(toFilter->size());
|
||||
for_const (auto row, *toFilter) {
|
||||
// #TODO feeds list
|
||||
auto &nameWords = row->history()->peer->nameWords();
|
||||
auto nb = nameWords.cbegin(), ne = nameWords.cend(), ni = nb;
|
||||
for (fi = fb; fi != fe; ++fi) {
|
||||
@ -768,15 +776,16 @@ void ShareBox::Inner::peopleReceived(const QString &query, const QVector<MTPPeer
|
||||
if (_byUsernameFiltered[j]->id == peerId) break;
|
||||
}
|
||||
if (j == already) {
|
||||
auto *peer = App::peer(peerId);
|
||||
if (!peer || !_filterCallback(peer)) continue;
|
||||
|
||||
auto chat = new Chat(peer, [this, peer] { repaintChat(peer); });
|
||||
updateChatName(chat, peer);
|
||||
if (auto row = _chatsIndexed->getRow(peer->id)) {
|
||||
const auto peer = App::peer(peerId);
|
||||
const auto history = App::historyLoaded(peer);
|
||||
if (!peer || !_filterCallback(peer)) {
|
||||
continue;
|
||||
} else if (history && _chatsIndexed->getRow(history)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto chat = new Chat(peer, [this, peer] { repaintChat(peer); });
|
||||
updateChatName(chat, peer);
|
||||
_byUsernameFiltered.push_back(peer);
|
||||
d_byUsernameFiltered.push_back(chat);
|
||||
}
|
||||
|
@ -15,37 +15,37 @@ IndexedList::IndexedList(SortMode sortMode)
|
||||
, _empty(sortMode) {
|
||||
}
|
||||
|
||||
RowsByLetter IndexedList::addToEnd(not_null<History*> history) {
|
||||
RowsByLetter IndexedList::addToEnd(Key key) {
|
||||
RowsByLetter result;
|
||||
if (!_list.contains(history->peer->id)) {
|
||||
result.emplace(0, _list.addToEnd(history));
|
||||
for (auto ch : history->peer->nameFirstChars()) {
|
||||
if (!_list.contains(key)) {
|
||||
result.emplace(0, _list.addToEnd(key));
|
||||
for (auto ch : key.nameFirstChars()) {
|
||||
auto j = _index.find(ch);
|
||||
if (j == _index.cend()) {
|
||||
j = _index.emplace(
|
||||
ch,
|
||||
std::make_unique<List>(_sortMode)).first;
|
||||
}
|
||||
result.emplace(ch, j->second->addToEnd(history));
|
||||
result.emplace(ch, j->second->addToEnd(key));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Row *IndexedList::addByName(not_null<History*> history) {
|
||||
if (const auto row = _list.getRow(history->peer->id)) {
|
||||
Row *IndexedList::addByName(Key key) {
|
||||
if (const auto row = _list.getRow(key)) {
|
||||
return row;
|
||||
}
|
||||
|
||||
Row *result = _list.addByName(history);
|
||||
for (auto ch : history->peer->nameFirstChars()) {
|
||||
Row *result = _list.addByName(key);
|
||||
for (auto ch : key.nameFirstChars()) {
|
||||
auto j = _index.find(ch);
|
||||
if (j == _index.cend()) {
|
||||
j = _index.emplace(
|
||||
ch,
|
||||
std::make_unique<List>(_sortMode)).first;
|
||||
}
|
||||
j->second->addByName(history);
|
||||
j->second->addByName(key);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -62,11 +62,11 @@ void IndexedList::adjustByPos(const RowsByLetter &links) {
|
||||
}
|
||||
}
|
||||
|
||||
void IndexedList::moveToTop(not_null<PeerData*> peer) {
|
||||
if (_list.moveToTop(peer->id)) {
|
||||
for (auto ch : peer->nameFirstChars()) {
|
||||
void IndexedList::moveToTop(Key key) {
|
||||
if (_list.moveToTop(key)) {
|
||||
for (auto ch : key.nameFirstChars()) {
|
||||
if (auto it = _index.find(ch); it != _index.cend()) {
|
||||
it->second->moveToTop(peer->id);
|
||||
it->second->moveToTop(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -81,6 +81,7 @@ void IndexedList::movePinned(Row *row, int deltaSign) {
|
||||
Assert(swapPinnedIndexWith != cbegin());
|
||||
--swapPinnedIndexWith;
|
||||
}
|
||||
// #TODO feeds pinned
|
||||
auto history1 = row->history();
|
||||
auto history2 = (*swapPinnedIndexWith)->history();
|
||||
Assert(history1->isPinnedDialog());
|
||||
@ -91,44 +92,52 @@ void IndexedList::movePinned(Row *row, int deltaSign) {
|
||||
history2->setPinnedIndex(index1);
|
||||
}
|
||||
|
||||
void IndexedList::peerNameChanged(not_null<PeerData*> peer, const PeerData::NameFirstChars &oldChars) {
|
||||
Assert(_sortMode != SortMode::Date);
|
||||
if (_sortMode == SortMode::Name) {
|
||||
adjustByName(peer, oldChars);
|
||||
} else {
|
||||
adjustNames(Dialogs::Mode::All, peer, oldChars);
|
||||
void IndexedList::peerNameChanged(
|
||||
not_null<PeerData*> peer,
|
||||
const PeerData::NameFirstChars &oldChars) {
|
||||
Expects(_sortMode != SortMode::Date);
|
||||
|
||||
if (const auto history = App::historyLoaded(peer)) {
|
||||
if (_sortMode == SortMode::Name) {
|
||||
adjustByName(history, oldChars);
|
||||
} else {
|
||||
adjustNames(Dialogs::Mode::All, history, oldChars);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IndexedList::peerNameChanged(Mode list, not_null<PeerData*> peer, const PeerData::NameFirstChars &oldChars) {
|
||||
Assert(_sortMode == SortMode::Date);
|
||||
adjustNames(list, peer, oldChars);
|
||||
void IndexedList::peerNameChanged(
|
||||
Mode list,
|
||||
not_null<PeerData*> peer,
|
||||
const PeerData::NameFirstChars &oldChars) {
|
||||
Expects(_sortMode == SortMode::Date);
|
||||
|
||||
if (const auto history = App::historyLoaded(peer)) {
|
||||
adjustNames(list, history, oldChars);
|
||||
}
|
||||
}
|
||||
|
||||
void IndexedList::adjustByName(
|
||||
not_null<PeerData*> peer,
|
||||
Key key,
|
||||
const PeerData::NameFirstChars &oldChars) {
|
||||
const auto mainRow = _list.adjustByName(peer);
|
||||
const auto mainRow = _list.adjustByName(key);
|
||||
if (!mainRow) return;
|
||||
|
||||
// #TODO dialogs
|
||||
const auto history = mainRow->history();
|
||||
|
||||
PeerData::NameFirstChars toRemove = oldChars, toAdd;
|
||||
for (auto ch : peer->nameFirstChars()) {
|
||||
for (auto ch : key.nameFirstChars()) {
|
||||
auto j = toRemove.find(ch);
|
||||
if (j == toRemove.cend()) {
|
||||
toAdd.insert(ch);
|
||||
} else {
|
||||
toRemove.erase(j);
|
||||
if (auto it = _index.find(ch); it != _index.cend()) {
|
||||
it->second->adjustByName(peer);
|
||||
it->second->adjustByName(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto ch : toRemove) {
|
||||
if (auto it = _index.find(ch); it != _index.cend()) {
|
||||
it->second->del(peer->id, mainRow);
|
||||
it->second->del(key, mainRow);
|
||||
}
|
||||
}
|
||||
if (!toAdd.empty()) {
|
||||
@ -139,20 +148,23 @@ void IndexedList::adjustByName(
|
||||
ch,
|
||||
std::make_unique<List>(_sortMode)).first;
|
||||
}
|
||||
j->second->addByName(history);
|
||||
j->second->addByName(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IndexedList::adjustNames(Mode list, not_null<PeerData*> peer, const PeerData::NameFirstChars &oldChars) {
|
||||
auto mainRow = _list.getRow(peer->id);
|
||||
void IndexedList::adjustNames(
|
||||
Mode list,
|
||||
Key key,
|
||||
const PeerData::NameFirstChars &oldChars) {
|
||||
auto mainRow = _list.getRow(key);
|
||||
if (!mainRow) return;
|
||||
|
||||
// #TODO dialogs
|
||||
// #TODO feeds dialogs
|
||||
auto history = mainRow->history();
|
||||
|
||||
PeerData::NameFirstChars toRemove = oldChars, toAdd;
|
||||
for (auto ch : peer->nameFirstChars()) {
|
||||
for (auto ch : key.nameFirstChars()) {
|
||||
auto j = toRemove.find(ch);
|
||||
if (j == toRemove.cend()) {
|
||||
toAdd.insert(ch);
|
||||
@ -165,7 +177,7 @@ void IndexedList::adjustNames(Mode list, not_null<PeerData*> peer, const PeerDat
|
||||
history->removeChatListEntryByLetter(list, ch);
|
||||
}
|
||||
if (auto it = _index.find(ch); it != _index.cend()) {
|
||||
it->second->del(peer->id, mainRow);
|
||||
it->second->del(key, mainRow);
|
||||
}
|
||||
}
|
||||
for (auto ch : toAdd) {
|
||||
@ -175,18 +187,18 @@ void IndexedList::adjustNames(Mode list, not_null<PeerData*> peer, const PeerDat
|
||||
ch,
|
||||
std::make_unique<List>(_sortMode)).first;
|
||||
}
|
||||
auto row = j->second->addToEnd(history);
|
||||
auto row = j->second->addToEnd(key);
|
||||
if (_sortMode == SortMode::Date) {
|
||||
history->addChatListEntryByLetter(list, ch, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IndexedList::del(not_null<const PeerData*> peer, Row *replacedBy) {
|
||||
if (_list.del(peer->id, replacedBy)) {
|
||||
for (auto ch : peer->nameFirstChars()) {
|
||||
void IndexedList::del(Key key, Row *replacedBy) {
|
||||
if (_list.del(key, replacedBy)) {
|
||||
for (auto ch : key.nameFirstChars()) {
|
||||
if (auto it = _index.find(ch); it != _index.cend()) {
|
||||
it->second->del(peer->id, replacedBy);
|
||||
it->second->del(key, replacedBy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,21 +18,26 @@ class IndexedList {
|
||||
public:
|
||||
IndexedList(SortMode sortMode);
|
||||
|
||||
RowsByLetter addToEnd(not_null<History*> history);
|
||||
Row *addByName(not_null<History*> history);
|
||||
RowsByLetter addToEnd(Key key);
|
||||
Row *addByName(Key key);
|
||||
void adjustByPos(const RowsByLetter &links);
|
||||
void moveToTop(not_null<PeerData*> peer);
|
||||
void moveToTop(Key key);
|
||||
|
||||
// row must belong to this indexed list all().
|
||||
void movePinned(Row *row, int deltaSign);
|
||||
|
||||
// For sortMode != SortMode::Date
|
||||
void peerNameChanged(not_null<PeerData*> peer, const PeerData::NameFirstChars &oldChars);
|
||||
void peerNameChanged(
|
||||
not_null<PeerData*> peer,
|
||||
const PeerData::NameFirstChars &oldChars);
|
||||
|
||||
//For sortMode == SortMode::Date
|
||||
void peerNameChanged(Mode list, not_null<PeerData*> peer, const PeerData::NameFirstChars &oldChars);
|
||||
void peerNameChanged(
|
||||
Mode list,
|
||||
not_null<PeerData*> peer,
|
||||
const PeerData::NameFirstChars &oldChars);
|
||||
|
||||
void del(not_null<const PeerData*> peer, Row *replacedBy = nullptr);
|
||||
void del(Key key, Row *replacedBy = nullptr);
|
||||
void clear();
|
||||
|
||||
const List &all() const {
|
||||
@ -50,8 +55,8 @@ public:
|
||||
// Part of List interface is duplicated here for all() list.
|
||||
int size() const { return all().size(); }
|
||||
bool isEmpty() const { return all().isEmpty(); }
|
||||
bool contains(PeerId peerId) const { return all().contains(peerId); }
|
||||
Row *getRow(PeerId peerId) const { return all().getRow(peerId); }
|
||||
bool contains(Key key) const { return all().contains(key); }
|
||||
Row *getRow(Key key) const { return all().getRow(key); }
|
||||
Row *rowAtY(int32 y, int32 h) const { return all().rowAtY(y, h); }
|
||||
|
||||
using iterator = List::iterator;
|
||||
@ -70,8 +75,13 @@ public:
|
||||
iterator find(int y, int h) { return all().find(y, h); }
|
||||
|
||||
private:
|
||||
void adjustByName(not_null<PeerData*> peer, const PeerData::NameFirstChars &oldChars);
|
||||
void adjustNames(Mode list, not_null<PeerData*> peer, const PeerData::NameFirstChars &oldChars);
|
||||
void adjustByName(
|
||||
Key key,
|
||||
const PeerData::NameFirstChars &oldChars);
|
||||
void adjustNames(
|
||||
Mode list,
|
||||
Key key,
|
||||
const PeerData::NameFirstChars &oldChars);
|
||||
|
||||
SortMode _sortMode;
|
||||
List _list, _empty;
|
||||
|
@ -53,9 +53,9 @@ struct DialogsInner::HashtagResult {
|
||||
};
|
||||
|
||||
struct DialogsInner::PeerSearchResult {
|
||||
PeerSearchResult(PeerData *peer) : peer(peer) {
|
||||
PeerSearchResult(not_null<PeerData*> peer) : peer(peer) {
|
||||
}
|
||||
PeerData *peer;
|
||||
not_null<PeerData*> peer;
|
||||
Dialogs::RippleRow row;
|
||||
};
|
||||
|
||||
@ -99,7 +99,7 @@ DialogsInner::DialogsInner(QWidget *parent, not_null<Window::Controller*> contro
|
||||
}, lifetime());
|
||||
subscribe(App::histories().sendActionAnimationUpdated(), [this](const Histories::SendActionAnimationUpdate &update) {
|
||||
auto updateRect = Dialogs::Layout::RowPainter::sendActionAnimationRect(update.width, update.height, getFullWidth(), update.textUpdated);
|
||||
updateDialogRow(update.history->peer, MsgId(0), updateRect, UpdateRowSection::Default | UpdateRowSection::Filtered);
|
||||
updateDialogRow(update.history, MsgId(0), updateRect, UpdateRowSection::Default | UpdateRowSection::Filtered);
|
||||
});
|
||||
|
||||
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &data) {
|
||||
@ -187,7 +187,16 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
||||
}
|
||||
auto otherStart = rows->size() * st::dialogsRowHeight;
|
||||
auto active = App::main()->activePeer();
|
||||
auto selected = _menuPeer ? _menuPeer : (isPressed() ? (_pressed ? _pressed->history()->peer : nullptr) : (_selected ? _selected->history()->peer : nullptr));
|
||||
// #TODO feeds dialogs
|
||||
auto selected = _menuPeer
|
||||
? _menuPeer
|
||||
: (isPressed()
|
||||
? (_pressed
|
||||
? _pressed->history()->peer
|
||||
: nullptr)
|
||||
: (_selected
|
||||
? _selected->history()->peer
|
||||
: nullptr));
|
||||
if (otherStart) {
|
||||
auto reorderingPinned = (_aboveIndex >= 0 && !_pinnedRows.empty());
|
||||
auto &list = rows->all();
|
||||
@ -297,8 +306,11 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
||||
auto activeMsgId = App::main()->activeMsgId();
|
||||
for (; from < to; ++from) {
|
||||
auto row = _filterResults[from];
|
||||
// #TODO feeds dialogs
|
||||
auto peer = row->history()->peer;
|
||||
auto active = ((peer == activePeer) || (peer->migrateTo() && peer->migrateTo() == activePeer)) && !activeMsgId;
|
||||
auto active = !activeMsgId && ((peer == activePeer)
|
||||
|| (peer->migrateTo()
|
||||
&& peer->migrateTo() == activePeer));
|
||||
auto selected = _menuPeer ? (peer == _menuPeer) : (from == (isPressed() ? _filteredPressed : _filteredSelected));
|
||||
Dialogs::Layout::RowPainter::paint(p, _filterResults[from], fullWidth, active, selected, paintingOther, ms);
|
||||
p.translate(0, st::dialogsRowHeight);
|
||||
@ -378,20 +390,44 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsInner::paintDialog(Painter &p, Dialogs::Row *row, int fullWidth, PeerData *active, PeerData *selected, bool onlyBackground, TimeMs ms) {
|
||||
void DialogsInner::paintDialog(
|
||||
Painter &p,
|
||||
not_null<Dialogs::Row*> row,
|
||||
int fullWidth,
|
||||
PeerData *active,
|
||||
PeerData *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);
|
||||
auto isActive = (row->history()->peer == active) || (row->history()->peer->migrateTo() && row->history()->peer->migrateTo() == active);
|
||||
// #TODO feeds dialogs
|
||||
auto isActive = (row->history()->peer == active)
|
||||
|| (row->history()->peer->migrateTo()
|
||||
&& row->history()->peer->migrateTo() == active);
|
||||
auto isSelected = (row->history()->peer == selected);
|
||||
Dialogs::Layout::RowPainter::paint(p, row, fullWidth, isActive, isSelected, onlyBackground, ms);
|
||||
Dialogs::Layout::RowPainter::paint(
|
||||
p,
|
||||
row,
|
||||
fullWidth,
|
||||
isActive,
|
||||
isSelected,
|
||||
onlyBackground,
|
||||
ms);
|
||||
if (xadd || yadd) p.translate(-xadd, -yadd);
|
||||
}
|
||||
|
||||
void DialogsInner::paintPeerSearchResult(Painter &p, const PeerSearchResult *result, int fullWidth, bool active, bool selected, bool onlyBackground, TimeMs ms) const {
|
||||
void DialogsInner::paintPeerSearchResult(
|
||||
Painter &p,
|
||||
not_null<const PeerSearchResult*> result,
|
||||
int fullWidth,
|
||||
bool active,
|
||||
bool selected,
|
||||
bool onlyBackground,
|
||||
TimeMs ms) const {
|
||||
QRect fullRect(0, 0, fullWidth, st::dialogsRowHeight);
|
||||
p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg));
|
||||
if (!active) {
|
||||
@ -443,7 +479,11 @@ void DialogsInner::paintPeerSearchResult(Painter &p, const PeerSearchResult *res
|
||||
peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
|
||||
}
|
||||
|
||||
void DialogsInner::paintSearchInPeer(Painter &p, int fullWidth, bool onlyBackground, TimeMs ms) const {
|
||||
void DialogsInner::paintSearchInPeer(
|
||||
Painter &p,
|
||||
int fullWidth,
|
||||
bool onlyBackground,
|
||||
TimeMs ms) const {
|
||||
auto height = searchInPeerSkip();
|
||||
|
||||
auto top = st::searchedBarHeight;
|
||||
@ -657,6 +697,7 @@ void DialogsInner::mousePressEvent(QMouseEvent *e) {
|
||||
auto row = _pressed;
|
||||
row->addRipple(e->pos() - QPoint(0, dialogsOffset() + _pressed->pos() * st::dialogsRowHeight), QSize(getFullWidth(), st::dialogsRowHeight), [this, row] {
|
||||
if (!_a_pinnedShifting.animating()) {
|
||||
// #TODO feeds dialogs
|
||||
row->history()->updateChatListEntry();
|
||||
}
|
||||
});
|
||||
@ -667,20 +708,19 @@ void DialogsInner::mousePressEvent(QMouseEvent *e) {
|
||||
update(0, index * st::mentionHeight, getFullWidth(), st::mentionHeight);
|
||||
});
|
||||
} else if (_filteredPressed >= 0 && _filteredPressed < _filterResults.size()) {
|
||||
auto row = _filterResults[_filteredPressed];
|
||||
row->addRipple(e->pos() - QPoint(0, filteredOffset() + _filteredPressed * st::dialogsRowHeight), QSize(getFullWidth(), st::dialogsRowHeight), [row] {
|
||||
if (auto main = App::main()) {
|
||||
main->dlgUpdated(row->history()->peer, 0);
|
||||
}
|
||||
});
|
||||
const auto row = _filterResults[_filteredPressed];
|
||||
const auto list = Global::DialogsMode();
|
||||
row->addRipple(
|
||||
e->pos() - QPoint(0, filteredOffset() + _filteredPressed * st::dialogsRowHeight),
|
||||
QSize(getFullWidth(), st::dialogsRowHeight),
|
||||
[=] { dlgUpdated(list, row); });
|
||||
} else if (_peerSearchPressed >= 0 && _peerSearchPressed < _peerSearchResults.size()) {
|
||||
auto &result = _peerSearchResults[_peerSearchPressed];
|
||||
auto row = &result->row;
|
||||
row->addRipple(e->pos() - QPoint(0, peerSearchOffset() + _peerSearchPressed * st::dialogsRowHeight), QSize(getFullWidth(), st::dialogsRowHeight), [peer = result->peer] {
|
||||
if (auto main = App::main()) {
|
||||
main->dlgUpdated(peer, 0);
|
||||
}
|
||||
});
|
||||
row->addRipple(
|
||||
e->pos() - QPoint(0, peerSearchOffset() + _peerSearchPressed * st::dialogsRowHeight),
|
||||
QSize(getFullWidth(), st::dialogsRowHeight),
|
||||
[this, peer = result->peer] { updateSearchResult(peer); });
|
||||
} else if (_searchedPressed >= 0 && _searchedPressed < _searchResults.size()) {
|
||||
auto &row = _searchResults[_searchedPressed];
|
||||
row->addRipple(e->pos() - QPoint(0, searchedOffset() + _searchedPressed * st::dialogsRowHeight), QSize(getFullWidth(), st::dialogsRowHeight), [this, index = _searchedPressed] {
|
||||
@ -708,6 +748,7 @@ void DialogsInner::checkReorderPinnedStart(QPoint localPosition) {
|
||||
int DialogsInner::shownPinnedCount() const {
|
||||
auto result = 0;
|
||||
for_const (auto row, *shownDialogs()) {
|
||||
// #TODO feeds pinned
|
||||
if (!row->history()->isPinnedDialog()) {
|
||||
break;
|
||||
}
|
||||
@ -717,6 +758,7 @@ int DialogsInner::shownPinnedCount() const {
|
||||
}
|
||||
|
||||
int DialogsInner::countPinnedIndex(Dialogs::Row *ofRow) {
|
||||
// #TODO feeds pinned
|
||||
if (!ofRow || !ofRow->history()->isPinnedDialog()) {
|
||||
return -1;
|
||||
}
|
||||
@ -1032,7 +1074,7 @@ void DialogsInner::onDialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRo
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsInner::createDialog(History *history) {
|
||||
void DialogsInner::createDialog(not_null<History*> history) {
|
||||
if (history->peer->loadedStatus != PeerData::LoadedStatus::FullLoaded) {
|
||||
LOG(("API Error: DialogsInner::createDialog() called for a non loaded peer!"));
|
||||
return;
|
||||
@ -1041,7 +1083,7 @@ void DialogsInner::createDialog(History *history) {
|
||||
bool creating = !history->inChatList(Dialogs::Mode::All);
|
||||
if (creating) {
|
||||
auto mainRow = history->addToChatList(Dialogs::Mode::All, _dialogs.get());
|
||||
_contactsNoDialogs->del(history->peer, mainRow);
|
||||
_contactsNoDialogs->del(history, mainRow);
|
||||
}
|
||||
if (_dialogsImportant && !history->inChatList(Dialogs::Mode::Important) && !history->mute()) {
|
||||
if (Global::DialogsMode() == Dialogs::Mode::Important) {
|
||||
@ -1079,9 +1121,8 @@ void DialogsInner::createDialog(History *history) {
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsInner::removeDialog(History *history) {
|
||||
if (!history) return;
|
||||
|
||||
void DialogsInner::removeDialog(not_null<History*> history) {
|
||||
// #TODO feeds dialogs
|
||||
if (history->peer == _menuPeer && _menu) {
|
||||
InvokeQueued(this, [this] { _menu = nullptr; });
|
||||
}
|
||||
@ -1096,8 +1137,8 @@ void DialogsInner::removeDialog(History *history) {
|
||||
history->removeFromChatList(Dialogs::Mode::Important, _dialogsImportant.get());
|
||||
}
|
||||
Auth().notifications().clearFromHistory(history);
|
||||
if (_contacts->contains(history->peer->id)) {
|
||||
if (!_contactsNoDialogs->contains(history->peer->id)) {
|
||||
if (_contacts->contains(history)) {
|
||||
if (!_contactsNoDialogs->contains(history)) {
|
||||
_contactsNoDialogs->addByName(history);
|
||||
}
|
||||
}
|
||||
@ -1109,7 +1150,9 @@ void DialogsInner::removeDialog(History *history) {
|
||||
refresh();
|
||||
}
|
||||
|
||||
void DialogsInner::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) {
|
||||
void DialogsInner::dlgUpdated(
|
||||
Dialogs::Mode list,
|
||||
not_null<Dialogs::Row*> row) {
|
||||
if (_state == DefaultState) {
|
||||
if (Global::DialogsMode() == list) {
|
||||
auto position = row->pos();
|
||||
@ -1121,9 +1164,13 @@ void DialogsInner::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) {
|
||||
}
|
||||
} else if (_state == FilteredState || _state == SearchedState) {
|
||||
if (list == Dialogs::Mode::All) {
|
||||
for (int32 i = 0, l = _filterResults.size(); i < l; ++i) {
|
||||
if (_filterResults.at(i)->history() == row->history()) {
|
||||
update(0, filteredOffset() + i * st::dialogsRowHeight, getFullWidth(), st::dialogsRowHeight);
|
||||
for (auto i = 0, l = _filterResults.size(); i != l; ++i) {
|
||||
if (_filterResults[i]->key() == row->key()) {
|
||||
update(
|
||||
0,
|
||||
filteredOffset() + i * st::dialogsRowHeight,
|
||||
getFullWidth(),
|
||||
st::dialogsRowHeight);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1131,17 +1178,39 @@ void DialogsInner::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) {
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsInner::dlgUpdated(PeerData *peer, MsgId msgId) {
|
||||
updateDialogRow(peer, msgId, QRect(0, 0, getFullWidth(), st::dialogsRowHeight));
|
||||
void DialogsInner::dlgUpdated(not_null<History*> history, MsgId msgId) {
|
||||
updateDialogRow(
|
||||
history,
|
||||
msgId,
|
||||
QRect(0, 0, getFullWidth(), st::dialogsRowHeight));
|
||||
}
|
||||
|
||||
void DialogsInner::updateDialogRow(PeerData *peer, MsgId msgId, QRect updateRect, UpdateRowSections sections) {
|
||||
void DialogsInner::updateSearchResult(not_null<PeerData*> peer) {
|
||||
if (_state == FilteredState || _state == SearchedState) {
|
||||
if (!_peerSearchResults.empty()) {
|
||||
auto index = 0, add = peerSearchOffset();
|
||||
for_const (auto &result, _peerSearchResults) {
|
||||
if (result->peer == peer) {
|
||||
rtlupdate(0, add + index * st::dialogsRowHeight, getFullWidth(), st::dialogsRowHeight);
|
||||
break;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsInner::updateDialogRow(
|
||||
not_null<History*> history,
|
||||
MsgId msgId,
|
||||
QRect updateRect,
|
||||
UpdateRowSections sections) {
|
||||
auto updateRow = [this, updateRect](int rowTop) {
|
||||
rtlupdate(updateRect.x(), rowTop + updateRect.y(), updateRect.width(), updateRect.height());
|
||||
};
|
||||
if (_state == DefaultState) {
|
||||
if (sections & UpdateRowSection::Default) {
|
||||
if (auto row = shownDialogs()->getRow(peer->id)) {
|
||||
if (const auto row = shownDialogs()->getRow(history)) {
|
||||
auto position = row->pos();
|
||||
auto top = dialogsOffset();
|
||||
if (position >= 0 && position < _pinnedRows.size()) {
|
||||
@ -1154,7 +1223,7 @@ void DialogsInner::updateDialogRow(PeerData *peer, MsgId msgId, QRect updateRect
|
||||
if ((sections & UpdateRowSection::Filtered) && !_filterResults.isEmpty()) {
|
||||
auto index = 0, add = filteredOffset();
|
||||
for_const (auto row, _filterResults) {
|
||||
if (row->history()->peer == peer) {
|
||||
if (row->history() == history) {
|
||||
updateRow(add + index * st::dialogsRowHeight);
|
||||
break;
|
||||
}
|
||||
@ -1164,7 +1233,7 @@ void DialogsInner::updateDialogRow(PeerData *peer, MsgId msgId, QRect updateRect
|
||||
if ((sections & UpdateRowSection::PeerSearch) && !_peerSearchResults.empty()) {
|
||||
auto index = 0, add = peerSearchOffset();
|
||||
for_const (auto &result, _peerSearchResults) {
|
||||
if (result->peer == peer) {
|
||||
if (result->peer == history->peer) {
|
||||
updateRow(add + index * st::dialogsRowHeight);
|
||||
break;
|
||||
}
|
||||
@ -1175,7 +1244,7 @@ void DialogsInner::updateDialogRow(PeerData *peer, MsgId msgId, QRect updateRect
|
||||
auto index = 0, add = searchedOffset();
|
||||
for_const (auto &result, _searchResults) {
|
||||
auto item = result->item();
|
||||
if (item->history()->peer == peer && item->id == msgId) {
|
||||
if (item->history() == history && item->id == msgId) {
|
||||
updateRow(add + index * st::dialogsRowHeight);
|
||||
break;
|
||||
}
|
||||
@ -1191,6 +1260,7 @@ void DialogsInner::enterEventHook(QEvent *e) {
|
||||
}
|
||||
|
||||
void DialogsInner::updateSelectedRow(PeerData *peer) {
|
||||
// #TODO feeds dialogs
|
||||
if (_state == DefaultState) {
|
||||
if (peer) {
|
||||
if (auto h = App::historyLoaded(peer->id)) {
|
||||
@ -1210,8 +1280,8 @@ void DialogsInner::updateSelectedRow(PeerData *peer) {
|
||||
}
|
||||
} else if (_state == FilteredState || _state == SearchedState) {
|
||||
if (peer) {
|
||||
for (int32 i = 0, l = _filterResults.size(); i != l; ++i) {
|
||||
if (_filterResults.at(i)->history()->peer == peer) {
|
||||
for (auto i = 0, l = _filterResults.size(); i != l; ++i) {
|
||||
if (_filterResults[i]->history()->peer == peer) {
|
||||
update(0, filteredOffset() + i * st::dialogsRowHeight, getFullWidth(), st::dialogsRowHeight);
|
||||
break;
|
||||
}
|
||||
@ -1257,6 +1327,7 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) {
|
||||
updateSelected();
|
||||
}
|
||||
|
||||
// #TODO feeds context menu
|
||||
auto history = [&]() -> History* {
|
||||
if (_state == DefaultState) {
|
||||
if (_selected) {
|
||||
@ -1362,6 +1433,7 @@ void DialogsInner::onFilterUpdate(QString newFilter, bool force) {
|
||||
_filterResults.reserve((toFilter ? toFilter->size() : 0) + (toFilterContacts ? toFilterContacts->size() : 0));
|
||||
if (toFilter) {
|
||||
for_const (auto row, *toFilter) {
|
||||
// #TODO feeds dialogs
|
||||
const auto &nameWords = row->history()->peer->nameWords();
|
||||
auto nb = nameWords.cbegin(), ne = nameWords.cend(), ni = nb;
|
||||
for (fi = fb; fi != fe; ++fi) {
|
||||
@ -1382,6 +1454,7 @@ void DialogsInner::onFilterUpdate(QString newFilter, bool force) {
|
||||
}
|
||||
if (toFilterContacts) {
|
||||
for_const (auto row, *toFilterContacts) {
|
||||
// #TODO feeds dialogs
|
||||
const auto &nameWords = row->history()->peer->nameWords();
|
||||
auto nb = nameWords.cbegin(), ne = nameWords.cend(), ni = nb;
|
||||
for (fi = fb; fi != fe; ++fi) {
|
||||
@ -1453,6 +1526,7 @@ void DialogsInner::clearSearchResults(bool clearPeerSearchResults) {
|
||||
}
|
||||
|
||||
PeerData *DialogsInner::updateFromParentDrag(QPoint globalPos) {
|
||||
// #TODO feeds dialogs
|
||||
_mouseSelection = true;
|
||||
updateSelected(mapFromGlobal(globalPos));
|
||||
if (_state == DefaultState) {
|
||||
@ -1549,9 +1623,11 @@ void DialogsInner::applyDialog(const MTPDdialog &dialog) {
|
||||
if (!history->isPinnedDialog() && !history->lastMsgDate.isNull()) {
|
||||
addSavedPeersAfter(history->lastMsgDate);
|
||||
}
|
||||
_contactsNoDialogs->del(peer);
|
||||
_contactsNoDialogs->del(history);
|
||||
if (peer->migrateFrom()) {
|
||||
removeDialog(App::historyLoaded(peer->migrateFrom()->id));
|
||||
if (const auto historyFrom = App::historyLoaded(peer->migrateFrom())) {
|
||||
removeDialog(historyFrom);
|
||||
}
|
||||
} else if (peer->migrateTo() && peer->migrateTo()->amIn()) {
|
||||
removeDialog(history);
|
||||
}
|
||||
@ -1591,7 +1667,7 @@ void DialogsInner::addSavedPeersAfter(const QDateTime &date) {
|
||||
while (!saved.isEmpty() && (date.isNull() || date < saved.lastKey())) {
|
||||
const auto history = App::history(saved.last()->id);
|
||||
history->setChatsListDate(saved.lastKey());
|
||||
_contactsNoDialogs->del(history->peer);
|
||||
_contactsNoDialogs->del(history);
|
||||
saved.remove(saved.lastKey(), saved.last());
|
||||
}
|
||||
}
|
||||
@ -1674,19 +1750,19 @@ void DialogsInner::userIsContactUpdated(not_null<UserData*> user) {
|
||||
if (user->contactStatus() == UserData::ContactStatus::Contact) {
|
||||
const auto history = App::history(user->id);
|
||||
_contacts->addByName(history);
|
||||
if (!shownDialogs()->getRow(user->id)
|
||||
&& !_dialogs->contains(user->id)) {
|
||||
if (!shownDialogs()->getRow(history)
|
||||
&& !_dialogs->contains(history)) {
|
||||
_contactsNoDialogs->addByName(history);
|
||||
}
|
||||
} else {
|
||||
if (_selected && _selected->history()->peer == user) {
|
||||
} else if (const auto history = App::historyLoaded(user)) {
|
||||
if (_selected && _selected->history() == history) {
|
||||
_selected = nullptr;
|
||||
}
|
||||
if (_pressed && _pressed->history()->peer == user) {
|
||||
if (_pressed && _pressed->history() == history) {
|
||||
setPressed(nullptr);
|
||||
}
|
||||
_contactsNoDialogs->del(user);
|
||||
_contacts->del(user);
|
||||
_contactsNoDialogs->del(history);
|
||||
_contacts->del(history);
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
@ -1932,24 +2008,24 @@ void DialogsInner::selectSkip(int32 direction) {
|
||||
update();
|
||||
}
|
||||
|
||||
void DialogsInner::scrollToPeer(const PeerId &peer, MsgId msgId) {
|
||||
void DialogsInner::scrollToPeer(not_null<History*> history, MsgId msgId) {
|
||||
int32 fromY = -1;
|
||||
if (_state == DefaultState) {
|
||||
if (auto row = shownDialogs()->getRow(peer)) {
|
||||
if (auto row = shownDialogs()->getRow(history)) {
|
||||
fromY = dialogsOffset() + row->pos() * st::dialogsRowHeight;
|
||||
}
|
||||
} else if (_state == FilteredState || _state == SearchedState) {
|
||||
if (msgId) {
|
||||
for (int32 i = 0, c = _searchResults.size(); i < c; ++i) {
|
||||
if (_searchResults[i]->item()->history()->peer->id == peer && _searchResults[i]->item()->id == msgId) {
|
||||
if (_searchResults[i]->item()->history() == history && _searchResults[i]->item()->id == msgId) {
|
||||
fromY = searchedOffset() + i * st::dialogsRowHeight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fromY < 0) {
|
||||
for (int32 i = 0, c = _filterResults.size(); i < c; ++i) {
|
||||
if (_filterResults[i]->history()->peer->id == peer) {
|
||||
for (auto i = 0, c = _filterResults.size(); i != c; ++i) {
|
||||
if (_filterResults[i]->history() == history) {
|
||||
fromY = filteredOffset() + (i * st::dialogsRowHeight);
|
||||
break;
|
||||
}
|
||||
@ -2008,6 +2084,7 @@ void DialogsInner::loadPeerPhotos() {
|
||||
if (((*i)->pos() * st::dialogsRowHeight) >= yTo) {
|
||||
break;
|
||||
}
|
||||
// #TODO feeds dialogs
|
||||
(*i)->history()->peer->loadUserpic();
|
||||
}
|
||||
yFrom = 0;
|
||||
@ -2023,6 +2100,7 @@ void DialogsInner::loadPeerPhotos() {
|
||||
if (to > _filterResults.size()) to = _filterResults.size();
|
||||
|
||||
for (; from < to; ++from) {
|
||||
// #TODO feeds dialogs
|
||||
_filterResults[from]->history()->peer->loadUserpic();
|
||||
}
|
||||
}
|
||||
@ -2066,6 +2144,7 @@ bool DialogsInner::choosePeer() {
|
||||
_importantSwitchSelected = true;
|
||||
return true;
|
||||
} else if (_selected) {
|
||||
// #TODO feeds open
|
||||
history = _selected->history();
|
||||
}
|
||||
} else if (_state == FilteredState || _state == SearchedState) {
|
||||
@ -2092,6 +2171,7 @@ bool DialogsInner::choosePeer() {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// #TODO feeds open
|
||||
if (_filteredSelected >= 0 && _filteredSelected < _filterResults.size()) {
|
||||
history = _filterResults[_filteredSelected]->history();
|
||||
} else if (_peerSearchSelected >= 0 && _peerSearchSelected < _peerSearchResults.size()) {
|
||||
@ -2163,141 +2243,154 @@ void DialogsInner::destroyData() {
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsInner::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const {
|
||||
if (!inPeer) {
|
||||
outPeer = nullptr;
|
||||
outMsg = 0;
|
||||
return;
|
||||
|
||||
Dialogs::RowDescriptor DialogsInner::chatListEntryBefore(
|
||||
const Dialogs::RowDescriptor &which) const {
|
||||
if (!which.key.value) {
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
if (_state == DefaultState) {
|
||||
if (auto row = shownDialogs()->getRow(inPeer->id)) {
|
||||
auto i = shownDialogs()->cfind(row);
|
||||
if (const auto row = shownDialogs()->getRow(which.key)) {
|
||||
const auto i = shownDialogs()->cfind(row);
|
||||
if (i != shownDialogs()->cbegin()) {
|
||||
outPeer = (*(--i))->history()->peer;
|
||||
outMsg = ShowAtUnreadMsgId;
|
||||
return;
|
||||
return Dialogs::RowDescriptor((*(i - 1))->key(),
|
||||
ShowAtUnreadMsgId);
|
||||
}
|
||||
}
|
||||
outPeer = nullptr;
|
||||
outMsg = 0;
|
||||
return;
|
||||
} else if (_state == FilteredState || _state == SearchedState) {
|
||||
if (inMsg && !_searchResults.empty()) {
|
||||
for (auto b = _searchResults.cbegin(), i = b + 1, e = _searchResults.cend(); i != e; ++i) {
|
||||
if ((*i)->item()->history()->peer == inPeer && (*i)->item()->id == inMsg) {
|
||||
auto j = i - 1;
|
||||
outPeer = (*j)->item()->history()->peer;
|
||||
outMsg = (*j)->item()->id;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_searchResults.at(0)->item()->history()->peer == inPeer && _searchResults.at(0)->item()->id == inMsg) {
|
||||
outMsg = ShowAtUnreadMsgId;
|
||||
if (_peerSearchResults.empty()) {
|
||||
if (_filterResults.isEmpty()) {
|
||||
outPeer = nullptr;
|
||||
} else {
|
||||
outPeer = _filterResults.back()->history()->peer;
|
||||
}
|
||||
} else {
|
||||
outPeer = _peerSearchResults.back()->peer;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!_peerSearchResults.empty() && _peerSearchResults[0]->peer == inPeer) {
|
||||
outPeer = _filterResults.isEmpty() ? 0 : _filterResults.back()->history()->peer;
|
||||
outMsg = ShowAtUnreadMsgId;
|
||||
return;
|
||||
}
|
||||
if (!_peerSearchResults.empty()) {
|
||||
for (auto b = _peerSearchResults.cbegin(), i = b + 1, e = _peerSearchResults.cend(); i != e; ++i) {
|
||||
if ((*i)->peer == inPeer) {
|
||||
outPeer = (*(i - 1))->peer;
|
||||
outMsg = ShowAtUnreadMsgId;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_filterResults.isEmpty() || _filterResults.at(0)->history()->peer == inPeer) {
|
||||
outPeer = nullptr;
|
||||
outMsg = 0;
|
||||
return;
|
||||
}
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
|
||||
for (auto b = _filterResults.cbegin(), i = b + 1, e = _filterResults.cend(); i != e; ++i) {
|
||||
if ((*i)->history()->peer == inPeer) {
|
||||
outPeer = (*(i - 1))->history()->peer;
|
||||
outMsg = ShowAtUnreadMsgId;
|
||||
return;
|
||||
const auto whichHistory = which.key.history();
|
||||
const auto whichMsgId = which.msgId;
|
||||
if (!whichHistory) {
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
if (whichMsgId && !_searchResults.empty()) {
|
||||
for (auto b = _searchResults.cbegin(), i = b + 1, e = _searchResults.cend(); i != e; ++i) {
|
||||
if ((*i)->item()->history() == whichHistory
|
||||
&& (*i)->item()->id == whichMsgId) {
|
||||
const auto j = i - 1;
|
||||
return Dialogs::RowDescriptor(
|
||||
(*j)->item()->history(),
|
||||
(*j)->item()->id);
|
||||
}
|
||||
}
|
||||
if (_searchResults[0]->item()->history() == whichHistory
|
||||
&& _searchResults[0]->item()->id == whichMsgId) {
|
||||
if (_peerSearchResults.empty()) {
|
||||
if (_filterResults.isEmpty()) {
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
return Dialogs::RowDescriptor(
|
||||
_filterResults.back()->key(),
|
||||
ShowAtUnreadMsgId);
|
||||
}
|
||||
return Dialogs::RowDescriptor(
|
||||
App::history(_peerSearchResults.back()->peer),
|
||||
ShowAtUnreadMsgId);
|
||||
}
|
||||
}
|
||||
if (!_peerSearchResults.empty() && _peerSearchResults[0]->peer == whichHistory->peer) {
|
||||
if (_filterResults.isEmpty()) {
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
return Dialogs::RowDescriptor(
|
||||
_filterResults.back()->key(),
|
||||
ShowAtUnreadMsgId);
|
||||
}
|
||||
if (!_peerSearchResults.empty()) {
|
||||
for (auto b = _peerSearchResults.cbegin(), i = b + 1, e = _peerSearchResults.cend(); i != e; ++i) {
|
||||
if ((*i)->peer == whichHistory->peer) {
|
||||
return Dialogs::RowDescriptor(
|
||||
App::history((*(i - 1))->peer),
|
||||
ShowAtUnreadMsgId);
|
||||
}
|
||||
}
|
||||
}
|
||||
outPeer = nullptr;
|
||||
outMsg = 0;
|
||||
if (_filterResults.isEmpty() || _filterResults[0]->key() == which.key) {
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
|
||||
for (auto b = _filterResults.cbegin(), i = b + 1, e = _filterResults.cend(); i != e; ++i) {
|
||||
if ((*i)->key() == which.key) {
|
||||
return Dialogs::RowDescriptor(
|
||||
(*(i - 1))->key(),
|
||||
ShowAtUnreadMsgId);
|
||||
}
|
||||
}
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
|
||||
void DialogsInner::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const {
|
||||
if (!inPeer) {
|
||||
outPeer = nullptr;
|
||||
outMsg = 0;
|
||||
return;
|
||||
Dialogs::RowDescriptor DialogsInner::chatListEntryAfter(
|
||||
const Dialogs::RowDescriptor &which) const {
|
||||
if (!which.key.value) {
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
if (_state == DefaultState) {
|
||||
if (auto row = shownDialogs()->getRow(inPeer->id)) {
|
||||
auto i = shownDialogs()->cfind(row) + 1;
|
||||
if (const auto row = shownDialogs()->getRow(which.key)) {
|
||||
const auto i = shownDialogs()->cfind(row) + 1;
|
||||
if (i != shownDialogs()->cend()) {
|
||||
outPeer = (*i)->history()->peer;
|
||||
outMsg = ShowAtUnreadMsgId;
|
||||
return;
|
||||
return Dialogs::RowDescriptor(
|
||||
(*i)->key(),
|
||||
ShowAtUnreadMsgId);
|
||||
}
|
||||
}
|
||||
outPeer = nullptr;
|
||||
outMsg = 0;
|
||||
return;
|
||||
} else if (_state == FilteredState || _state == SearchedState) {
|
||||
if (inMsg) {
|
||||
for (auto i = _searchResults.cbegin(), e = _searchResults.cend(); i != e; ++i) {
|
||||
if ((*i)->item()->history()->peer == inPeer && (*i)->item()->id == inMsg) {
|
||||
++i;
|
||||
outPeer = (i == e) ? nullptr : (*i)->item()->history()->peer;
|
||||
outMsg = (i == e) ? 0 : (*i)->item()->id;
|
||||
return;
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
|
||||
const auto whichHistory = which.key.history();
|
||||
const auto whichMsgId = which.msgId;
|
||||
if (!whichHistory) {
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
if (whichMsgId) {
|
||||
for (auto i = _searchResults.cbegin(), e = _searchResults.cend(); i != e; ++i) {
|
||||
if ((*i)->item()->history() == whichHistory
|
||||
&& (*i)->item()->id == whichMsgId) {
|
||||
if (++i != e) {
|
||||
return Dialogs::RowDescriptor(
|
||||
(*i)->item()->history(),
|
||||
(*i)->item()->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto i = _peerSearchResults.cbegin(), e = _peerSearchResults.cend(); i != e; ++i) {
|
||||
if ((*i)->peer == inPeer) {
|
||||
++i;
|
||||
if (i == e && !_searchResults.empty()) {
|
||||
outPeer = _searchResults.front()->item()->history()->peer;
|
||||
outMsg = _searchResults.front()->item()->id;
|
||||
} else {
|
||||
outPeer = (i == e) ? nullptr : (*i)->peer;
|
||||
outMsg = ShowAtUnreadMsgId;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (FilteredDialogs::const_iterator i = _filterResults.cbegin(), e = _filterResults.cend(); i != e; ++i) {
|
||||
if ((*i)->history()->peer == inPeer) {
|
||||
++i;
|
||||
if (i == e && !_peerSearchResults.empty()) {
|
||||
outPeer = _peerSearchResults.front()->peer;
|
||||
outMsg = ShowAtUnreadMsgId;
|
||||
} else if (i == e && !_searchResults.empty()) {
|
||||
outPeer = _searchResults.front()->item()->history()->peer;
|
||||
outMsg = _searchResults.front()->item()->id;
|
||||
} else {
|
||||
outPeer = (i == e) ? nullptr : (*i)->history()->peer;
|
||||
outMsg = ShowAtUnreadMsgId;
|
||||
}
|
||||
return;
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
}
|
||||
}
|
||||
outPeer = nullptr;
|
||||
outMsg = 0;
|
||||
for (auto i = _peerSearchResults.cbegin(), e = _peerSearchResults.cend(); i != e; ++i) {
|
||||
if ((*i)->peer == whichHistory->peer) {
|
||||
++i;
|
||||
if (i != e) {
|
||||
return Dialogs::RowDescriptor(
|
||||
App::history((*i)->peer),
|
||||
ShowAtUnreadMsgId);
|
||||
} else if (!_searchResults.empty()) {
|
||||
return Dialogs::RowDescriptor(
|
||||
_searchResults.front()->item()->history(),
|
||||
_searchResults.front()->item()->id);
|
||||
}
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
}
|
||||
for (auto i = _filterResults.cbegin(), e = _filterResults.cend(); i != e; ++i) {
|
||||
if ((*i)->key() == which.key) {
|
||||
++i;
|
||||
if (i != e) {
|
||||
return Dialogs::RowDescriptor(
|
||||
(*i)->key(),
|
||||
ShowAtUnreadMsgId);
|
||||
} else if (!_peerSearchResults.empty()) {
|
||||
return Dialogs::RowDescriptor(
|
||||
App::history(_peerSearchResults.front()->peer),
|
||||
ShowAtUnreadMsgId);
|
||||
} else if (!_searchResults.empty()) {
|
||||
return Dialogs::RowDescriptor(
|
||||
_searchResults.front()->item()->history(),
|
||||
_searchResults.front()->item()->id);
|
||||
}
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
}
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
|
||||
Dialogs::IndexedList *DialogsInner::contactsList() {
|
||||
|
@ -44,10 +44,10 @@ public:
|
||||
void selectSkip(int32 direction);
|
||||
void selectSkipPage(int32 pixels, int32 direction);
|
||||
|
||||
void createDialog(History *history);
|
||||
void dlgUpdated(Dialogs::Mode list, Dialogs::Row *row);
|
||||
void dlgUpdated(PeerData *peer, MsgId msgId);
|
||||
void removeDialog(History *history);
|
||||
void createDialog(not_null<History*> history);
|
||||
void dlgUpdated(Dialogs::Mode list, not_null<Dialogs::Row*> row);
|
||||
void dlgUpdated(not_null<History*> history, MsgId msgId);
|
||||
void removeDialog(not_null<History*> history);
|
||||
|
||||
void dragLeft();
|
||||
|
||||
@ -59,9 +59,13 @@ public:
|
||||
|
||||
void destroyData();
|
||||
|
||||
void peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const;
|
||||
void peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const;
|
||||
void scrollToPeer(const PeerId &peer, MsgId msgId);
|
||||
|
||||
Dialogs::RowDescriptor chatListEntryBefore(
|
||||
const Dialogs::RowDescriptor &which) const;
|
||||
Dialogs::RowDescriptor chatListEntryAfter(
|
||||
const Dialogs::RowDescriptor &which) const;
|
||||
|
||||
void scrollToPeer(not_null<History*> history, MsgId msgId);
|
||||
|
||||
Dialogs::IndexedList *contactsList();
|
||||
Dialogs::IndexedList *dialogsList();
|
||||
@ -185,8 +189,9 @@ private:
|
||||
using UpdateRowSections = base::flags<UpdateRowSection>;
|
||||
friend inline constexpr auto is_flag_type(UpdateRowSection) { return true; };
|
||||
|
||||
void updateSearchResult(not_null<PeerData*> peer);
|
||||
void updateDialogRow(
|
||||
PeerData *peer,
|
||||
not_null<History*> history,
|
||||
MsgId msgId,
|
||||
QRect updateRect,
|
||||
UpdateRowSections sections = UpdateRowSection::All);
|
||||
@ -197,9 +202,27 @@ private:
|
||||
int searchedOffset() const;
|
||||
int searchInPeerSkip() const;
|
||||
|
||||
void paintDialog(Painter &p, Dialogs::Row *row, int fullWidth, PeerData *active, PeerData *selected, bool onlyBackground, TimeMs ms);
|
||||
void paintPeerSearchResult(Painter &p, const PeerSearchResult *result, int fullWidth, bool active, bool selected, bool onlyBackground, TimeMs ms) const;
|
||||
void paintSearchInPeer(Painter &p, int fullWidth, bool onlyBackground, TimeMs ms) const;
|
||||
void paintDialog(
|
||||
Painter &p,
|
||||
not_null<Dialogs::Row*> row,
|
||||
int fullWidth,
|
||||
PeerData *active,
|
||||
PeerData *selected,
|
||||
bool onlyBackground,
|
||||
TimeMs ms);
|
||||
void paintPeerSearchResult(
|
||||
Painter &p,
|
||||
not_null<const PeerSearchResult*> result,
|
||||
int fullWidth,
|
||||
bool active,
|
||||
bool selected,
|
||||
bool onlyBackground,
|
||||
TimeMs ms) const;
|
||||
void paintSearchInPeer(
|
||||
Painter &p,
|
||||
int fullWidth,
|
||||
bool onlyBackground,
|
||||
TimeMs ms) const;
|
||||
void paintSearchInFilter(
|
||||
Painter &p,
|
||||
PeerData *peer,
|
||||
|
@ -334,6 +334,7 @@ void RowPainter::paint(
|
||||
bool selected,
|
||||
bool onlyBackground,
|
||||
TimeMs ms) {
|
||||
// #TODO feeds show
|
||||
auto history = row->history();
|
||||
auto item = history->lastMsg;
|
||||
auto cloudDraft = history->cloudDraft();
|
||||
|
@ -14,7 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
namespace Dialogs {
|
||||
|
||||
List::List(SortMode sortMode)
|
||||
: _last(std::make_unique<Row>(nullptr, nullptr, nullptr, 0))
|
||||
: _last(std::make_unique<Row>(nullptr))
|
||||
, _begin(_last.get())
|
||||
, _end(_last.get())
|
||||
, _sortMode(sortMode)
|
||||
@ -33,15 +33,15 @@ void List::adjustCurrent(int32 y, int32 h) const {
|
||||
}
|
||||
}
|
||||
|
||||
Row *List::addToEnd(not_null<History*> history) {
|
||||
const auto result = new Row(history, _end->_prev, _end, _end->_pos);
|
||||
Row *List::addToEnd(Key key) {
|
||||
const auto result = new Row(key, _end->_prev, _end, _end->_pos);
|
||||
_end->_pos++;
|
||||
if (_begin == _end) {
|
||||
_begin = _current = result;
|
||||
} else {
|
||||
_end->_prev->_next = result;
|
||||
}
|
||||
_rowByPeer.insert(history->peer->id, result);
|
||||
_rowByKey.emplace(key, result);
|
||||
++_count;
|
||||
_end->_prev = result;
|
||||
if (_sortMode == SortMode::Date) {
|
||||
@ -51,13 +51,15 @@ Row *List::addToEnd(not_null<History*> history) {
|
||||
}
|
||||
|
||||
bool List::insertBefore(Row *row, Row *before) {
|
||||
if (row == before) return false;
|
||||
if (row == before) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_current == row) {
|
||||
_current = row->_prev;
|
||||
}
|
||||
|
||||
Row *updateTill = row->_prev;
|
||||
const auto updateTill = row->_prev;
|
||||
remove(row);
|
||||
|
||||
// insert row
|
||||
@ -70,8 +72,8 @@ bool List::insertBefore(Row *row, Row *before) {
|
||||
_begin = row;
|
||||
}
|
||||
|
||||
// update y
|
||||
for (Row *n = row; n != updateTill; n = n->_next) {
|
||||
// update pos
|
||||
for (auto n = row; n != updateTill; n = n->_next) {
|
||||
n->_next->_pos++;
|
||||
row->_pos--;
|
||||
}
|
||||
@ -79,13 +81,15 @@ bool List::insertBefore(Row *row, Row *before) {
|
||||
}
|
||||
|
||||
bool List::insertAfter(Row *row, Row *after) {
|
||||
if (row == after) return false;
|
||||
if (row == after) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_current == row) {
|
||||
_current = row->_next;
|
||||
}
|
||||
|
||||
Row *updateFrom = row->_next;
|
||||
const auto updateFrom = row->_next;
|
||||
remove(row);
|
||||
|
||||
// insert row
|
||||
@ -94,26 +98,28 @@ bool List::insertAfter(Row *row, Row *after) {
|
||||
row->_prev->_next = row; // update row->prev
|
||||
row->_next->_prev = row; // update row->next
|
||||
|
||||
// update y
|
||||
for (Row *n = updateFrom; n != row; n = n->_next) {
|
||||
// update pos
|
||||
for (auto n = updateFrom; n != row; n = n->_next) {
|
||||
n->_pos--;
|
||||
row->_pos++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Row *List::adjustByName(const PeerData *peer) {
|
||||
Row *List::adjustByName(Key key) {
|
||||
if (_sortMode != SortMode::Name) return nullptr;
|
||||
|
||||
auto i = _rowByPeer.find(peer->id);
|
||||
if (i == _rowByPeer.cend()) return nullptr;
|
||||
const auto i = _rowByKey.find(key);
|
||||
if (i == _rowByKey.cend()) return nullptr;
|
||||
|
||||
Row *row = i.value(), *change = row;
|
||||
while (change->_prev && change->_prev->history()->peer->name > peer->name) {
|
||||
const auto row = i->second;
|
||||
const auto name = key.name();
|
||||
auto change = row;
|
||||
while (change->_prev && change->_prev->name().compare(name, Qt::CaseInsensitive) < 0) {
|
||||
change = change->_prev;
|
||||
}
|
||||
if (!insertBefore(row, change)) {
|
||||
while (change->_next != _end && change->_next->history()->peer->name < peer->name) {
|
||||
while (change->_next != _end && change->_next->name().compare(name, Qt::CaseInsensitive) < 0) {
|
||||
change = change->_next;
|
||||
}
|
||||
insertAfter(row, change);
|
||||
@ -121,19 +127,19 @@ Row *List::adjustByName(const PeerData *peer) {
|
||||
return row;
|
||||
}
|
||||
|
||||
Row *List::addByName(not_null<History*> history) {
|
||||
Row *List::addByName(Key key) {
|
||||
if (_sortMode != SortMode::Name) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto row = addToEnd(history);
|
||||
const auto row = addToEnd(key);
|
||||
auto change = row;
|
||||
const QString &peerName(history->peer->name);
|
||||
while (change->_prev && change->_prev->history()->peer->name.compare(peerName, Qt::CaseInsensitive) > 0) {
|
||||
const auto name = key.name();
|
||||
while (change->_prev && change->_prev->name().compare(name, Qt::CaseInsensitive) > 0) {
|
||||
change = change->_prev;
|
||||
}
|
||||
if (!insertBefore(row, change)) {
|
||||
while (change->_next != _end && change->_next->history()->peer->name.compare(peerName, Qt::CaseInsensitive) < 0) {
|
||||
while (change->_next != _end && change->_next->name().compare(name, Qt::CaseInsensitive) < 0) {
|
||||
change = change->_next;
|
||||
}
|
||||
insertAfter(row, change);
|
||||
@ -145,18 +151,18 @@ void List::adjustByPos(Row *row) {
|
||||
if (_sortMode != SortMode::Date || !_begin) return;
|
||||
|
||||
Row *change = row;
|
||||
if (change != _begin && _begin->history()->sortKeyInChatList() < row->history()->sortKeyInChatList()) {
|
||||
if (change != _begin && _begin->sortKey() < row->sortKey()) {
|
||||
change = _begin;
|
||||
} else {
|
||||
while (change->_prev && change->_prev->history()->sortKeyInChatList() < row->history()->sortKeyInChatList()) {
|
||||
while (change->_prev && change->_prev->sortKey() < row->sortKey()) {
|
||||
change = change->_prev;
|
||||
}
|
||||
}
|
||||
if (!insertBefore(row, change)) {
|
||||
if (change->_next != _end && _end->_prev->history()->sortKeyInChatList() > row->history()->sortKeyInChatList()) {
|
||||
if (change->_next != _end && _end->_prev->sortKey() > row->sortKey()) {
|
||||
change = _end->_prev;
|
||||
} else {
|
||||
while (change->_next != _end && change->_next->history()->sortKeyInChatList() > row->history()->sortKeyInChatList()) {
|
||||
while (change->_next != _end && change->_next->sortKey() > row->sortKey()) {
|
||||
change = change->_next;
|
||||
}
|
||||
}
|
||||
@ -164,19 +170,23 @@ void List::adjustByPos(Row *row) {
|
||||
}
|
||||
}
|
||||
|
||||
bool List::moveToTop(PeerId peerId) {
|
||||
auto i = _rowByPeer.find(peerId);
|
||||
if (i == _rowByPeer.cend()) return false;
|
||||
bool List::moveToTop(Key key) {
|
||||
auto i = _rowByKey.find(key);
|
||||
if (i == _rowByKey.cend()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
insertBefore(i.value(), _begin);
|
||||
insertBefore(i->second, _begin);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool List::del(PeerId peerId, Row *replacedBy) {
|
||||
auto i = _rowByPeer.find(peerId);
|
||||
if (i == _rowByPeer.cend()) return false;
|
||||
bool List::del(Key key, Row *replacedBy) {
|
||||
auto i = _rowByKey.find(key);
|
||||
if (i == _rowByKey.cend()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = i.value();
|
||||
const auto row = i->second;
|
||||
if (App::main()) {
|
||||
emit App::main()->dialogRowReplaced(row, replacedBy);
|
||||
}
|
||||
@ -191,7 +201,7 @@ bool List::del(PeerId peerId, Row *replacedBy) {
|
||||
remove(row);
|
||||
delete row;
|
||||
--_count;
|
||||
_rowByPeer.erase(i);
|
||||
_rowByKey.erase(i);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -212,7 +222,7 @@ void List::clear() {
|
||||
delete _current;
|
||||
}
|
||||
_current = _begin;
|
||||
_rowByPeer.clear();
|
||||
_rowByKey.clear();
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
|
@ -24,11 +24,12 @@ public:
|
||||
bool isEmpty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
bool contains(PeerId peerId) const {
|
||||
return _rowByPeer.contains(peerId);
|
||||
bool contains(Key key) const {
|
||||
return _rowByKey.find(key) != _rowByKey.end();
|
||||
}
|
||||
Row *getRow(PeerId peerId) const {
|
||||
return _rowByPeer.value(peerId);
|
||||
Row *getRow(Key key) const {
|
||||
const auto i = _rowByKey.find(key);
|
||||
return (i == _rowByKey.end()) ? nullptr : i->second.get();
|
||||
}
|
||||
Row *rowAtY(int32 y, int32 h) const {
|
||||
auto i = cfind(y, h);
|
||||
@ -38,12 +39,12 @@ public:
|
||||
return *i;
|
||||
}
|
||||
|
||||
Row *addToEnd(not_null<History*> history);
|
||||
Row *adjustByName(const PeerData *peer);
|
||||
Row *addByName(not_null<History*> history);
|
||||
bool moveToTop(PeerId peerId);
|
||||
Row *addToEnd(Key key);
|
||||
Row *adjustByName(Key key);
|
||||
Row *addByName(Key key);
|
||||
bool moveToTop(Key key);
|
||||
void adjustByPos(Row *row);
|
||||
bool del(PeerId peerId, Row *replacedBy = nullptr);
|
||||
bool del(Key key, Row *replacedBy = nullptr);
|
||||
void remove(Row *row);
|
||||
void clear();
|
||||
|
||||
@ -114,10 +115,10 @@ private:
|
||||
SortMode _sortMode;
|
||||
int _count = 0;
|
||||
|
||||
typedef QHash<PeerId, Row*> RowByPeer;
|
||||
RowByPeer _rowByPeer;
|
||||
std::map<Key, not_null<Row*>> _rowByKey;
|
||||
|
||||
mutable Row *_current; // cache
|
||||
|
||||
};
|
||||
|
||||
} // namespace Dialogs
|
||||
|
@ -8,10 +8,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#pragma once
|
||||
|
||||
#include "ui/text/text.h"
|
||||
#include "base/value_ordering.h"
|
||||
|
||||
class History;
|
||||
class HistoryItem;
|
||||
|
||||
namespace Data {
|
||||
class Feed;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
class RippleAnimation;
|
||||
} // namespace Ui
|
||||
@ -21,6 +26,79 @@ namespace Layout {
|
||||
class RowPainter;
|
||||
} // namespace Layout
|
||||
|
||||
struct Key {
|
||||
Key() = default;
|
||||
Key(History *history) : value(history) {
|
||||
}
|
||||
Key(not_null<History*> history) : value(history) {
|
||||
}
|
||||
Key(Data::Feed *feed) : value(feed) {
|
||||
}
|
||||
Key(not_null<Data::Feed*> feed) : value(feed) {
|
||||
}
|
||||
const QString &name() const {
|
||||
if (const auto p = base::get_if<not_null<History*>>(&value)) {
|
||||
return (*p)->peer->name;
|
||||
}
|
||||
// #TODO feeds name
|
||||
static const auto empty = QString();
|
||||
return empty;
|
||||
}
|
||||
const PeerData::NameFirstChars &nameFirstChars() const {
|
||||
if (const auto p = base::get_if<not_null<History*>>(&value)) {
|
||||
return (*p)->peer->nameFirstChars();
|
||||
}
|
||||
// #TODO feeds name
|
||||
static const auto empty = PeerData::NameFirstChars();
|
||||
return empty;
|
||||
}
|
||||
uint64 sortKey() const {
|
||||
if (const auto p = base::get_if<not_null<History*>>(&value)) {
|
||||
return (*p)->sortKeyInChatList();
|
||||
}
|
||||
// #TODO feeds sort in chats list
|
||||
return 0ULL;
|
||||
}
|
||||
History *history() const {
|
||||
if (const auto p = base::get_if<not_null<History*>>(&value)) {
|
||||
return *p;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
Data::Feed *feed() const {
|
||||
if (const auto p = base::get_if<not_null<Data::Feed*>>(&value)) {
|
||||
return *p;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline bool operator<(const Key &other) const {
|
||||
return value < other.value;
|
||||
}
|
||||
inline bool operator==(const Key &other) const {
|
||||
return value == other.value;
|
||||
}
|
||||
|
||||
// Not working :(
|
||||
//friend inline auto value_ordering_helper(const Key &key) {
|
||||
// return key.value;
|
||||
//}
|
||||
|
||||
base::optional_variant<
|
||||
not_null<History*>,
|
||||
not_null<Data::Feed*>> value;
|
||||
|
||||
};
|
||||
|
||||
struct RowDescriptor {
|
||||
RowDescriptor() = default;
|
||||
RowDescriptor(Key key, MsgId msgId) : key(key), msgId(msgId) {
|
||||
}
|
||||
|
||||
Key key;
|
||||
MsgId msgId = 0;
|
||||
};
|
||||
|
||||
class RippleRow {
|
||||
public:
|
||||
RippleRow();
|
||||
@ -39,27 +117,44 @@ private:
|
||||
class List;
|
||||
class Row : public RippleRow {
|
||||
public:
|
||||
Row(History *history, Row *prev, Row *next, int pos)
|
||||
: _history(history)
|
||||
, _prev(prev)
|
||||
, _next(next)
|
||||
, _pos(pos) {
|
||||
explicit Row(std::nullptr_t) {
|
||||
}
|
||||
Row(Key key, Row *prev, Row *next, int pos)
|
||||
: _id(key)
|
||||
, _prev(prev)
|
||||
, _next(next)
|
||||
, _pos(pos) {
|
||||
}
|
||||
void *attached = nullptr; // for any attached data, for example View in contacts list
|
||||
|
||||
Key key() const {
|
||||
return _id;
|
||||
}
|
||||
History *history() const {
|
||||
return _history;
|
||||
return _id.history();
|
||||
}
|
||||
Data::Feed *feed() const {
|
||||
return _id.feed();
|
||||
}
|
||||
QString name() const {
|
||||
return _id.name();
|
||||
}
|
||||
int pos() const {
|
||||
return _pos;
|
||||
}
|
||||
uint64 sortKey() const {
|
||||
return _id.sortKey();
|
||||
}
|
||||
|
||||
// for any attached data, for example View in contacts list
|
||||
void *attached = nullptr;
|
||||
|
||||
private:
|
||||
friend class List;
|
||||
|
||||
History *_history;
|
||||
Row *_prev, *_next;
|
||||
int _pos;
|
||||
Key _id;
|
||||
Row *_prev = nullptr;
|
||||
Row *_next = nullptr;
|
||||
int _pos = 0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -9,8 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "dialogs/dialogs_inner_widget.h"
|
||||
#include "dialogs/dialogs_search_from_controllers.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_window.h"
|
||||
#include "dialogs/dialogs_row.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
@ -28,6 +27,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "profile/profile_channel_controllers.h"
|
||||
#include "storage/storage_media_prepare.h"
|
||||
#include "data/data_session.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_window.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -181,11 +182,11 @@ void DialogsWidget::activate() {
|
||||
_inner->activate();
|
||||
}
|
||||
|
||||
void DialogsWidget::createDialog(History *history) {
|
||||
void DialogsWidget::createDialog(not_null<History*> history) {
|
||||
auto creating = !history->inChatList(Dialogs::Mode::All);
|
||||
_inner->createDialog(history);
|
||||
if (creating && history->peer->migrateFrom()) {
|
||||
if (auto migrated = App::historyLoaded(history->peer->migrateFrom()->id)) {
|
||||
if (const auto migrated = App::historyLoaded(history->peer->migrateFrom())) {
|
||||
if (migrated->inChatList(Dialogs::Mode::All)) {
|
||||
removeDialog(migrated);
|
||||
}
|
||||
@ -193,12 +194,14 @@ void DialogsWidget::createDialog(History *history) {
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsWidget::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) {
|
||||
void DialogsWidget::dlgUpdated(
|
||||
Dialogs::Mode list,
|
||||
not_null<Dialogs::Row*> row) {
|
||||
_inner->dlgUpdated(list, row);
|
||||
}
|
||||
|
||||
void DialogsWidget::dlgUpdated(PeerData *peer, MsgId msgId) {
|
||||
_inner->dlgUpdated(peer, msgId);
|
||||
void DialogsWidget::dlgUpdated(not_null<History*> history, MsgId msgId) {
|
||||
_inner->dlgUpdated(history, msgId);
|
||||
}
|
||||
|
||||
void DialogsWidget::dialogsToUp() {
|
||||
@ -1103,19 +1106,21 @@ void DialogsWidget::destroyData() {
|
||||
_inner->destroyData();
|
||||
}
|
||||
|
||||
void DialogsWidget::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const {
|
||||
return _inner->peerBefore(inPeer, inMsg, outPeer, outMsg);
|
||||
Dialogs::RowDescriptor DialogsWidget::chatListEntryBefore(
|
||||
const Dialogs::RowDescriptor &which) const {
|
||||
return _inner->chatListEntryBefore(which);
|
||||
}
|
||||
|
||||
void DialogsWidget::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const {
|
||||
return _inner->peerAfter(inPeer, inMsg, outPeer, outMsg);
|
||||
Dialogs::RowDescriptor DialogsWidget::chatListEntryAfter(
|
||||
const Dialogs::RowDescriptor &which) const {
|
||||
return _inner->chatListEntryAfter(which);
|
||||
}
|
||||
|
||||
void DialogsWidget::scrollToPeer(const PeerId &peer, MsgId msgId) {
|
||||
_inner->scrollToPeer(peer, msgId);
|
||||
void DialogsWidget::scrollToPeer(not_null<History*> history, MsgId msgId) {
|
||||
_inner->scrollToPeer(history, msgId);
|
||||
}
|
||||
|
||||
void DialogsWidget::removeDialog(History *history) {
|
||||
void DialogsWidget::removeDialog(not_null<History*> history) {
|
||||
_inner->removeDialog(history);
|
||||
onFilterUpdate();
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
class DialogsInner;
|
||||
|
||||
namespace Dialogs {
|
||||
struct RowDescriptor;
|
||||
class Row;
|
||||
class FakeRow;
|
||||
class IndexedList;
|
||||
@ -54,9 +55,10 @@ public:
|
||||
|
||||
void loadDialogs();
|
||||
void loadPinnedDialogs();
|
||||
void createDialog(History *history);
|
||||
void dlgUpdated(Dialogs::Mode list, Dialogs::Row *row);
|
||||
void dlgUpdated(PeerData *peer, MsgId msgId);
|
||||
void createDialog(not_null<History*> history);
|
||||
void removeDialog(not_null<History*> history);
|
||||
void dlgUpdated(Dialogs::Mode list, not_null<Dialogs::Row*> row);
|
||||
void dlgUpdated(not_null<History*> history, MsgId msgId);
|
||||
|
||||
void dialogsToUp();
|
||||
|
||||
@ -71,11 +73,12 @@ public:
|
||||
|
||||
void destroyData();
|
||||
|
||||
void peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const;
|
||||
void peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const;
|
||||
void scrollToPeer(const PeerId &peer, MsgId msgId);
|
||||
Dialogs::RowDescriptor chatListEntryBefore(
|
||||
const Dialogs::RowDescriptor &which) const;
|
||||
Dialogs::RowDescriptor chatListEntryAfter(
|
||||
const Dialogs::RowDescriptor &which) const;
|
||||
|
||||
void removeDialog(History *history);
|
||||
void scrollToPeer(not_null<History*> history, MsgId msgId);
|
||||
|
||||
Dialogs::IndexedList *contactsList();
|
||||
Dialogs::IndexedList *dialogsList();
|
||||
|
@ -168,12 +168,6 @@ void joinGroupByHash(const QString &hash) {
|
||||
if (MainWidget *m = main()) m->joinGroupByHash(hash);
|
||||
}
|
||||
|
||||
void removeDialog(History *history) {
|
||||
if (MainWidget *m = main()) {
|
||||
m->removeDialog(history);
|
||||
}
|
||||
}
|
||||
|
||||
void showSettings() {
|
||||
if (auto w = wnd()) {
|
||||
w->showSettings();
|
||||
|
@ -133,7 +133,6 @@ void openPeerByName(
|
||||
MsgId msgId = ShowAtUnreadMsgId,
|
||||
const QString &startToken = QString());
|
||||
void joinGroupByHash(const QString &hash);
|
||||
void removeDialog(History *history);
|
||||
void showSettings();
|
||||
|
||||
void activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button);
|
||||
|
@ -2564,7 +2564,7 @@ Dialogs::Row *History::addToChatList(Dialogs::Mode list, Dialogs::IndexedList *i
|
||||
void History::removeFromChatList(Dialogs::Mode list, Dialogs::IndexedList *indexed) {
|
||||
Assert(indexed != nullptr);
|
||||
if (inChatList(list)) {
|
||||
indexed->del(peer);
|
||||
indexed->del(this);
|
||||
chatListLinks(list).clear();
|
||||
if (list == Dialogs::Mode::All && unreadCount()) {
|
||||
App::histories().unreadIncrement(-unreadCount(), mute());
|
||||
@ -2590,9 +2590,13 @@ void History::addChatListEntryByLetter(Dialogs::Mode list, QChar letter, Dialogs
|
||||
void History::updateChatListEntry() const {
|
||||
if (auto main = App::main()) {
|
||||
if (inChatList(Dialogs::Mode::All)) {
|
||||
main->dlgUpdated(Dialogs::Mode::All, mainChatListLink(Dialogs::Mode::All));
|
||||
main->dlgUpdated(
|
||||
Dialogs::Mode::All,
|
||||
mainChatListLink(Dialogs::Mode::All));
|
||||
if (inChatList(Dialogs::Mode::Important)) {
|
||||
main->dlgUpdated(Dialogs::Mode::Important, mainChatListLink(Dialogs::Mode::Important));
|
||||
main->dlgUpdated(
|
||||
Dialogs::Mode::Important,
|
||||
mainChatListLink(Dialogs::Mode::Important));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +164,8 @@ ReplyKeyboard *HistoryItem::inlineReplyKeyboard() {
|
||||
|
||||
void HistoryItem::invalidateChatsListEntry() {
|
||||
if (App::main()) {
|
||||
App::main()->dlgUpdated(history()->peer, id);
|
||||
// #TODO feeds dialogs
|
||||
App::main()->dlgUpdated(history(), id);
|
||||
}
|
||||
|
||||
// invalidate cache for drawInDialog
|
||||
|
@ -775,7 +775,8 @@ void HistoryService::updateDependentText() {
|
||||
history()->textCachedFor = nullptr;
|
||||
}
|
||||
if (App::main()) {
|
||||
App::main()->dlgUpdated(history()->peer, id);
|
||||
// #TODO feeds dialogs
|
||||
App::main()->dlgUpdated(history(), id);
|
||||
}
|
||||
App::historyUpdateDependent(this);
|
||||
}
|
||||
|
@ -7,13 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "history/history_widget.h"
|
||||
|
||||
#include "styles/style_history.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_window.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_profile.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_info.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "boxes/send_files_box.h"
|
||||
#include "boxes/share_box.h"
|
||||
@ -72,6 +65,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "inline_bots/inline_results_widget.h"
|
||||
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||
#include "core/crash_reports.h"
|
||||
#include "dialogs/dialogs_row.h"
|
||||
#include "styles/style_history.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_window.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_profile.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_info.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -1391,24 +1392,30 @@ bool HistoryWidget::cmd_search() {
|
||||
}
|
||||
|
||||
bool HistoryWidget::cmd_next_chat() {
|
||||
PeerData *p = 0;
|
||||
MsgId m = 0;
|
||||
App::main()->peerAfter(_peer, qMax(_showAtMsgId, 0), p, m);
|
||||
if (p) {
|
||||
Ui::showPeerHistory(p, m);
|
||||
if (!_history) {
|
||||
return false;
|
||||
}
|
||||
const auto next = App::main()->chatListEntryAfter(
|
||||
Dialogs::RowDescriptor(_history, std::max(_showAtMsgId, 0)));
|
||||
if (const auto history = next.key.history()) {
|
||||
Ui::showPeerHistory(history, next.msgId);
|
||||
return true;
|
||||
}
|
||||
// #TODO feeds show
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HistoryWidget::cmd_previous_chat() {
|
||||
PeerData *p = 0;
|
||||
MsgId m = 0;
|
||||
App::main()->peerBefore(_peer, qMax(_showAtMsgId, 0), p, m);
|
||||
if (p) {
|
||||
Ui::showPeerHistory(p, m);
|
||||
if (!_history) {
|
||||
return false;
|
||||
}
|
||||
const auto next = App::main()->chatListEntryBefore(
|
||||
Dialogs::RowDescriptor(_history, std::max(_showAtMsgId, 0)));
|
||||
if (const auto history = next.key.history()) {
|
||||
Ui::showPeerHistory(history, next.msgId);
|
||||
return true;
|
||||
}
|
||||
// #TODO feeds show
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1579,7 +1586,9 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
||||
if (!canShowNow) {
|
||||
delayedShowAt(showAtMsgId);
|
||||
|
||||
App::main()->dlgUpdated(wasHistory ? wasHistory->peer : nullptr, wasMsgId);
|
||||
if (wasHistory) {
|
||||
App::main()->dlgUpdated(wasHistory, wasMsgId);
|
||||
}
|
||||
emit historyShown(_history, _showAtMsgId);
|
||||
} else {
|
||||
_history->forgetScrollState();
|
||||
@ -1780,7 +1789,9 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
||||
|
||||
if (App::wnd()) QTimer::singleShot(0, App::wnd(), SLOT(setInnerFocus()));
|
||||
|
||||
App::main()->dlgUpdated(wasHistory ? wasHistory->peer : nullptr, wasMsgId);
|
||||
if (wasHistory) {
|
||||
App::main()->dlgUpdated(wasHistory, wasMsgId);
|
||||
}
|
||||
emit historyShown(_history, _showAtMsgId);
|
||||
|
||||
controller()->historyPeer = _peer;
|
||||
@ -2988,11 +2999,14 @@ PeerData *HistoryWidget::peer() const {
|
||||
return _peer;
|
||||
}
|
||||
|
||||
void HistoryWidget::setMsgId(MsgId showAtMsgId) { // sometimes _showAtMsgId is set directly
|
||||
// Sometimes _showAtMsgId is set directly.
|
||||
void HistoryWidget::setMsgId(MsgId showAtMsgId) {
|
||||
if (_showAtMsgId != showAtMsgId) {
|
||||
auto wasMsgId = _showAtMsgId;
|
||||
_showAtMsgId = showAtMsgId;
|
||||
App::main()->dlgUpdated(_history ? _history->peer : nullptr, wasMsgId);
|
||||
if (_history) {
|
||||
App::main()->dlgUpdated(_history, wasMsgId);
|
||||
}
|
||||
emit historyShown(_history, _showAtMsgId);
|
||||
}
|
||||
}
|
||||
|
@ -15,15 +15,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_web_page.h"
|
||||
#include "data/data_game.h"
|
||||
#include "data/data_peer_values.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_history.h"
|
||||
#include "data/data_drafts.h"
|
||||
#include "data/data_session.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "window/section_memento.h"
|
||||
#include "window/section_widget.h"
|
||||
#include "data/data_drafts.h"
|
||||
#include "data/data_session.h"
|
||||
#include "ui/widgets/dropdown_menu.h"
|
||||
#include "ui/focus_persister.h"
|
||||
#include "ui/resize_area.h"
|
||||
@ -36,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "observer_peer.h"
|
||||
#include "apiwrap.h"
|
||||
#include "dialogs/dialogs_widget.h"
|
||||
#include "dialogs/dialogs_row.h"
|
||||
#include "history/history_widget.h"
|
||||
#include "history/history_message.h"
|
||||
#include "history/history_media.h"
|
||||
@ -69,16 +68,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "window/window_slide_animation.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "mtproto/dc_options.h"
|
||||
#include "core/file_utilities.h"
|
||||
#include "auth_session.h"
|
||||
#include "calls/calls_instance.h"
|
||||
#include "calls/calls_top_bar.h"
|
||||
#include "auth_session.h"
|
||||
#include "storage/storage_facade.h"
|
||||
#include "storage/storage_shared_media.h"
|
||||
#include "storage/storage_user_photos.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_history.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
enum StackItemType {
|
||||
HistoryStackItem,
|
||||
@ -120,10 +120,11 @@ private:
|
||||
class StackItemHistory : public StackItem {
|
||||
public:
|
||||
StackItemHistory(
|
||||
PeerData *peer,
|
||||
not_null<History*> history,
|
||||
MsgId msgId,
|
||||
QList<MsgId> replyReturns)
|
||||
: StackItem(peer)
|
||||
: StackItem(history->peer)
|
||||
, history(history)
|
||||
, msgId(msgId)
|
||||
, replyReturns(replyReturns) {
|
||||
}
|
||||
@ -132,6 +133,7 @@ public:
|
||||
return HistoryStackItem;
|
||||
}
|
||||
|
||||
not_null<History*> history;
|
||||
MsgId msgId;
|
||||
QList<MsgId> replyReturns;
|
||||
|
||||
@ -902,7 +904,7 @@ void MainWidget::hiderLayer(object_ptr<HistoryHider> h) {
|
||||
_hider->hide();
|
||||
auto animationParams = prepareDialogsAnimation();
|
||||
|
||||
onHistoryShown(0, 0);
|
||||
onHistoryShown(nullptr, 0);
|
||||
if (_mainSection) {
|
||||
_mainSection->hide();
|
||||
} else {
|
||||
@ -1089,7 +1091,7 @@ void MainWidget::deletedContact(UserData *user, const MTPcontacts_Link &result)
|
||||
App::feedUserLink(MTP_int(peerToUser(user->id)), d.vmy_link, d.vforeign_link);
|
||||
}
|
||||
|
||||
void MainWidget::removeDialog(History *history) {
|
||||
void MainWidget::removeDialog(not_null<History*> history) {
|
||||
_dialogs->removeDialog(history);
|
||||
}
|
||||
|
||||
@ -2198,7 +2200,7 @@ bool MainWidget::viewsIncrementFail(const RPCError &error, mtpRequestId req) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void MainWidget::createDialog(History *history) {
|
||||
void MainWidget::createDialog(not_null<History*> history) {
|
||||
_dialogs->createDialog(history);
|
||||
}
|
||||
|
||||
@ -2307,15 +2309,12 @@ void MainWidget::ui_showPeerHistory(
|
||||
|
||||
auto animationParams = animatedShow() ? prepareHistoryAnimation(peerId) : Window::SectionSlideParams();
|
||||
|
||||
dlgUpdated();
|
||||
if (back || (way == Way::ClearStack)) {
|
||||
_peerInStack = nullptr;
|
||||
_msgIdInStack = 0;
|
||||
clearEntryInStack();
|
||||
} else {
|
||||
// This may modify the current section, for example remove its contents.
|
||||
saveSectionInStack();
|
||||
}
|
||||
dlgUpdated();
|
||||
|
||||
if (_history->peer() && _history->peer()->id != peerId && way != Way::Forward) {
|
||||
clearBotStartToken(_history->peer());
|
||||
@ -2371,7 +2370,9 @@ void MainWidget::ui_showPeerHistory(
|
||||
|
||||
if (!_dialogs->isHidden()) {
|
||||
if (!back) {
|
||||
_dialogs->scrollToPeer(peerId, showAtMsgId);
|
||||
if (const auto history = _history->history()) {
|
||||
_dialogs->scrollToPeer(history, showAtMsgId);
|
||||
}
|
||||
}
|
||||
_dialogs->update();
|
||||
}
|
||||
@ -2387,22 +2388,20 @@ PeerData *MainWidget::ui_getPeerForMouseAction() {
|
||||
return _history->ui_getPeerForMouseAction();
|
||||
}
|
||||
|
||||
void MainWidget::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) {
|
||||
Dialogs::RowDescriptor MainWidget::chatListEntryBefore(
|
||||
const Dialogs::RowDescriptor &which) const {
|
||||
if (selectingPeer()) {
|
||||
outPeer = 0;
|
||||
outMsg = 0;
|
||||
return;
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
_dialogs->peerBefore(inPeer, inMsg, outPeer, outMsg);
|
||||
return _dialogs->chatListEntryBefore(which);
|
||||
}
|
||||
|
||||
void MainWidget::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) {
|
||||
Dialogs::RowDescriptor MainWidget::chatListEntryAfter(
|
||||
const Dialogs::RowDescriptor &which) const {
|
||||
if (selectingPeer()) {
|
||||
outPeer = 0;
|
||||
outMsg = 0;
|
||||
return;
|
||||
return Dialogs::RowDescriptor();
|
||||
}
|
||||
_dialogs->peerAfter(inPeer, inMsg, outPeer, outMsg);
|
||||
return _dialogs->chatListEntryAfter(which);
|
||||
}
|
||||
|
||||
PeerData *MainWidget::peer() {
|
||||
@ -2410,13 +2409,33 @@ PeerData *MainWidget::peer() {
|
||||
}
|
||||
|
||||
PeerData *MainWidget::activePeer() {
|
||||
return _history->peer() ? _history->peer() : _peerInStack;
|
||||
if (const auto history = _history->history()) {
|
||||
return history->peer;
|
||||
} else if (_historyInStack) {
|
||||
return _historyInStack->peer;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MsgId MainWidget::activeMsgId() {
|
||||
return _history->peer() ? _history->msgId() : _msgIdInStack;
|
||||
}
|
||||
|
||||
void MainWidget::setEntryInStack(not_null<History*> history, MsgId msgId) {
|
||||
setEntryInStackValues(history, msgId);
|
||||
}
|
||||
|
||||
void MainWidget::clearEntryInStack() {
|
||||
setEntryInStackValues(nullptr, 0);
|
||||
}
|
||||
|
||||
void MainWidget::setEntryInStackValues(History *history, MsgId msgId) {
|
||||
updateCurrentChatListEntry();
|
||||
_historyInStack = history;
|
||||
_msgIdInStack = msgId;
|
||||
updateCurrentChatListEntry();
|
||||
}
|
||||
|
||||
void MainWidget::saveSectionInStack() {
|
||||
if (_mainSection) {
|
||||
if (auto memento = _mainSection->createMemento()) {
|
||||
@ -2424,11 +2443,10 @@ void MainWidget::saveSectionInStack() {
|
||||
std::move(memento)));
|
||||
_stack.back()->setThirdSectionWeak(_thirdSection.data());
|
||||
}
|
||||
} else if (_history->peer()) {
|
||||
_peerInStack = _history->peer();
|
||||
_msgIdInStack = _history->msgId();
|
||||
} else if (const auto history = _history->history()) {
|
||||
setEntryInStack(history, _history->msgId());
|
||||
_stack.push_back(std::make_unique<StackItemHistory>(
|
||||
_peerInStack,
|
||||
_historyInStack,
|
||||
_msgIdInStack,
|
||||
_history->replyReturns()));
|
||||
_stack.back()->setThirdSectionWeak(_thirdSection.data());
|
||||
@ -2765,15 +2783,11 @@ void MainWidget::showBackFromStack(
|
||||
}
|
||||
_thirdSectionFromStack = item->takeThirdSectionMemento();
|
||||
if (item->type() == HistoryStackItem) {
|
||||
dlgUpdated();
|
||||
_peerInStack = nullptr;
|
||||
_msgIdInStack = 0;
|
||||
clearEntryInStack();
|
||||
for (auto i = _stack.size(); i > 0;) {
|
||||
if (_stack[--i]->type() == HistoryStackItem) {
|
||||
auto historyItem = static_cast<StackItemHistory*>(_stack[i].get());
|
||||
_peerInStack = historyItem->peer();
|
||||
_msgIdInStack = historyItem->msgId;
|
||||
dlgUpdated();
|
||||
setEntryInStack(historyItem->history, historyItem->msgId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2899,24 +2913,29 @@ QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams ¶m
|
||||
return result;
|
||||
}
|
||||
|
||||
void MainWidget::dlgUpdated() {
|
||||
if (_peerInStack) {
|
||||
_dialogs->dlgUpdated(_peerInStack, _msgIdInStack);
|
||||
void MainWidget::updateCurrentChatListEntry() {
|
||||
if (_historyInStack) {
|
||||
_dialogs->dlgUpdated(_historyInStack, _msgIdInStack);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) {
|
||||
void MainWidget::dlgUpdated(
|
||||
Dialogs::Mode list,
|
||||
not_null<Dialogs::Row*> row) {
|
||||
if (row) {
|
||||
_dialogs->dlgUpdated(list, row);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::dlgUpdated(PeerData *peer, MsgId msgId) {
|
||||
if (!peer) return;
|
||||
if (msgId < 0 && -msgId < ServerMaxMsgId && peer->migrateFrom()) {
|
||||
_dialogs->dlgUpdated(peer->migrateFrom(), -msgId);
|
||||
void MainWidget::dlgUpdated(not_null<History*> history, MsgId msgId) {
|
||||
if (msgId < 0 && -msgId < ServerMaxMsgId) {
|
||||
if (const auto from = history->peer->migrateFrom()) {
|
||||
if (const auto migrated = App::historyLoaded(from)) {
|
||||
_dialogs->dlgUpdated(migrated, -msgId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_dialogs->dlgUpdated(peer, msgId);
|
||||
_dialogs->dlgUpdated(history, msgId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3539,7 +3558,9 @@ int MainWidget::backgroundFromY() const {
|
||||
|
||||
void MainWidget::onHistoryShown(History *history, MsgId atMsgId) {
|
||||
// updateControlsGeometry();
|
||||
dlgUpdated(history ? history->peer : nullptr, atMsgId);
|
||||
if (history) {
|
||||
dlgUpdated(history, atMsgId);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::searchInPeer(PeerData *peer) {
|
||||
|
@ -25,6 +25,7 @@ struct PeerUpdate;
|
||||
} // namespace Notify
|
||||
|
||||
namespace Dialogs {
|
||||
struct RowDescriptor;
|
||||
class Row;
|
||||
} // namespace Dialogs
|
||||
|
||||
@ -105,11 +106,10 @@ public:
|
||||
|
||||
void activate();
|
||||
|
||||
void createDialog(History *history);
|
||||
void removeDialog(History *history);
|
||||
void dlgUpdated();
|
||||
void dlgUpdated(Dialogs::Mode list, Dialogs::Row *row);
|
||||
void dlgUpdated(PeerData *peer, MsgId msgId);
|
||||
void createDialog(not_null<History*> history);
|
||||
void removeDialog(not_null<History*> history);
|
||||
void dlgUpdated(Dialogs::Mode list, not_null<Dialogs::Row*> row);
|
||||
void dlgUpdated(not_null<History*> history, MsgId msgId);
|
||||
|
||||
void windowShown();
|
||||
|
||||
@ -126,10 +126,12 @@ public:
|
||||
void newUnreadMsg(History *history, HistoryItem *item);
|
||||
void markActiveHistoryAsRead();
|
||||
|
||||
void peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg);
|
||||
void peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg);
|
||||
PeerData *peer();
|
||||
Dialogs::RowDescriptor chatListEntryBefore(
|
||||
const Dialogs::RowDescriptor &which) const;
|
||||
Dialogs::RowDescriptor chatListEntryAfter(
|
||||
const Dialogs::RowDescriptor &which) const;
|
||||
|
||||
PeerData *peer();
|
||||
PeerData *activePeer();
|
||||
MsgId activeMsgId();
|
||||
|
||||
@ -438,6 +440,11 @@ private:
|
||||
void closeBothPlayers();
|
||||
void playerHeightUpdated();
|
||||
|
||||
void updateCurrentChatListEntry();
|
||||
void setEntryInStack(not_null<History*> history, MsgId msgId);
|
||||
void clearEntryInStack();
|
||||
void setEntryInStackValues(History *history, MsgId msgId);
|
||||
|
||||
void setCurrentCall(Calls::Call *call);
|
||||
void createCallTopBar();
|
||||
void destroyCallTopBar();
|
||||
@ -581,7 +588,7 @@ private:
|
||||
QPointer<ConfirmBox> _forwardConfirm; // for single column layout
|
||||
object_ptr<HistoryHider> _hider = { nullptr };
|
||||
std::vector<std::unique_ptr<StackItem>> _stack;
|
||||
PeerData *_peerInStack = nullptr;
|
||||
History *_historyInStack = nullptr;
|
||||
MsgId _msgIdInStack = 0;
|
||||
|
||||
int _playerHeight = 0;
|
||||
|
@ -1935,6 +1935,7 @@ void AddParticipantBoxSearchController::addChatsContacts() {
|
||||
}
|
||||
|
||||
for_const (auto row, *list) {
|
||||
// #TODO feeds list
|
||||
if (auto user = row->history()->peer->asUser()) {
|
||||
if (allWordsAreFound(user->nameWords())) {
|
||||
delegate()->peerListSearchAddRow(user);
|
||||
|
Loading…
Reference in New Issue
Block a user