mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 10:11:41 -05:00
Encapsulated unreadCount and mute fields in History.
Support for hiding all muted chats from the list.
This commit is contained in:
parent
03bbb2269d
commit
e0d6a68554
26 changed files with 1323 additions and 962 deletions
|
@ -886,6 +886,8 @@ dlgPaddingVer: 8px;
|
||||||
dlgHeight: 62px;
|
dlgHeight: 62px;
|
||||||
dlgPhotoPadding: 12px;
|
dlgPhotoPadding: 12px;
|
||||||
|
|
||||||
|
dlgImportantHeight: 37px;
|
||||||
|
|
||||||
noContactsHeight: 100px;
|
noContactsHeight: 100px;
|
||||||
noContactsFont: font(fsize);
|
noContactsFont: font(fsize);
|
||||||
noContactsColor: #777;
|
noContactsColor: #777;
|
||||||
|
|
|
@ -245,7 +245,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
||||||
if (!h->isEmpty()) {
|
if (!h->isEmpty()) {
|
||||||
h->clear(true);
|
h->clear(true);
|
||||||
}
|
}
|
||||||
if (hto->inChatList() && h->inChatList()) {
|
if (hto->inChatList(Dialogs::Mode::All) && h->inChatList(Dialogs::Mode::All)) {
|
||||||
App::removeDialog(h);
|
App::removeDialog(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -557,7 +557,7 @@ namespace {
|
||||||
if (!h->isEmpty()) {
|
if (!h->isEmpty()) {
|
||||||
h->clear(true);
|
h->clear(true);
|
||||||
}
|
}
|
||||||
if (hto->inChatList() && h->inChatList()) {
|
if (hto->inChatList(Dialogs::Mode::All) && h->inChatList(Dialogs::Mode::All)) {
|
||||||
App::removeDialog(h);
|
App::removeDialog(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1137,8 +1137,8 @@ namespace {
|
||||||
} else {
|
} else {
|
||||||
if (channelHistory) {
|
if (channelHistory) {
|
||||||
channelHistory->messageWithIdDeleted(i->v);
|
channelHistory->messageWithIdDeleted(i->v);
|
||||||
if (channelHistory->unreadCount > 0 && i->v >= channelHistory->inboxReadBefore) {
|
if (channelHistory->unreadCount() > 0 && i->v >= channelHistory->inboxReadBefore) {
|
||||||
channelHistory->setUnreadCount(channelHistory->unreadCount - 1);
|
channelHistory->setUnreadCount(channelHistory->unreadCount() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -962,6 +962,15 @@ void AppClass::onSwitchDebugMode() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AppClass::onSwitchWorkMode() {
|
||||||
|
Global::SetDialogsModeEnabled(!Global::DialogsModeEnabled());
|
||||||
|
Global::SetDialogsMode(Dialogs::Mode::All);
|
||||||
|
Local::writeUserSettings();
|
||||||
|
cSetRestarting(true);
|
||||||
|
cSetRestartingToSettings(true);
|
||||||
|
App::quit();
|
||||||
|
}
|
||||||
|
|
||||||
void AppClass::onSwitchTestMode() {
|
void AppClass::onSwitchTestMode() {
|
||||||
if (cTestMode()) {
|
if (cTestMode()) {
|
||||||
QFile(cWorkingDir() + qsl("tdata/withtestmode")).remove();
|
QFile(cWorkingDir() + qsl("tdata/withtestmode")).remove();
|
||||||
|
|
|
@ -195,6 +195,7 @@ public slots:
|
||||||
void photoUpdated(const FullMsgId &msgId, bool silent, const MTPInputFile &file);
|
void photoUpdated(const FullMsgId &msgId, bool silent, const MTPInputFile &file);
|
||||||
|
|
||||||
void onSwitchDebugMode();
|
void onSwitchDebugMode();
|
||||||
|
void onSwitchWorkMode();
|
||||||
void onSwitchTestMode();
|
void onSwitchTestMode();
|
||||||
|
|
||||||
void killDownloadSessions();
|
void killDownloadSessions();
|
||||||
|
|
|
@ -26,9 +26,14 @@ class Row;
|
||||||
using RowsByLetter = QMap<QChar, Row*>;
|
using RowsByLetter = QMap<QChar, Row*>;
|
||||||
|
|
||||||
enum class SortMode {
|
enum class SortMode {
|
||||||
Date,
|
Date = 0x00,
|
||||||
Name,
|
Name = 0x01,
|
||||||
Add
|
Add = 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Mode {
|
||||||
|
All = 0x00,
|
||||||
|
Important = 0x01,
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Dialogs
|
} // namespace Dialogs
|
||||||
|
|
|
@ -71,9 +71,21 @@ void IndexedList::adjustByPos(const RowsByLetter &links) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void IndexedList::peerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars) {
|
void IndexedList::peerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars) {
|
||||||
|
t_assert(_sortMode != SortMode::Date);
|
||||||
if (_sortMode == SortMode::Name) {
|
if (_sortMode == SortMode::Name) {
|
||||||
|
adjustByName(peer, oldNames, oldChars);
|
||||||
|
} else {
|
||||||
|
adjustNames(Dialogs::Mode::All, peer, oldNames, oldChars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IndexedList::peerNameChanged(Mode list, PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars) {
|
||||||
|
t_assert(_sortMode == SortMode::Date);
|
||||||
|
adjustNames(list, peer, oldNames, oldChars);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IndexedList::adjustByName(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars) {
|
||||||
Row *mainRow = _list.adjustByName(peer);
|
Row *mainRow = _list.adjustByName(peer);
|
||||||
if (!mainRow) return;
|
if (!mainRow) return;
|
||||||
|
|
||||||
|
@ -105,7 +117,9 @@ void IndexedList::peerNameChanged(PeerData *peer, const PeerData::Names &oldName
|
||||||
j.value()->addByName(history);
|
j.value()->addByName(history);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
void IndexedList::adjustNames(Mode list, PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars) {
|
||||||
auto mainRow = _list.getRow(peer->id);
|
auto mainRow = _list.getRow(peer->id);
|
||||||
if (!mainRow) return;
|
if (!mainRow) return;
|
||||||
|
|
||||||
|
@ -122,7 +136,7 @@ void IndexedList::peerNameChanged(PeerData *peer, const PeerData::Names &oldName
|
||||||
}
|
}
|
||||||
for_const (auto ch, toRemove) {
|
for_const (auto ch, toRemove) {
|
||||||
if (_sortMode == SortMode::Date) {
|
if (_sortMode == SortMode::Date) {
|
||||||
history->removeChatListEntryByLetter(ch);
|
history->removeChatListEntryByLetter(list, ch);
|
||||||
}
|
}
|
||||||
if (auto list = _index.value(ch)) {
|
if (auto list = _index.value(ch)) {
|
||||||
list->del(peer->id, mainRow);
|
list->del(peer->id, mainRow);
|
||||||
|
@ -135,8 +149,7 @@ void IndexedList::peerNameChanged(PeerData *peer, const PeerData::Names &oldName
|
||||||
}
|
}
|
||||||
Row *row = j.value()->addToEnd(history);
|
Row *row = j.value()->addToEnd(history);
|
||||||
if (_sortMode == SortMode::Date) {
|
if (_sortMode == SortMode::Date) {
|
||||||
history->addChatListEntryByLetter(ch, row);
|
history->addChatListEntryByLetter(list, ch, row);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,13 @@ public:
|
||||||
RowsByLetter addToEnd(History *history);
|
RowsByLetter addToEnd(History *history);
|
||||||
Row *addByName(History *history);
|
Row *addByName(History *history);
|
||||||
void adjustByPos(const RowsByLetter &links);
|
void adjustByPos(const RowsByLetter &links);
|
||||||
|
|
||||||
|
// For sortMode != SortMode::Date
|
||||||
void peerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars);
|
void peerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars);
|
||||||
|
|
||||||
|
//For sortMode == SortMode::Date
|
||||||
|
void peerNameChanged(Mode list, PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars);
|
||||||
|
|
||||||
void del(const PeerData *peer, Row *replacedBy = nullptr);
|
void del(const PeerData *peer, Row *replacedBy = nullptr);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
@ -71,6 +77,9 @@ public:
|
||||||
iterator find(int y, int h) { return all().find(y, h); }
|
iterator find(int y, int h) { return all().find(y, h); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void adjustByName(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars);
|
||||||
|
void adjustNames(Mode list, PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars);
|
||||||
|
|
||||||
SortMode _sortMode;
|
SortMode _sortMode;
|
||||||
List _list;
|
List _list;
|
||||||
using Index = QMap<QChar, List*>;
|
using Index = QMap<QChar, List*>;
|
||||||
|
|
|
@ -170,41 +170,48 @@ void paintUnreadBadge(Painter &p, const QRect &rect, bool active, bool muted) {
|
||||||
p.drawPixmap(rect.x() + sizehalf + bar, rect.y(), unreadBadgeStyle->right[index]);
|
p.drawPixmap(rect.x() + sizehalf + bar, rect.y(), unreadBadgeStyle->right[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void paintUnreadCount(Painter &p, const QString &text, int top, int w, bool active, bool muted, int *outAvailableWidth) {
|
||||||
|
int unreadWidth = st::dlgUnreadFont->width(text);
|
||||||
|
int unreadRectWidth = unreadWidth + 2 * st::dlgUnreadPaddingHor;
|
||||||
|
int unreadRectHeight = st::dlgUnreadHeight;
|
||||||
|
accumulate_max(unreadRectWidth, unreadRectHeight);
|
||||||
|
|
||||||
|
int unreadRectLeft = w - st::dlgPaddingHor - unreadRectWidth;
|
||||||
|
int unreadRectTop =top;
|
||||||
|
if (outAvailableWidth) {
|
||||||
|
*outAvailableWidth -= unreadRectWidth + st::dlgUnreadPaddingHor;
|
||||||
|
}
|
||||||
|
|
||||||
|
paintUnreadBadge(p, QRect(unreadRectLeft, unreadRectTop, unreadRectWidth, unreadRectHeight), active, muted);
|
||||||
|
|
||||||
|
p.setFont(st::dlgUnreadFont);
|
||||||
|
p.setPen(active ? st::dlgActiveUnreadColor : st::dlgUnreadColor);
|
||||||
|
p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + st::dlgUnreadTop + st::dlgUnreadFont->ascent, text);
|
||||||
|
}
|
||||||
|
|
||||||
} // namepsace
|
} // namepsace
|
||||||
|
|
||||||
void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool selected, bool onlyBackground) {
|
void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool selected, bool onlyBackground) {
|
||||||
auto history = row->history();
|
auto history = row->history();
|
||||||
auto item = history->lastMsg;
|
auto item = history->lastMsg;
|
||||||
paintRow(p, history, item, w, active, selected, onlyBackground, [&p, w, active, history, item](int nameleft, int namewidth) {
|
paintRow(p, history, item, w, active, selected, onlyBackground, [&p, w, active, history, item](int nameleft, int namewidth) {
|
||||||
int32 lastWidth = namewidth, unread = history->unreadCount;
|
int32 unread = history->unreadCount();
|
||||||
if (history->peer->migrateFrom()) {
|
if (history->peer->migrateFrom()) {
|
||||||
if (History *h = App::historyLoaded(history->peer->migrateFrom()->id)) {
|
if (History *h = App::historyLoaded(history->peer->migrateFrom()->id)) {
|
||||||
unread += h->unreadCount;
|
unread += h->unreadCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int availableWidth = namewidth;
|
||||||
int texttop = st::dlgPaddingVer + st::dlgFont->height + st::dlgSep;
|
int texttop = st::dlgPaddingVer + st::dlgFont->height + st::dlgSep;
|
||||||
if (unread) {
|
if (unread) {
|
||||||
QString unreadStr = QString::number(unread);
|
int unreadTop = texttop + st::dlgHistFont->ascent - st::dlgUnreadFont->ascent - st::dlgUnreadTop;
|
||||||
int unreadWidth = st::dlgUnreadFont->width(unreadStr);
|
paintUnreadCount(p, QString::number(unread), unreadTop, w, active, history->mute(), &availableWidth);
|
||||||
int unreadRectWidth = unreadWidth + 2 * st::dlgUnreadPaddingHor;
|
|
||||||
int unreadRectHeight = st::dlgUnreadHeight;
|
|
||||||
accumulate_max(unreadRectWidth, unreadRectHeight);
|
|
||||||
|
|
||||||
int unreadRectLeft = w - st::dlgPaddingHor - unreadRectWidth;
|
|
||||||
int unreadRectTop = texttop + st::dlgHistFont->ascent - st::dlgUnreadFont->ascent - st::dlgUnreadTop;
|
|
||||||
lastWidth -= unreadRectWidth + st::dlgUnreadPaddingHor;
|
|
||||||
|
|
||||||
paintUnreadBadge(p, QRect(unreadRectLeft, unreadRectTop, unreadRectWidth, unreadRectHeight), active, history->mute);
|
|
||||||
|
|
||||||
p.setFont(st::dlgUnreadFont);
|
|
||||||
p.setPen(active ? st::dlgActiveUnreadColor : st::dlgUnreadColor);
|
|
||||||
p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + st::dlgUnreadTop + st::dlgUnreadFont->ascent, unreadStr);
|
|
||||||
}
|
}
|
||||||
if (history->typing.isEmpty() && history->sendActions.isEmpty()) {
|
if (history->typing.isEmpty() && history->sendActions.isEmpty()) {
|
||||||
item->drawInDialog(p, QRect(nameleft, texttop, lastWidth, st::dlgFont->height), active, history->textCachedFor, history->lastItemTextCache);
|
item->drawInDialog(p, QRect(nameleft, texttop, availableWidth, st::dlgFont->height), active, history->textCachedFor, history->lastItemTextCache);
|
||||||
} else {
|
} else {
|
||||||
p.setPen(active ? st::dlgActiveColor : st::dlgSystemColor);
|
p.setPen(active ? st::dlgActiveColor : st::dlgSystemColor);
|
||||||
history->typingText.drawElided(p, nameleft, texttop, lastWidth);
|
history->typingText.drawElided(p, nameleft, texttop, availableWidth);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -218,6 +225,28 @@ void RowPainter::paint(Painter &p, const FakeRow *row, int w, bool active, bool
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool onlyBackground) {
|
||||||
|
p.fillRect(0, 0, w, st::dlgImportantHeight, selected ? st::dlgHoverBG : st::white);
|
||||||
|
if (onlyBackground) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.setFont(st::semiboldFont);
|
||||||
|
p.setPen(st::black);
|
||||||
|
|
||||||
|
int unreadTop = (st::dlgImportantHeight - st::dlgUnreadHeight) / 2;
|
||||||
|
bool mutedHidden = (current == Dialogs::Mode::Important);
|
||||||
|
QString text = mutedHidden ? qsl("Show all chats") : qsl("Hide muted chats");
|
||||||
|
int textBaseline = unreadTop + st::dlgUnreadTop + st::dlgUnreadFont->ascent;
|
||||||
|
p.drawText(st::dlgPaddingHor, textBaseline, text);
|
||||||
|
|
||||||
|
if (mutedHidden) {
|
||||||
|
if (int32 unread = App::histories().unreadMutedCount()) {
|
||||||
|
paintUnreadCount(p, QString::number(unread), unreadTop, w, false, true, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using StyleSheets = OrderedSet<StyleSheet**>;
|
using StyleSheets = OrderedSet<StyleSheet**>;
|
||||||
|
|
|
@ -33,6 +33,8 @@ public:
|
||||||
static void paint(Painter &p, const FakeRow *row, int w, bool active, bool selected, bool onlyBackground);
|
static void paint(Painter &p, const FakeRow *row, int w, bool active, bool selected, bool onlyBackground);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool onlyBackground);
|
||||||
|
|
||||||
// This will be moved somewhere outside as soon as anyone starts using that.
|
// This will be moved somewhere outside as soon as anyone starts using that.
|
||||||
class StyleSheet {
|
class StyleSheet {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -40,6 +40,9 @@ DialogsInner::DialogsInner(QWidget *parent, MainWidget *main) : SplittedWidget(p
|
||||||
, contacts(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
, contacts(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
||||||
, _addContactLnk(this, lang(lng_add_contact_button))
|
, _addContactLnk(this, lang(lng_add_contact_button))
|
||||||
, _cancelSearchInPeer(this, st::btnCancelSearch) {
|
, _cancelSearchInPeer(this, st::btnCancelSearch) {
|
||||||
|
if (Global::DialogsModeEnabled()) {
|
||||||
|
importantDialogs = std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Date);
|
||||||
|
}
|
||||||
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
||||||
connect(main, SIGNAL(peerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)));
|
connect(main, SIGNAL(peerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)));
|
||||||
connect(main, SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(onPeerPhotoChanged(PeerData*)));
|
connect(main, SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(onPeerPhotoChanged(PeerData*)));
|
||||||
|
@ -50,16 +53,20 @@ DialogsInner::DialogsInner(QWidget *parent, MainWidget *main) : SplittedWidget(p
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 DialogsInner::filteredOffset() const {
|
int DialogsInner::dialogsOffset() const {
|
||||||
|
return importantDialogs ? st::dlgImportantHeight : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DialogsInner::filteredOffset() const {
|
||||||
return _hashtagResults.size() * st::mentionHeight;
|
return _hashtagResults.size() * st::mentionHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 DialogsInner::peopleOffset() const {
|
int DialogsInner::peopleOffset() const {
|
||||||
return filteredOffset() + (_filterResults.size() * st::dlgHeight) + st::searchedBarHeight;
|
return filteredOffset() + (_filterResults.size() * st::dlgHeight) + st::searchedBarHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 DialogsInner::searchedOffset() const {
|
int DialogsInner::searchedOffset() const {
|
||||||
int32 result = peopleOffset() + (_peopleResults.isEmpty() ? 0 : ((_peopleResults.size() * st::dlgHeight) + st::searchedBarHeight));
|
int result = peopleOffset() + (_peopleResults.isEmpty() ? 0 : ((_peopleResults.size() * st::dlgHeight) + st::searchedBarHeight));
|
||||||
if (_searchInPeer) result += st::dlgHeight;
|
if (_searchInPeer) result += st::dlgHeight;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -76,16 +83,22 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
int32 otherStart = dialogs->size() * st::dlgHeight;
|
QRect dialogsClip = r;
|
||||||
PeerData *active = App::main()->activePeer(), *selected = _menuPeer ? _menuPeer : (sel ? sel->history()->peer : 0);
|
if (importantDialogs) {
|
||||||
|
Dialogs::Layout::paintImportantSwitch(p, Global::DialogsMode(), fullWidth(), _importantSwitchSel, paintingOther);
|
||||||
|
dialogsClip.translate(0, -st::dlgImportantHeight);
|
||||||
|
p.translate(0, st::dlgImportantHeight);
|
||||||
|
}
|
||||||
|
int32 otherStart = shownDialogs()->size() * st::dlgHeight;
|
||||||
|
PeerData *active = App::main()->activePeer(), *selected = _menuPeer ? _menuPeer : (_sel ? _sel->history()->peer : 0);
|
||||||
if (otherStart) {
|
if (otherStart) {
|
||||||
dialogs->all().paint(p, fullWidth(), r.top(), r.top() + r.height(), active, selected, paintingOther);
|
shownDialogs()->all().paint(p, fullWidth(), dialogsClip.top(), dialogsClip.top() + dialogsClip.height(), active, selected, paintingOther);
|
||||||
}
|
}
|
||||||
if (!otherStart) {
|
if (!otherStart) {
|
||||||
p.fillRect(r, st::white->b);
|
p.fillRect(dialogsClip, st::white);
|
||||||
if (!paintingOther) {
|
if (!paintingOther) {
|
||||||
p.setFont(st::noContactsFont->f);
|
p.setFont(st::noContactsFont);
|
||||||
p.setPen(st::noContactsColor->p);
|
p.setPen(st::noContactsColor);
|
||||||
p.drawText(QRect(0, 0, fullWidth(), st::noContactsHeight - (cContactsReceived() ? st::noContactsFont->height : 0)), lang(cContactsReceived() ? lng_no_chats : lng_contacts_loading), style::al_center);
|
p.drawText(QRect(0, 0, fullWidth(), st::noContactsHeight - (cContactsReceived() ? st::noContactsFont->height : 0)), lang(cContactsReceived() ? lng_no_chats : lng_contacts_loading), style::al_center);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,13 +236,11 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const {
|
void DialogsInner::peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool active, bool selected, bool onlyBackground) const {
|
||||||
QRect fullRect(0, 0, w, st::dlgHeight);
|
QRect fullRect(0, 0, w, st::dlgHeight);
|
||||||
p.fillRect(fullRect, (act ? st::dlgActiveBG : (sel ? st::dlgHoverBG : st::dlgBG))->b);
|
p.fillRect(fullRect, active ? st::dlgActiveBG : (selected ? st::dlgHoverBG : st::dlgBG));
|
||||||
if (onlyBackground) return;
|
if (onlyBackground) return;
|
||||||
|
|
||||||
History *history = App::history(peer->id);
|
|
||||||
|
|
||||||
PeerData *userpicPeer = (peer->migrateTo() ? peer->migrateTo() : peer);
|
PeerData *userpicPeer = (peer->migrateTo() ? peer->migrateTo() : peer);
|
||||||
userpicPeer->paintUserpicLeft(p, st::dlgPhotoSize, st::dlgPaddingHor, st::dlgPaddingVer, fullWidth());
|
userpicPeer->paintUserpicLeft(p, st::dlgPhotoSize, st::dlgPaddingHor, st::dlgPaddingVer, fullWidth());
|
||||||
|
|
||||||
|
@ -239,21 +250,21 @@ void DialogsInner::peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool a
|
||||||
|
|
||||||
// draw chat icon
|
// draw chat icon
|
||||||
if (peer->isChat() || peer->isMegagroup()) {
|
if (peer->isChat() || peer->isMegagroup()) {
|
||||||
p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgPos.x(), rectForName.top() + st::dlgChatImgPos.y()), App::sprite(), (act ? st::dlgActiveChatImg : st::dlgChatImg));
|
p.drawSprite(QPoint(rectForName.left() + st::dlgChatImgPos.x(), rectForName.top() + st::dlgChatImgPos.y()), (active ? st::dlgActiveChatImg : st::dlgChatImg));
|
||||||
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
||||||
} else if (peer->isChannel()) {
|
} else if (peer->isChannel()) {
|
||||||
p.drawPixmap(QPoint(rectForName.left() + st::dlgChannelImgPos.x(), rectForName.top() + st::dlgChannelImgPos.y()), App::sprite(), (act ? st::dlgActiveChannelImg : st::dlgChannelImg));
|
p.drawSprite(QPoint(rectForName.left() + st::dlgChannelImgPos.x(), rectForName.top() + st::dlgChannelImgPos.y()), (active ? st::dlgActiveChannelImg : st::dlgChannelImg));
|
||||||
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
||||||
}
|
}
|
||||||
if (peer->isVerified()) {
|
if (peer->isVerified()) {
|
||||||
rectForName.setWidth(rectForName.width() - st::verifiedCheck.pxWidth() - st::verifiedCheckPos.x());
|
rectForName.setWidth(rectForName.width() - st::verifiedCheck.pxWidth() - st::verifiedCheckPos.x());
|
||||||
p.drawSprite(rectForName.topLeft() + QPoint(qMin(peer->dialogName().maxWidth(), rectForName.width()), 0) + st::verifiedCheckPos, (act ? st::verifiedCheckInv : st::verifiedCheck));
|
p.drawSprite(rectForName.topLeft() + QPoint(qMin(peer->dialogName().maxWidth(), rectForName.width()), 0) + st::verifiedCheckPos, (active ? st::verifiedCheckInv : st::verifiedCheck));
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect tr(nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgSep, namewidth, st::dlgFont->height);
|
QRect tr(nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgSep, namewidth, st::dlgFont->height);
|
||||||
p.setFont(st::dlgHistFont->f);
|
p.setFont(st::dlgHistFont->f);
|
||||||
QString username = peer->userName();
|
QString username = peer->userName();
|
||||||
if (!act && username.toLower().startsWith(_peopleQuery)) {
|
if (!active && username.toLower().startsWith(_peopleQuery)) {
|
||||||
QString first = '@' + username.mid(0, _peopleQuery.size()), second = username.mid(_peopleQuery.size());
|
QString first = '@' + username.mid(0, _peopleQuery.size()), second = username.mid(_peopleQuery.size());
|
||||||
int32 w = st::dlgHistFont->width(first);
|
int32 w = st::dlgHistFont->width(first);
|
||||||
if (w >= tr.width()) {
|
if (w >= tr.width()) {
|
||||||
|
@ -266,11 +277,11 @@ void DialogsInner::peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool a
|
||||||
p.drawText(tr.left() + w, tr.top() + st::dlgHistFont->ascent, st::dlgHistFont->elided(second, tr.width() - w));
|
p.drawText(tr.left() + w, tr.top() + st::dlgHistFont->ascent, st::dlgHistFont->elided(second, tr.width() - w));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p.setPen((act ? st::dlgActiveColor : st::dlgSystemColor)->p);
|
p.setPen((active ? st::dlgActiveColor : st::dlgSystemColor)->p);
|
||||||
p.drawText(tr.left(), tr.top() + st::dlgHistFont->ascent, st::dlgHistFont->elided('@' + username, tr.width()));
|
p.drawText(tr.left(), tr.top() + st::dlgHistFont->ascent, st::dlgHistFont->elided('@' + username, tr.width()));
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setPen((act ? st::dlgActiveColor : st::dlgNameColor)->p);
|
p.setPen((active ? st::dlgActiveColor : st::dlgNameColor)->p);
|
||||||
peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
|
peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,24 +319,26 @@ void DialogsInner::activate() {
|
||||||
|
|
||||||
void DialogsInner::mouseMoveEvent(QMouseEvent *e) {
|
void DialogsInner::mouseMoveEvent(QMouseEvent *e) {
|
||||||
lastMousePos = mapToGlobal(e->pos());
|
lastMousePos = mapToGlobal(e->pos());
|
||||||
selByMouse = true;
|
_selByMouse = true;
|
||||||
onUpdateSelected(true);
|
onUpdateSelected(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::onUpdateSelected(bool force) {
|
void DialogsInner::onUpdateSelected(bool force) {
|
||||||
QPoint mouse(mapFromGlobal(lastMousePos));
|
QPoint mouse(mapFromGlobal(lastMousePos));
|
||||||
if ((!force && !rect().contains(mouse)) || !selByMouse) return;
|
if ((!force && !rect().contains(mouse)) || !_selByMouse) return;
|
||||||
|
|
||||||
int w = width(), mouseY = mouse.y();
|
int w = width(), mouseY = mouse.y();
|
||||||
_overDelete = false;
|
_overDelete = false;
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
auto newSel = dialogs->rowAtY(mouseY, st::dlgHeight);
|
auto newImportantSwitchSel = (importantDialogs && mouseY >= 0 && mouseY < dialogsOffset());
|
||||||
int otherStart = dialogs->size() * st::dlgHeight;
|
mouseY -= dialogsOffset();
|
||||||
if (newSel != sel) {
|
auto newSel = newImportantSwitchSel ? nullptr : shownDialogs()->rowAtY(mouseY, st::dlgHeight);
|
||||||
|
if (newSel != _sel || newImportantSwitchSel != _importantSwitchSel) {
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
sel = newSel;
|
_sel = newSel;
|
||||||
|
_importantSwitchSel = newImportantSwitchSel;
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
setCursor(sel ? style::cur_pointer : style::cur_default);
|
setCursor(_sel ? style::cur_pointer : style::cur_default);
|
||||||
}
|
}
|
||||||
} else if (_state == FilteredState || _state == SearchedState) {
|
} else if (_state == FilteredState || _state == SearchedState) {
|
||||||
if (!_hashtagResults.isEmpty()) {
|
if (!_hashtagResults.isEmpty()) {
|
||||||
|
@ -384,7 +397,7 @@ void DialogsInner::onUpdateSelected(bool force) {
|
||||||
|
|
||||||
void DialogsInner::mousePressEvent(QMouseEvent *e) {
|
void DialogsInner::mousePressEvent(QMouseEvent *e) {
|
||||||
lastMousePos = mapToGlobal(e->pos());
|
lastMousePos = mapToGlobal(e->pos());
|
||||||
selByMouse = true;
|
_selByMouse = true;
|
||||||
onUpdateSelected(true);
|
onUpdateSelected(true);
|
||||||
if (e->button() == Qt::LeftButton) {
|
if (e->button() == Qt::LeftButton) {
|
||||||
choosePeer();
|
choosePeer();
|
||||||
|
@ -411,25 +424,46 @@ void DialogsInner::onDialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sel == oldRow) {
|
if (_sel == oldRow) {
|
||||||
sel = newRow;
|
_sel = newRow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::createDialog(History *history) {
|
void DialogsInner::createDialog(History *history) {
|
||||||
bool creating = !history->inChatList();
|
bool creating = !history->inChatList(Dialogs::Mode::All);
|
||||||
if (creating) {
|
if (creating) {
|
||||||
Dialogs::Row *mainRow = history->addToChatList(dialogs.get());
|
Dialogs::Row *mainRow = history->addToChatList(Dialogs::Mode::All, dialogs.get());
|
||||||
contactsNoDialogs->del(history->peer, mainRow);
|
contactsNoDialogs->del(history->peer, mainRow);
|
||||||
}
|
}
|
||||||
RefPair(int32, movedFrom, int32, movedTo) = history->adjustByPosInChatsList(dialogs.get());
|
if (importantDialogs && !history->inChatList(Dialogs::Mode::Important) && !history->mute()) {
|
||||||
|
if (Global::DialogsMode() == Dialogs::Mode::Important) {
|
||||||
|
creating = true;
|
||||||
|
}
|
||||||
|
history->addToChatList(Dialogs::Mode::Important, importantDialogs.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto changed = history->adjustByPosInChatList(Dialogs::Mode::All, dialogs.get());
|
||||||
|
|
||||||
|
if (importantDialogs) {
|
||||||
|
if (history->mute()) {
|
||||||
|
if (Global::DialogsMode() == Dialogs::Mode::Important) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto importantChanged = history->adjustByPosInChatList(Dialogs::Mode::Important, importantDialogs.get());
|
||||||
|
if (Global::DialogsMode() == Dialogs::Mode::Important) {
|
||||||
|
changed = importantChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RefPair(int32, movedFrom, int32, movedTo) = changed;
|
||||||
|
|
||||||
emit dialogMoved(movedFrom, movedTo);
|
emit dialogMoved(movedFrom, movedTo);
|
||||||
|
|
||||||
if (creating) {
|
if (creating) {
|
||||||
refresh();
|
refresh();
|
||||||
} else if (_state == DefaultState && movedFrom != movedTo) {
|
} else if (_state == DefaultState && movedFrom != movedTo) {
|
||||||
update(0, qMin(movedFrom, movedTo), fullWidth(), qAbs(movedFrom - movedTo) + st::dlgHeight);
|
update(0, dialogsOffset() + qMin(movedFrom, movedTo), fullWidth(), qAbs(movedFrom - movedTo) + st::dlgHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,10 +472,13 @@ void DialogsInner::removeDialog(History *history) {
|
||||||
if (history->peer == _menuPeer && _menu) {
|
if (history->peer == _menuPeer && _menu) {
|
||||||
_menu->deleteLater();
|
_menu->deleteLater();
|
||||||
}
|
}
|
||||||
if (sel && sel->history() == history) {
|
if (_sel && _sel->history() == history) {
|
||||||
sel = nullptr;
|
_sel = nullptr;
|
||||||
|
}
|
||||||
|
history->removeFromChatList(Dialogs::Mode::All, dialogs.get());
|
||||||
|
if (importantDialogs) {
|
||||||
|
history->removeFromChatList(Dialogs::Mode::Important, importantDialogs.get());
|
||||||
}
|
}
|
||||||
history->removeFromChatList(dialogs.get());
|
|
||||||
history->clearNotifications();
|
history->clearNotifications();
|
||||||
if (App::wnd()) App::wnd()->notifyClear(history);
|
if (App::wnd()) App::wnd()->notifyClear(history);
|
||||||
if (contacts->contains(history->peer->id)) {
|
if (contacts->contains(history->peer->id)) {
|
||||||
|
@ -457,10 +494,13 @@ void DialogsInner::removeDialog(History *history) {
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::dlgUpdated(Dialogs::Row *row) {
|
void DialogsInner::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) {
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
update(0, row->pos() * st::dlgHeight, fullWidth(), st::dlgHeight);
|
if (Global::DialogsMode() == list) {
|
||||||
|
update(0, dialogsOffset() + row->pos() * st::dlgHeight, fullWidth(), st::dlgHeight);
|
||||||
|
}
|
||||||
} else if (_state == FilteredState || _state == SearchedState) {
|
} else if (_state == FilteredState || _state == SearchedState) {
|
||||||
|
if (list == Dialogs::Mode::All) {
|
||||||
for (int32 i = 0, l = _filterResults.size(); i < l; ++i) {
|
for (int32 i = 0, l = _filterResults.size(); i < l; ++i) {
|
||||||
if (_filterResults.at(i)->history() == row->history()) {
|
if (_filterResults.at(i)->history() == row->history()) {
|
||||||
update(0, i * st::dlgHeight, fullWidth(), st::dlgHeight);
|
update(0, i * st::dlgHeight, fullWidth(), st::dlgHeight);
|
||||||
|
@ -469,11 +509,12 @@ void DialogsInner::dlgUpdated(Dialogs::Row *row) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DialogsInner::dlgUpdated(History *history, MsgId msgId) {
|
void DialogsInner::dlgUpdated(History *history, MsgId msgId) {
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
if (auto row = dialogs->getRow(history->peer->id)) {
|
if (auto row = shownDialogs()->getRow(history->peer->id)) {
|
||||||
update(0, row->pos() * st::dlgHeight, fullWidth(), st::dlgHeight);
|
update(0, dialogsOffset() + row->pos() * st::dlgHeight, fullWidth(), st::dlgHeight);
|
||||||
}
|
}
|
||||||
} else if (_state == FilteredState || _state == SearchedState) {
|
} else if (_state == FilteredState || _state == SearchedState) {
|
||||||
int32 cnt = 0, add = filteredOffset();
|
int32 cnt = 0, add = filteredOffset();
|
||||||
|
@ -517,12 +558,14 @@ void DialogsInner::updateSelectedRow(PeerData *peer) {
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
if (peer) {
|
if (peer) {
|
||||||
if (History *h = App::historyLoaded(peer->id)) {
|
if (History *h = App::historyLoaded(peer->id)) {
|
||||||
if (h->inChatList()) {
|
if (h->inChatList(Global::DialogsMode())) {
|
||||||
update(0, h->posInChatList() * st::dlgHeight, fullWidth(), st::dlgHeight);
|
update(0, dialogsOffset() + h->posInChatList(Global::DialogsMode()) * st::dlgHeight, fullWidth(), st::dlgHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (sel) {
|
} else if (_sel) {
|
||||||
update(0, sel->pos() * st::dlgHeight, fullWidth(), st::dlgHeight);
|
update(0, dialogsOffset() + _sel->pos() * st::dlgHeight, fullWidth(), st::dlgHeight);
|
||||||
|
} else if (_importantSwitchSel) {
|
||||||
|
update(0, 0, fullWidth(), st::dlgImportantHeight);
|
||||||
}
|
}
|
||||||
} else if (_state == FilteredState || _state == SearchedState) {
|
} else if (_state == FilteredState || _state == SearchedState) {
|
||||||
if (peer) {
|
if (peer) {
|
||||||
|
@ -547,10 +590,15 @@ void DialogsInner::updateSelectedRow(PeerData *peer) {
|
||||||
|
|
||||||
void DialogsInner::leaveEvent(QEvent *e) {
|
void DialogsInner::leaveEvent(QEvent *e) {
|
||||||
setMouseTracking(false);
|
setMouseTracking(false);
|
||||||
selByMouse = false;
|
clearSelection();
|
||||||
if (sel || _filteredSel >= 0 || _hashtagSel >= 0 || _searchedSel >= 0 || _peopleSel >= 0) {
|
}
|
||||||
|
|
||||||
|
void DialogsInner::clearSelection() {
|
||||||
|
_selByMouse = false;
|
||||||
|
if (_sel || _filteredSel >= 0 || _hashtagSel >= 0 || _searchedSel >= 0 || _peopleSel >= 0) {
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
sel = 0;
|
_sel = nullptr;
|
||||||
|
_importantSwitchSel = false;
|
||||||
_filteredSel = _searchedSel = _peopleSel = _hashtagSel = -1;
|
_filteredSel = _searchedSel = _peopleSel = _hashtagSel = -1;
|
||||||
setCursor(style::cur_default);
|
setCursor(style::cur_default);
|
||||||
}
|
}
|
||||||
|
@ -569,13 +617,13 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) {
|
||||||
|
|
||||||
if (e->reason() == QContextMenuEvent::Mouse) {
|
if (e->reason() == QContextMenuEvent::Mouse) {
|
||||||
lastMousePos = e->globalPos();
|
lastMousePos = e->globalPos();
|
||||||
selByMouse = true;
|
_selByMouse = true;
|
||||||
onUpdateSelected(true);
|
onUpdateSelected(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
History *history = 0;
|
History *history = 0;
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
if (sel) history = sel->history();
|
if (_sel) history = _sel->history();
|
||||||
} else if (_state == FilteredState || _state == SearchedState) {
|
} else if (_state == FilteredState || _state == SearchedState) {
|
||||||
if (_filteredSel >= 0 && _filteredSel < _filterResults.size()) {
|
if (_filteredSel >= 0 && _filteredSel < _filterResults.size()) {
|
||||||
history = _filterResults[_filteredSel]->history();
|
history = _filterResults[_filteredSel]->history();
|
||||||
|
@ -691,7 +739,7 @@ void DialogsInner::onMenuDestroyed(QObject *obj) {
|
||||||
}
|
}
|
||||||
lastMousePos = QCursor::pos();
|
lastMousePos = QCursor::pos();
|
||||||
if (rect().contains(mapFromGlobal(lastMousePos))) {
|
if (rect().contains(mapFromGlobal(lastMousePos))) {
|
||||||
selByMouse = true;
|
_selByMouse = true;
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
onUpdateSelected(true);
|
onUpdateSelected(true);
|
||||||
}
|
}
|
||||||
|
@ -707,7 +755,10 @@ void DialogsInner::onParentGeometryChanged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::onPeerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars) {
|
void DialogsInner::onPeerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars) {
|
||||||
dialogs->peerNameChanged(peer, oldNames, oldChars);
|
dialogs->peerNameChanged(Dialogs::Mode::All, peer, oldNames, oldChars);
|
||||||
|
if (importantDialogs) {
|
||||||
|
importantDialogs->peerNameChanged(Dialogs::Mode::Important, peer, oldNames, oldChars);
|
||||||
|
}
|
||||||
contactsNoDialogs->peerNameChanged(peer, oldNames, oldChars);
|
contactsNoDialogs->peerNameChanged(peer, oldNames, oldChars);
|
||||||
contacts->peerNameChanged(peer, oldNames, oldChars);
|
contacts->peerNameChanged(peer, oldNames, oldChars);
|
||||||
update();
|
update();
|
||||||
|
@ -889,10 +940,10 @@ void DialogsInner::peerUpdated(PeerData *peer) {
|
||||||
|
|
||||||
PeerData *DialogsInner::updateFromParentDrag(QPoint globalPos) {
|
PeerData *DialogsInner::updateFromParentDrag(QPoint globalPos) {
|
||||||
lastMousePos = globalPos;
|
lastMousePos = globalPos;
|
||||||
selByMouse = true;
|
_selByMouse = true;
|
||||||
onUpdateSelected(true);
|
onUpdateSelected(true);
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
if (sel) return sel->history()->peer;
|
if (_sel) return _sel->history()->peer;
|
||||||
} else if (_state == FilteredState || _state == SearchedState) {
|
} else if (_state == FilteredState || _state == SearchedState) {
|
||||||
if (_filteredSel >= 0 && _filteredSel < _filterResults.size()) {
|
if (_filteredSel >= 0 && _filteredSel < _filterResults.size()) {
|
||||||
return _filterResults[_filteredSel]->history()->peer;
|
return _filterResults[_filteredSel]->history()->peer;
|
||||||
|
@ -976,8 +1027,9 @@ void DialogsInner::dialogsReceived(const QVector<MTPDialog> &added) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (App::wnd()) App::wnd()->updateCounter();
|
if (App::wnd()) App::wnd()->updateCounter();
|
||||||
if (!sel && !dialogs->isEmpty()) {
|
if (!_sel && !shownDialogs()->isEmpty()) {
|
||||||
sel = *dialogs->cbegin();
|
_sel = *shownDialogs()->cbegin();
|
||||||
|
_importantSwitchSel = false;
|
||||||
}
|
}
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
@ -1042,7 +1094,7 @@ void DialogsInner::peopleReceived(const QString &query, const QVector<MTPPeer> &
|
||||||
for (QVector<MTPPeer>::const_iterator i = people.cbegin(), e = people.cend(); i != e; ++i) {
|
for (QVector<MTPPeer>::const_iterator i = people.cbegin(), e = people.cend(); i != e; ++i) {
|
||||||
PeerId peerId = peerFromMTP(*i);
|
PeerId peerId = peerFromMTP(*i);
|
||||||
if (History *h = App::historyLoaded(peerId)) {
|
if (History *h = App::historyLoaded(peerId)) {
|
||||||
if (h->inChatList()) {
|
if (h->inChatList(Dialogs::Mode::All)) {
|
||||||
continue; // skip existing chats
|
continue; // skip existing chats
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1069,16 +1121,17 @@ void DialogsInner::notify_userIsContactChanged(UserData *user, bool fromThisApp)
|
||||||
if (user->contact > 0) {
|
if (user->contact > 0) {
|
||||||
History *history = App::history(user->id);
|
History *history = App::history(user->id);
|
||||||
contacts->addByName(history);
|
contacts->addByName(history);
|
||||||
if (auto row = dialogs->getRow(user->id)) {
|
if (auto row = shownDialogs()->getRow(user->id)) {
|
||||||
if (fromThisApp) {
|
if (fromThisApp) {
|
||||||
sel = row;
|
_sel = row;
|
||||||
|
_importantSwitchSel = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!dialogs->contains(user->id)) {
|
||||||
contactsNoDialogs->addByName(history);
|
contactsNoDialogs->addByName(history);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (sel && sel->history()->peer == user) {
|
if (_sel && _sel->history()->peer == user) {
|
||||||
sel = nullptr;
|
_sel = nullptr;
|
||||||
}
|
}
|
||||||
contactsNoDialogs->del(user);
|
contactsNoDialogs->del(user);
|
||||||
contacts->del(user);
|
contacts->del(user);
|
||||||
|
@ -1086,19 +1139,54 @@ void DialogsInner::notify_userIsContactChanged(UserData *user, bool fromThisApp)
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogsInner::notify_historyMuteUpdated(History *history) {
|
||||||
|
if (!importantDialogs || !history->inChatList(Dialogs::Mode::All)) return;
|
||||||
|
|
||||||
|
if (history->mute()) {
|
||||||
|
if (_sel && _sel->history() == history && Global::DialogsMode() == Dialogs::Mode::Important) {
|
||||||
|
_sel = nullptr;
|
||||||
|
}
|
||||||
|
history->removeFromChatList(Dialogs::Mode::Important, importantDialogs.get());
|
||||||
|
if (Global::DialogsMode() != Dialogs::Mode::Important) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
refresh();
|
||||||
|
} else {
|
||||||
|
bool creating = !history->inChatList(Dialogs::Mode::Important);
|
||||||
|
if (creating) {
|
||||||
|
history->addToChatList(Dialogs::Mode::Important, importantDialogs.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto changed = history->adjustByPosInChatList(Dialogs::Mode::All, dialogs.get());
|
||||||
|
|
||||||
|
if (Global::DialogsMode() != Dialogs::Mode::Important) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RefPair(int32, movedFrom, int32, movedTo) = changed;
|
||||||
|
|
||||||
|
emit dialogMoved(movedFrom, movedTo);
|
||||||
|
|
||||||
|
if (creating) {
|
||||||
|
refresh();
|
||||||
|
} else if (_state == DefaultState && movedFrom != movedTo) {
|
||||||
|
update(0, dialogsOffset() + qMin(movedFrom, movedTo), fullWidth(), qAbs(movedFrom - movedTo) + st::dlgHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DialogsInner::refresh(bool toTop) {
|
void DialogsInner::refresh(bool toTop) {
|
||||||
int32 h = 0;
|
int32 h = 0;
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
h = (dialogs->size()/* + contactsNoDialogs->size()*/) * st::dlgHeight;
|
if (shownDialogs()->isEmpty()) {
|
||||||
if (h) {
|
|
||||||
if (!_addContactLnk.isHidden()) _addContactLnk.hide();
|
|
||||||
} else {
|
|
||||||
h = st::noContactsHeight;
|
h = st::noContactsHeight;
|
||||||
if (cContactsReceived()) {
|
if (cContactsReceived()) {
|
||||||
if (_addContactLnk.isHidden()) _addContactLnk.show();
|
if (_addContactLnk.isHidden()) _addContactLnk.show();
|
||||||
} else {
|
} else {
|
||||||
if (!_addContactLnk.isHidden()) _addContactLnk.hide();
|
if (!_addContactLnk.isHidden()) _addContactLnk.hide();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
h = dialogsOffset() + shownDialogs()->size() * st::dlgHeight;
|
||||||
|
if (!_addContactLnk.isHidden()) _addContactLnk.hide();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!_addContactLnk.isHidden()) _addContactLnk.hide();
|
if (!_addContactLnk.isHidden()) _addContactLnk.hide();
|
||||||
|
@ -1117,10 +1205,11 @@ void DialogsInner::refresh(bool toTop) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::setMouseSel(bool msel, bool toTop) {
|
void DialogsInner::setMouseSel(bool msel, bool toTop) {
|
||||||
selByMouse = msel;
|
_selByMouse = msel;
|
||||||
if (!selByMouse && toTop) {
|
if (!_selByMouse && toTop) {
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
sel = !dialogs->isEmpty() ? *dialogs->cbegin() : nullptr;
|
_sel = !shownDialogs()->isEmpty() ? *shownDialogs()->cbegin() : nullptr;
|
||||||
|
_importantSwitchSel = false;
|
||||||
} else if (_state == FilteredState || _state == SearchedState) { // don't select first elem in search
|
} else if (_state == FilteredState || _state == SearchedState) { // don't select first elem in search
|
||||||
_filteredSel = _peopleSel = _searchedSel = _hashtagSel = -1;
|
_filteredSel = _peopleSel = _searchedSel = _hashtagSel = -1;
|
||||||
setCursor(style::cur_default);
|
setCursor(style::cur_default);
|
||||||
|
@ -1182,25 +1271,39 @@ void DialogsInner::clearFilter() {
|
||||||
|
|
||||||
void DialogsInner::selectSkip(int32 direction) {
|
void DialogsInner::selectSkip(int32 direction) {
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
if (!sel) {
|
if (_importantSwitchSel) {
|
||||||
if (!dialogs->isEmpty() && direction > 0) {
|
if (!shownDialogs()->isEmpty() && direction > 0) {
|
||||||
sel = *dialogs->cbegin();
|
_sel = *shownDialogs()->cbegin();
|
||||||
|
_importantSwitchSel = false;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (!_sel) {
|
||||||
|
if (importantDialogs) {
|
||||||
|
_importantSwitchSel = true;
|
||||||
|
} else if (!shownDialogs()->isEmpty() && direction > 0) {
|
||||||
|
_sel = *shownDialogs()->cbegin();
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (direction > 0) {
|
} else if (direction > 0) {
|
||||||
auto next = dialogs->cfind(sel);
|
auto next = shownDialogs()->cfind(_sel);
|
||||||
if (++next != dialogs->cend()) {
|
if (++next != shownDialogs()->cend()) {
|
||||||
sel = *next;
|
_sel = *next;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto prev = dialogs->cfind(sel);
|
auto prev = shownDialogs()->cfind(_sel);
|
||||||
if (prev != dialogs->cbegin()) {
|
if (prev != shownDialogs()->cbegin()) {
|
||||||
sel = *(--prev);
|
_sel = *(--prev);
|
||||||
|
} else if (importantDialogs) {
|
||||||
|
_importantSwitchSel = true;
|
||||||
|
_sel = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int32 fromY = sel->pos() * st::dlgHeight;
|
if (_importantSwitchSel || _sel) {
|
||||||
|
int fromY = _importantSwitchSel ? 0 : (dialogsOffset() + _sel->pos() * st::dlgHeight);
|
||||||
emit mustScrollTo(fromY, fromY + st::dlgHeight);
|
emit mustScrollTo(fromY, fromY + st::dlgHeight);
|
||||||
|
}
|
||||||
} else if (_state == FilteredState || _state == SearchedState) {
|
} else if (_state == FilteredState || _state == SearchedState) {
|
||||||
if (_hashtagResults.isEmpty() && _filterResults.isEmpty() && _peopleResults.isEmpty() && _searchResults.isEmpty()) return;
|
if (_hashtagResults.isEmpty() && _filterResults.isEmpty() && _peopleResults.isEmpty() && _searchResults.isEmpty()) return;
|
||||||
if ((_hashtagSel < 0 || _hashtagSel >= _hashtagResults.size()) &&
|
if ((_hashtagSel < 0 || _hashtagSel >= _hashtagResults.size()) &&
|
||||||
|
@ -1249,8 +1352,8 @@ void DialogsInner::selectSkip(int32 direction) {
|
||||||
void DialogsInner::scrollToPeer(const PeerId &peer, MsgId msgId) {
|
void DialogsInner::scrollToPeer(const PeerId &peer, MsgId msgId) {
|
||||||
int32 fromY = -1;
|
int32 fromY = -1;
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
if (auto row = dialogs->getRow(peer)) {
|
if (auto row = shownDialogs()->getRow(peer)) {
|
||||||
fromY = row->pos() * st::dlgHeight;
|
fromY = dialogsOffset() + row->pos() * st::dlgHeight;
|
||||||
}
|
}
|
||||||
} else if (_state == FilteredState || _state == SearchedState) {
|
} else if (_state == FilteredState || _state == SearchedState) {
|
||||||
if (msgId) {
|
if (msgId) {
|
||||||
|
@ -1278,24 +1381,31 @@ void DialogsInner::scrollToPeer(const PeerId &peer, MsgId msgId) {
|
||||||
void DialogsInner::selectSkipPage(int32 pixels, int32 direction) {
|
void DialogsInner::selectSkipPage(int32 pixels, int32 direction) {
|
||||||
int toSkip = pixels / int(st::dlgHeight);
|
int toSkip = pixels / int(st::dlgHeight);
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
if (!sel) {
|
if (!_sel) {
|
||||||
if (direction > 0 && !dialogs->isEmpty()) {
|
if (direction > 0 && !shownDialogs()->isEmpty()) {
|
||||||
sel = *dialogs->cbegin();
|
_sel = *shownDialogs()->cbegin();
|
||||||
|
_importantSwitchSel = false;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (direction > 0) {
|
if (direction > 0) {
|
||||||
for (auto i = dialogs->cfind(sel), end = dialogs->cend(); i != end && (toSkip--); ++i) {
|
for (auto i = shownDialogs()->cfind(_sel), end = shownDialogs()->cend(); i != end && (toSkip--); ++i) {
|
||||||
sel = *i;
|
_sel = *i;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (auto i = dialogs->cfind(sel), b = dialogs->cbegin(); i != b && (toSkip--); --i) {
|
for (auto i = shownDialogs()->cfind(_sel), b = shownDialogs()->cbegin(); i != b && (toSkip--); --i) {
|
||||||
sel = *i;
|
_sel = *i;
|
||||||
|
}
|
||||||
|
if (toSkip && importantDialogs) {
|
||||||
|
_importantSwitchSel = true;
|
||||||
|
_sel = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int fromY = sel->pos() * st::dlgHeight;
|
if (_importantSwitchSel || _sel) {
|
||||||
|
int fromY = (_importantSwitchSel ? 0 : (dialogsOffset() + _sel->pos() * st::dlgHeight));
|
||||||
emit mustScrollTo(fromY, fromY + st::dlgHeight);
|
emit mustScrollTo(fromY, fromY + st::dlgHeight);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return selectSkip(direction * toSkip);
|
return selectSkip(direction * toSkip);
|
||||||
}
|
}
|
||||||
|
@ -1308,9 +1418,9 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
|
||||||
int32 yTo = yFrom + parentWidget()->height() * 5;
|
int32 yTo = yFrom + parentWidget()->height() * 5;
|
||||||
MTP::clearLoaderPriorities();
|
MTP::clearLoaderPriorities();
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
int32 otherStart = dialogs->size() * st::dlgHeight;
|
int32 otherStart = shownDialogs()->size() * st::dlgHeight;
|
||||||
if (yFrom < otherStart) {
|
if (yFrom < otherStart) {
|
||||||
for (auto i = dialogs->cfind(yFrom, st::dlgHeight), end = dialogs->cend(); i != end; ++i) {
|
for (auto i = shownDialogs()->cfind(yFrom, st::dlgHeight), end = shownDialogs()->cend(); i != end; ++i) {
|
||||||
if (((*i)->pos() * st::dlgHeight) >= yTo) {
|
if (((*i)->pos() * st::dlgHeight) >= yTo) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1357,10 +1467,23 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DialogsInner::choosePeer() {
|
bool DialogsInner::choosePeer() {
|
||||||
History *history = 0;
|
History *history = nullptr;
|
||||||
MsgId msgId = ShowAtUnreadMsgId;
|
MsgId msgId = ShowAtUnreadMsgId;
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
if (sel) history = sel->history();
|
if (_importantSwitchSel && importantDialogs) {
|
||||||
|
clearSelection();
|
||||||
|
if (Global::DialogsMode() == Dialogs::Mode::All) {
|
||||||
|
Global::SetDialogsMode(Dialogs::Mode::Important);
|
||||||
|
} else {
|
||||||
|
Global::SetDialogsMode(Dialogs::Mode::All);
|
||||||
|
}
|
||||||
|
Local::writeUserSettings();
|
||||||
|
refresh();
|
||||||
|
_importantSwitchSel = true;
|
||||||
|
return true;
|
||||||
|
} else if (_sel) {
|
||||||
|
history = _sel->history();
|
||||||
|
}
|
||||||
} else if (_state == FilteredState || _state == SearchedState) {
|
} else if (_state == FilteredState || _state == SearchedState) {
|
||||||
if (_hashtagSel >= 0 && _hashtagSel < _hashtagResults.size()) {
|
if (_hashtagSel >= 0 && _hashtagSel < _hashtagResults.size()) {
|
||||||
QString hashtag = _hashtagResults.at(_hashtagSel);
|
QString hashtag = _hashtagResults.at(_hashtagSel);
|
||||||
|
@ -1379,7 +1502,7 @@ bool DialogsInner::choosePeer() {
|
||||||
Local::writeRecentHashtagsAndBots();
|
Local::writeRecentHashtagsAndBots();
|
||||||
emit refreshHashtags();
|
emit refreshHashtags();
|
||||||
|
|
||||||
selByMouse = true;
|
_selByMouse = true;
|
||||||
onUpdateSelected(true);
|
onUpdateSelected(true);
|
||||||
} else {
|
} else {
|
||||||
saveRecentHashtags('#' + hashtag);
|
saveRecentHashtags('#' + hashtag);
|
||||||
|
@ -1406,7 +1529,7 @@ bool DialogsInner::choosePeer() {
|
||||||
emit searchResultChosen();
|
emit searchResultChosen();
|
||||||
}
|
}
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
sel = 0;
|
_sel = nullptr;
|
||||||
_filteredSel = _peopleSel = _searchedSel = _hashtagSel = -1;
|
_filteredSel = _peopleSel = _searchedSel = _hashtagSel = -1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1442,7 +1565,7 @@ void DialogsInner::saveRecentHashtags(const QString &text) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::destroyData() {
|
void DialogsInner::destroyData() {
|
||||||
sel = nullptr;
|
_sel = nullptr;
|
||||||
_hashtagSel = -1;
|
_hashtagSel = -1;
|
||||||
_hashtagResults.clear();
|
_hashtagResults.clear();
|
||||||
_filteredSel = -1;
|
_filteredSel = -1;
|
||||||
|
@ -1453,6 +1576,9 @@ void DialogsInner::destroyData() {
|
||||||
contacts = nullptr;
|
contacts = nullptr;
|
||||||
contactsNoDialogs = nullptr;
|
contactsNoDialogs = nullptr;
|
||||||
dialogs = nullptr;
|
dialogs = nullptr;
|
||||||
|
if (importantDialogs) {
|
||||||
|
importantDialogs = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const {
|
void DialogsInner::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const {
|
||||||
|
@ -1462,9 +1588,9 @@ void DialogsInner::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&ou
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
if (auto row = dialogs->getRow(inPeer->id)) {
|
if (auto row = shownDialogs()->getRow(inPeer->id)) {
|
||||||
auto i = dialogs->cfind(row);
|
auto i = shownDialogs()->cfind(row);
|
||||||
if (i != dialogs->cbegin()) {
|
if (i != shownDialogs()->cbegin()) {
|
||||||
outPeer = (*(--i))->history()->peer;
|
outPeer = (*(--i))->history()->peer;
|
||||||
outMsg = ShowAtUnreadMsgId;
|
outMsg = ShowAtUnreadMsgId;
|
||||||
return;
|
return;
|
||||||
|
@ -1536,9 +1662,9 @@ void DialogsInner::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&out
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
if (auto row = dialogs->getRow(inPeer->id)) {
|
if (auto row = shownDialogs()->getRow(inPeer->id)) {
|
||||||
auto i = dialogs->cfind(row) + 1;
|
auto i = shownDialogs()->cfind(row) + 1;
|
||||||
if (i != dialogs->cend()) {
|
if (i != shownDialogs()->cend()) {
|
||||||
outPeer = (*i)->history()->peer;
|
outPeer = (*i)->history()->peer;
|
||||||
outMsg = ShowAtUnreadMsgId;
|
outMsg = ShowAtUnreadMsgId;
|
||||||
return;
|
return;
|
||||||
|
@ -1697,19 +1823,19 @@ void DialogsWidget::activate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsWidget::createDialog(History *history) {
|
void DialogsWidget::createDialog(History *history) {
|
||||||
bool creating = !history->inChatList();
|
bool creating = !history->inChatList(Dialogs::Mode::All);
|
||||||
_inner.createDialog(history);
|
_inner.createDialog(history);
|
||||||
if (creating && history->peer->migrateFrom()) {
|
if (creating && history->peer->migrateFrom()) {
|
||||||
if (History *h = App::historyLoaded(history->peer->migrateFrom()->id)) {
|
if (History *h = App::historyLoaded(history->peer->migrateFrom()->id)) {
|
||||||
if (h->inChatList()) {
|
if (h->inChatList(Dialogs::Mode::All)) {
|
||||||
removeDialog(h);
|
removeDialog(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsWidget::dlgUpdated(Dialogs::Row *row) {
|
void DialogsWidget::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) {
|
||||||
_inner.dlgUpdated(row);
|
_inner.dlgUpdated(list, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsWidget::dlgUpdated(History *row, MsgId msgId) {
|
void DialogsWidget::dlgUpdated(History *row, MsgId msgId) {
|
||||||
|
@ -1795,6 +1921,10 @@ void DialogsWidget::notify_userIsContactChanged(UserData *user, bool fromThisApp
|
||||||
_inner.notify_userIsContactChanged(user, fromThisApp);
|
_inner.notify_userIsContactChanged(user, fromThisApp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogsWidget::notify_historyMuteUpdated(History *history) {
|
||||||
|
_inner.notify_historyMuteUpdated(history);
|
||||||
|
}
|
||||||
|
|
||||||
void DialogsWidget::unreadCountsReceived(const QVector<MTPDialog> &dialogs) {
|
void DialogsWidget::unreadCountsReceived(const QVector<MTPDialog> &dialogs) {
|
||||||
for (QVector<MTPDialog>::const_iterator i = dialogs.cbegin(), e = dialogs.cend(); i != e; ++i) {
|
for (QVector<MTPDialog>::const_iterator i = dialogs.cbegin(), e = dialogs.cend(); i != e; ++i) {
|
||||||
switch (i->type()) {
|
switch (i->type()) {
|
||||||
|
@ -1802,7 +1932,7 @@ void DialogsWidget::unreadCountsReceived(const QVector<MTPDialog> &dialogs) {
|
||||||
const auto &d(i->c_dialog());
|
const auto &d(i->c_dialog());
|
||||||
if (History *h = App::historyLoaded(peerFromMTP(d.vpeer))) {
|
if (History *h = App::historyLoaded(peerFromMTP(d.vpeer))) {
|
||||||
App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, h);
|
App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, h);
|
||||||
if (d.vunread_count.v >= h->unreadCount) {
|
if (d.vunread_count.v >= h->unreadCount()) {
|
||||||
h->setUnreadCount(d.vunread_count.v, false);
|
h->setUnreadCount(d.vunread_count.v, false);
|
||||||
h->inboxReadBefore = d.vread_inbox_max_id.v + 1;
|
h->inboxReadBefore = d.vread_inbox_max_id.v + 1;
|
||||||
}
|
}
|
||||||
|
@ -1820,7 +1950,7 @@ void DialogsWidget::unreadCountsReceived(const QVector<MTPDialog> &dialogs) {
|
||||||
}
|
}
|
||||||
App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, h);
|
App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, h);
|
||||||
int32 unreadCount = h->isMegagroup() ? d.vunread_count.v : d.vunread_important_count.v;
|
int32 unreadCount = h->isMegagroup() ? d.vunread_count.v : d.vunread_important_count.v;
|
||||||
if (unreadCount >= h->unreadCount) {
|
if (unreadCount >= h->unreadCount()) {
|
||||||
h->setUnreadCount(unreadCount, false);
|
h->setUnreadCount(unreadCount, false);
|
||||||
h->inboxReadBefore = d.vread_inbox_max_id.v + 1;
|
h->inboxReadBefore = d.vread_inbox_max_id.v + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,10 +54,6 @@ public:
|
||||||
|
|
||||||
void contactsReceived(const QVector<MTPContact> &contacts);
|
void contactsReceived(const QVector<MTPContact> &contacts);
|
||||||
|
|
||||||
int32 filteredOffset() const;
|
|
||||||
int32 peopleOffset() const;
|
|
||||||
int32 searchedOffset() const;
|
|
||||||
|
|
||||||
void mouseMoveEvent(QMouseEvent *e);
|
void mouseMoveEvent(QMouseEvent *e);
|
||||||
void mousePressEvent(QMouseEvent *e);
|
void mousePressEvent(QMouseEvent *e);
|
||||||
void resizeEvent(QResizeEvent *e);
|
void resizeEvent(QResizeEvent *e);
|
||||||
|
@ -65,14 +61,11 @@ public:
|
||||||
void leaveEvent(QEvent *e);
|
void leaveEvent(QEvent *e);
|
||||||
void contextMenuEvent(QContextMenuEvent *e);
|
void contextMenuEvent(QContextMenuEvent *e);
|
||||||
|
|
||||||
void peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const;
|
|
||||||
void searchInPeerPaint(Painter &p, int32 w, bool onlyBackground) const;
|
|
||||||
|
|
||||||
void selectSkip(int32 direction);
|
void selectSkip(int32 direction);
|
||||||
void selectSkipPage(int32 pixels, int32 direction);
|
void selectSkipPage(int32 pixels, int32 direction);
|
||||||
|
|
||||||
void createDialog(History *history);
|
void createDialog(History *history);
|
||||||
void dlgUpdated(Dialogs::Row *row);
|
void dlgUpdated(Dialogs::Mode list, Dialogs::Row *row);
|
||||||
void dlgUpdated(History *row, MsgId msgId);
|
void dlgUpdated(History *row, MsgId msgId);
|
||||||
void removeDialog(History *history);
|
void removeDialog(History *history);
|
||||||
|
|
||||||
|
@ -125,6 +118,7 @@ public:
|
||||||
void updateNotifySettings(PeerData *peer);
|
void updateNotifySettings(PeerData *peer);
|
||||||
|
|
||||||
void notify_userIsContactChanged(UserData *user, bool fromThisApp);
|
void notify_userIsContactChanged(UserData *user, bool fromThisApp);
|
||||||
|
void notify_historyMuteUpdated(History *history);
|
||||||
|
|
||||||
~DialogsInner();
|
~DialogsInner();
|
||||||
|
|
||||||
|
@ -165,17 +159,34 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
int dialogsOffset() const;
|
||||||
|
int filteredOffset() const;
|
||||||
|
int peopleOffset() const;
|
||||||
|
int searchedOffset() const;
|
||||||
|
|
||||||
|
void peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool active, bool selected, bool onlyBackground) const;
|
||||||
|
void searchInPeerPaint(Painter &p, int32 w, bool onlyBackground) const;
|
||||||
|
|
||||||
|
void clearSelection();
|
||||||
void clearSearchResults(bool clearPeople = true);
|
void clearSearchResults(bool clearPeople = true);
|
||||||
void updateSelectedRow(PeerData *peer = 0);
|
void updateSelectedRow(PeerData *peer = 0);
|
||||||
bool menuPeerMuted();
|
bool menuPeerMuted();
|
||||||
void contextBlockDone(QPair<UserData*, bool> data, const MTPBool &result);
|
void contextBlockDone(QPair<UserData*, bool> data, const MTPBool &result);
|
||||||
|
|
||||||
|
Dialogs::IndexedList *shownDialogs() const {
|
||||||
|
return (Global::DialogsMode() == Dialogs::Mode::Important) ? importantDialogs.get() : dialogs.get();
|
||||||
|
}
|
||||||
|
|
||||||
using DialogsList = std_::unique_ptr<Dialogs::IndexedList>;
|
using DialogsList = std_::unique_ptr<Dialogs::IndexedList>;
|
||||||
DialogsList dialogs;
|
DialogsList dialogs;
|
||||||
|
DialogsList importantDialogs;
|
||||||
|
|
||||||
DialogsList contactsNoDialogs;
|
DialogsList contactsNoDialogs;
|
||||||
DialogsList contacts;
|
DialogsList contacts;
|
||||||
Dialogs::Row *sel = nullptr;
|
|
||||||
bool selByMouse = false;
|
bool _importantSwitchSel = false;
|
||||||
|
Dialogs::Row *_sel = nullptr;
|
||||||
|
bool _selByMouse = false;
|
||||||
|
|
||||||
QString _filter, _hashtagFilter;
|
QString _filter, _hashtagFilter;
|
||||||
|
|
||||||
|
@ -244,7 +255,7 @@ public:
|
||||||
|
|
||||||
void loadDialogs();
|
void loadDialogs();
|
||||||
void createDialog(History *history);
|
void createDialog(History *history);
|
||||||
void dlgUpdated(Dialogs::Row *row);
|
void dlgUpdated(Dialogs::Mode list, Dialogs::Row *row);
|
||||||
void dlgUpdated(History *row, MsgId msgId);
|
void dlgUpdated(History *row, MsgId msgId);
|
||||||
|
|
||||||
void dialogsToUp();
|
void dialogsToUp();
|
||||||
|
@ -276,6 +287,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void notify_userIsContactChanged(UserData *user, bool fromThisApp);
|
void notify_userIsContactChanged(UserData *user, bool fromThisApp);
|
||||||
|
void notify_historyMuteUpdated(History *history);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,7 @@ namespace App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace App
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ namespace Ui {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Notify {
|
namespace Notify {
|
||||||
|
|
||||||
|
@ -313,6 +313,10 @@ namespace Notify {
|
||||||
if (MainWidget *m = App::main()) m->notify_inlineItemLayoutChanged(layout);
|
if (MainWidget *m = App::main()) m->notify_inlineItemLayoutChanged(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void historyMuteUpdated(History *history) {
|
||||||
|
if (MainWidget *m = App::main()) m->notify_historyMuteUpdated(history);
|
||||||
|
}
|
||||||
|
|
||||||
void handlePendingHistoryUpdate() {
|
void handlePendingHistoryUpdate() {
|
||||||
if (MainWidget *m = App::main()) {
|
if (MainWidget *m = App::main()) {
|
||||||
m->notify_handlePendingHistoryUpdate();
|
m->notify_handlePendingHistoryUpdate();
|
||||||
|
@ -323,7 +327,7 @@ namespace Notify {
|
||||||
Global::RefPendingRepaintItems().clear();
|
Global::RefPendingRepaintItems().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace Notify
|
||||||
|
|
||||||
#define DefineReadOnlyVar(Namespace, Type, Name) const Type &Name() { \
|
#define DefineReadOnlyVar(Namespace, Type, Name) const Type &Name() { \
|
||||||
t_assert_full(Namespace##Data != 0, #Namespace "Data != nullptr in " #Namespace "::" #Name, __FILE__, __LINE__); \
|
t_assert_full(Namespace##Data != 0, #Namespace "Data != nullptr in " #Namespace "::" #Name, __FILE__, __LINE__); \
|
||||||
|
@ -341,7 +345,6 @@ void Set##Name(const Type &Name) { \
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Sandbox {
|
namespace Sandbox {
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
struct Data {
|
struct Data {
|
||||||
|
@ -352,10 +355,10 @@ namespace Sandbox {
|
||||||
ConnectionProxy PreLaunchProxy;
|
ConnectionProxy PreLaunchProxy;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace internal
|
||||||
|
} // namespace Sandbox
|
||||||
|
|
||||||
}
|
Sandbox::internal::Data *SandboxData = nullptr;
|
||||||
Sandbox::internal::Data *SandboxData = 0;
|
|
||||||
uint64 SandboxUserTag = 0;
|
uint64 SandboxUserTag = 0;
|
||||||
|
|
||||||
namespace Sandbox {
|
namespace Sandbox {
|
||||||
|
@ -469,7 +472,7 @@ namespace Sandbox {
|
||||||
DefineVar(Sandbox, QByteArray, LastCrashDump);
|
DefineVar(Sandbox, QByteArray, LastCrashDump);
|
||||||
DefineVar(Sandbox, ConnectionProxy, PreLaunchProxy);
|
DefineVar(Sandbox, ConnectionProxy, PreLaunchProxy);
|
||||||
|
|
||||||
}
|
} // namespace Sandbox
|
||||||
|
|
||||||
namespace Global {
|
namespace Global {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -480,6 +483,8 @@ namespace Global {
|
||||||
|
|
||||||
Adaptive::Layout AdaptiveLayout = Adaptive::NormalLayout;
|
Adaptive::Layout AdaptiveLayout = Adaptive::NormalLayout;
|
||||||
bool AdaptiveForWide = true;
|
bool AdaptiveForWide = true;
|
||||||
|
bool DialogsModeEnabled = false;
|
||||||
|
Dialogs::Mode DialogsMode = Dialogs::Mode::All;
|
||||||
|
|
||||||
int32 DebugLoggingFlags = 0;
|
int32 DebugLoggingFlags = 0;
|
||||||
|
|
||||||
|
@ -513,15 +518,15 @@ namespace Global {
|
||||||
CircleMasksMap CircleMasks;
|
CircleMasksMap CircleMasks;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace internal
|
||||||
}
|
} // namespace Global
|
||||||
|
|
||||||
Global::internal::Data *GlobalData = 0;
|
Global::internal::Data *GlobalData = nullptr;
|
||||||
|
|
||||||
namespace Global {
|
namespace Global {
|
||||||
|
|
||||||
bool started() {
|
bool started() {
|
||||||
return GlobalData != 0;
|
return GlobalData != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
|
@ -532,7 +537,7 @@ namespace Global {
|
||||||
|
|
||||||
void finish() {
|
void finish() {
|
||||||
delete GlobalData;
|
delete GlobalData;
|
||||||
GlobalData = 0;
|
GlobalData = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
DefineReadOnlyVar(Global, uint64, LaunchId);
|
DefineReadOnlyVar(Global, uint64, LaunchId);
|
||||||
|
@ -540,6 +545,8 @@ namespace Global {
|
||||||
|
|
||||||
DefineVar(Global, Adaptive::Layout, AdaptiveLayout);
|
DefineVar(Global, Adaptive::Layout, AdaptiveLayout);
|
||||||
DefineVar(Global, bool, AdaptiveForWide);
|
DefineVar(Global, bool, AdaptiveForWide);
|
||||||
|
DefineVar(Global, bool, DialogsModeEnabled);
|
||||||
|
DefineVar(Global, Dialogs::Mode, DialogsMode);
|
||||||
|
|
||||||
DefineVar(Global, int32, DebugLoggingFlags);
|
DefineVar(Global, int32, DebugLoggingFlags);
|
||||||
|
|
||||||
|
@ -572,4 +579,4 @@ namespace Global {
|
||||||
|
|
||||||
DefineRefVar(Global, CircleMasksMap, CircleMasks);
|
DefineRefVar(Global, CircleMasksMap, CircleMasks);
|
||||||
|
|
||||||
};
|
} // namespace Global
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace App {
|
||||||
|
|
||||||
void logOutDelayed();
|
void logOutDelayed();
|
||||||
|
|
||||||
};
|
} // namespace App
|
||||||
|
|
||||||
namespace InlineBots {
|
namespace InlineBots {
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
|
@ -88,7 +88,7 @@ namespace Ui {
|
||||||
|
|
||||||
bool hideWindowNoQuit();
|
bool hideWindowNoQuit();
|
||||||
|
|
||||||
};
|
} // namespace Ui
|
||||||
|
|
||||||
enum ClipStopperType {
|
enum ClipStopperType {
|
||||||
ClipStopperMediaview,
|
ClipStopperMediaview,
|
||||||
|
@ -112,11 +112,12 @@ namespace Notify {
|
||||||
|
|
||||||
void historyItemLayoutChanged(const HistoryItem *item);
|
void historyItemLayoutChanged(const HistoryItem *item);
|
||||||
void inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout);
|
void inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout);
|
||||||
|
void historyMuteUpdated(History *history);
|
||||||
|
|
||||||
// handle pending resize() / paint() on history items
|
// handle pending resize() / paint() on history items
|
||||||
void handlePendingHistoryUpdate();
|
void handlePendingHistoryUpdate();
|
||||||
|
|
||||||
};
|
} // namespace Notify
|
||||||
|
|
||||||
#define DeclareReadOnlyVar(Type, Name) const Type &Name();
|
#define DeclareReadOnlyVar(Type, Name) const Type &Name();
|
||||||
#define DeclareRefVar(Type, Name) DeclareReadOnlyVar(Type, Name) \
|
#define DeclareRefVar(Type, Name) DeclareReadOnlyVar(Type, Name) \
|
||||||
|
@ -139,7 +140,7 @@ namespace Sandbox {
|
||||||
DeclareVar(QByteArray, LastCrashDump);
|
DeclareVar(QByteArray, LastCrashDump);
|
||||||
DeclareVar(ConnectionProxy, PreLaunchProxy);
|
DeclareVar(ConnectionProxy, PreLaunchProxy);
|
||||||
|
|
||||||
}
|
} // namespace Sandbox
|
||||||
|
|
||||||
namespace Adaptive {
|
namespace Adaptive {
|
||||||
enum Layout {
|
enum Layout {
|
||||||
|
@ -147,15 +148,16 @@ namespace Adaptive {
|
||||||
NormalLayout,
|
NormalLayout,
|
||||||
WideLayout,
|
WideLayout,
|
||||||
};
|
};
|
||||||
};
|
} // namespace Adaptive
|
||||||
|
|
||||||
namespace DebugLogging {
|
namespace DebugLogging {
|
||||||
enum Flags {
|
enum Flags {
|
||||||
FileLoaderFlag = 0x00000001,
|
FileLoaderFlag = 0x00000001,
|
||||||
};
|
};
|
||||||
}
|
} // namespace DebugLogging
|
||||||
|
|
||||||
namespace Stickers {
|
namespace Stickers {
|
||||||
|
|
||||||
static const uint64 DefaultSetId = 0; // for backward compatibility
|
static const uint64 DefaultSetId = 0; // for backward compatibility
|
||||||
static const uint64 CustomSetId = 0xFFFFFFFFFFFFFFFFULL, RecentSetId = 0xFFFFFFFFFFFFFFFEULL;
|
static const uint64 CustomSetId = 0xFFFFFFFFFFFFFFFFULL, RecentSetId = 0xFFFFFFFFFFFFFFFEULL;
|
||||||
static const uint64 NoneSetId = 0xFFFFFFFFFFFFFFFDULL; // for emoji/stickers panel
|
static const uint64 NoneSetId = 0xFFFFFFFFFFFFFFFDULL; // for emoji/stickers panel
|
||||||
|
@ -169,9 +171,10 @@ namespace Stickers {
|
||||||
StickerPack stickers;
|
StickerPack stickers;
|
||||||
StickersByEmojiMap emoji;
|
StickersByEmojiMap emoji;
|
||||||
};
|
};
|
||||||
typedef QMap<uint64, Set> Sets;
|
using Sets = QMap<uint64, Set>;
|
||||||
typedef QList<uint64> Order;
|
using Order = QList<uint64>;
|
||||||
}
|
|
||||||
|
} // namespace Stickers
|
||||||
|
|
||||||
namespace Global {
|
namespace Global {
|
||||||
|
|
||||||
|
@ -184,6 +187,8 @@ namespace Global {
|
||||||
|
|
||||||
DeclareVar(Adaptive::Layout, AdaptiveLayout);
|
DeclareVar(Adaptive::Layout, AdaptiveLayout);
|
||||||
DeclareVar(bool, AdaptiveForWide);
|
DeclareVar(bool, AdaptiveForWide);
|
||||||
|
DeclareVar(bool, DialogsModeEnabled);
|
||||||
|
DeclareVar(Dialogs::Mode, DialogsMode);
|
||||||
|
|
||||||
DeclareVar(int32, DebugLoggingFlags);
|
DeclareVar(int32, DebugLoggingFlags);
|
||||||
|
|
||||||
|
@ -219,9 +224,10 @@ namespace Global {
|
||||||
typedef QMap<uint64, QPixmap> CircleMasksMap;
|
typedef QMap<uint64, QPixmap> CircleMasksMap;
|
||||||
DeclareRefVar(CircleMasksMap, CircleMasks);
|
DeclareRefVar(CircleMasksMap, CircleMasks);
|
||||||
|
|
||||||
};
|
} // namespace Global
|
||||||
|
|
||||||
namespace Adaptive {
|
namespace Adaptive {
|
||||||
|
|
||||||
inline bool OneColumn() {
|
inline bool OneColumn() {
|
||||||
return Global::AdaptiveLayout() == OneColumnLayout;
|
return Global::AdaptiveLayout() == OneColumnLayout;
|
||||||
}
|
}
|
||||||
|
@ -231,10 +237,13 @@ namespace Adaptive {
|
||||||
inline bool Wide() {
|
inline bool Wide() {
|
||||||
return Global::AdaptiveForWide() && (Global::AdaptiveLayout() == WideLayout);
|
return Global::AdaptiveForWide() && (Global::AdaptiveLayout() == WideLayout);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
} // namespace Adaptive
|
||||||
|
|
||||||
namespace DebugLogging {
|
namespace DebugLogging {
|
||||||
|
|
||||||
inline bool FileLoader() {
|
inline bool FileLoader() {
|
||||||
return (Global::DebugLoggingFlags() | FileLoaderFlag) != 0;
|
return (Global::DebugLoggingFlags() | FileLoaderFlag) != 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
} // namespace DebugLogging
|
||||||
|
|
|
@ -104,7 +104,7 @@ void historyInit() {
|
||||||
|
|
||||||
History::History(const PeerId &peerId)
|
History::History(const PeerId &peerId)
|
||||||
: peer(App::peer(peerId))
|
: peer(App::peer(peerId))
|
||||||
, mute(isNotifyMuted(peer->notify)) {
|
, _mute(isNotifyMuted(peer->notify)) {
|
||||||
if (peer->isChannel() || (peer->isUser() && peer->asUser()->botInfo)) {
|
if (peer->isChannel() || (peer->isUser() && peer->asUser()->botInfo)) {
|
||||||
outboxReadBefore = INT_MAX;
|
outboxReadBefore = INT_MAX;
|
||||||
}
|
}
|
||||||
|
@ -1683,7 +1683,7 @@ void History::updateShowFrom() {
|
||||||
|
|
||||||
MsgId History::inboxRead(MsgId upTo) {
|
MsgId History::inboxRead(MsgId upTo) {
|
||||||
if (upTo < 0) return upTo;
|
if (upTo < 0) return upTo;
|
||||||
if (unreadCount) {
|
if (unreadCount()) {
|
||||||
if (upTo && loadedAtBottom()) App::main()->historyToDown(this);
|
if (upTo && loadedAtBottom()) App::main()->historyToDown(this);
|
||||||
setUnreadCount(upTo ? countUnread(upTo) : 0);
|
setUnreadCount(upTo ? countUnread(upTo) : 0);
|
||||||
}
|
}
|
||||||
|
@ -1739,7 +1739,7 @@ HistoryItem *History::lastImportantMessage() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::setUnreadCount(int newUnreadCount, bool psUpdate) {
|
void History::setUnreadCount(int newUnreadCount, bool psUpdate) {
|
||||||
if (unreadCount != newUnreadCount) {
|
if (_unreadCount != newUnreadCount) {
|
||||||
if (newUnreadCount == 1) {
|
if (newUnreadCount == 1) {
|
||||||
if (loadedAtBottom()) showFrom = lastImportantMessage();
|
if (loadedAtBottom()) showFrom = lastImportantMessage();
|
||||||
inboxReadBefore = qMax(inboxReadBefore, msgIdForRead());
|
inboxReadBefore = qMax(inboxReadBefore, msgIdForRead());
|
||||||
|
@ -1747,18 +1747,18 @@ void History::setUnreadCount(int newUnreadCount, bool psUpdate) {
|
||||||
showFrom = nullptr;
|
showFrom = nullptr;
|
||||||
inboxReadBefore = qMax(inboxReadBefore, msgIdForRead() + 1);
|
inboxReadBefore = qMax(inboxReadBefore, msgIdForRead() + 1);
|
||||||
}
|
}
|
||||||
if (inChatList()) {
|
if (inChatList(Dialogs::Mode::All)) {
|
||||||
App::histories().unreadIncrement(newUnreadCount - unreadCount, mute);
|
App::histories().unreadIncrement(newUnreadCount - _unreadCount, mute());
|
||||||
if (psUpdate && (!mute || cIncludeMuted()) && App::wnd()) {
|
if (psUpdate && (!mute() || cIncludeMuted()) && App::wnd()) {
|
||||||
App::wnd()->updateCounter();
|
App::wnd()->updateCounter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unreadCount = newUnreadCount;
|
_unreadCount = newUnreadCount;
|
||||||
if (unreadBar) {
|
if (unreadBar) {
|
||||||
int32 count = unreadCount;
|
int32 count = _unreadCount;
|
||||||
if (peer->migrateTo()) {
|
if (peer->migrateTo()) {
|
||||||
if (History *h = App::historyLoaded(peer->migrateTo()->id)) {
|
if (History *h = App::historyLoaded(peer->migrateTo()->id)) {
|
||||||
count += h->unreadCount;
|
count += h->unreadCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
|
@ -1771,12 +1771,15 @@ void History::setUnreadCount(int newUnreadCount, bool psUpdate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::setMute(bool newMute) {
|
void History::setMute(bool newMute) {
|
||||||
if (mute != newMute) {
|
if (_mute != newMute) {
|
||||||
mute = newMute;
|
_mute = newMute;
|
||||||
if (inChatList() && unreadCount) {
|
if (inChatList(Dialogs::Mode::All)) {
|
||||||
App::histories().unreadMuteChanged(unreadCount, newMute);
|
if (_unreadCount) {
|
||||||
|
App::histories().unreadMuteChanged(_unreadCount, newMute);
|
||||||
if (App::wnd()) App::wnd()->updateCounter();
|
if (App::wnd()) App::wnd()->updateCounter();
|
||||||
}
|
}
|
||||||
|
Notify::historyMuteUpdated(this);
|
||||||
|
}
|
||||||
updateChatListEntry();
|
updateChatListEntry();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1881,12 +1884,12 @@ void History::getNextScrollTopItem(HistoryBlock *block, int32 i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::addUnreadBar() {
|
void History::addUnreadBar() {
|
||||||
if (unreadBar || !showFrom || showFrom->detached() || !unreadCount) return;
|
if (unreadBar || !showFrom || showFrom->detached() || !unreadCount()) return;
|
||||||
|
|
||||||
int32 count = unreadCount;
|
int32 count = unreadCount();
|
||||||
if (peer->migrateTo()) {
|
if (peer->migrateTo()) {
|
||||||
if (History *h = App::historyLoaded(peer->migrateTo()->id)) {
|
if (History *h = App::historyLoaded(peer->migrateTo()->id)) {
|
||||||
count += h->unreadCount;
|
count += h->unreadCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
showFrom->setUnreadBarCount(count);
|
showFrom->setUnreadBarCount(count);
|
||||||
|
@ -2014,12 +2017,12 @@ bool History::isReadyFor(MsgId msgId, MsgId &fixInScrollMsgId, int32 &fixInScrol
|
||||||
if (msgId == ShowAtUnreadMsgId) {
|
if (msgId == ShowAtUnreadMsgId) {
|
||||||
if (peer->migrateFrom()) { // old group history
|
if (peer->migrateFrom()) { // old group history
|
||||||
if (History *h = App::historyLoaded(peer->migrateFrom()->id)) {
|
if (History *h = App::historyLoaded(peer->migrateFrom()->id)) {
|
||||||
if (h->unreadCount) {
|
if (h->unreadCount()) {
|
||||||
return h->isReadyFor(msgId, fixInScrollMsgId, fixInScrollMsgTop);
|
return h->isReadyFor(msgId, fixInScrollMsgId, fixInScrollMsgTop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (unreadCount) {
|
if (unreadCount()) {
|
||||||
if (!isEmpty()) {
|
if (!isEmpty()) {
|
||||||
return (loadedAtTop() || minMsgId() <= inboxReadBefore) && (loadedAtBottom() || maxMsgId() >= inboxReadBefore);
|
return (loadedAtTop() || minMsgId() <= inboxReadBefore) && (loadedAtBottom() || maxMsgId() >= inboxReadBefore);
|
||||||
}
|
}
|
||||||
|
@ -2045,7 +2048,7 @@ void History::getReadyFor(MsgId msgId, MsgId &fixInScrollMsgId, int32 &fixInScro
|
||||||
}
|
}
|
||||||
if (msgId == ShowAtUnreadMsgId && peer->migrateFrom()) {
|
if (msgId == ShowAtUnreadMsgId && peer->migrateFrom()) {
|
||||||
if (History *h = App::historyLoaded(peer->migrateFrom()->id)) {
|
if (History *h = App::historyLoaded(peer->migrateFrom()->id)) {
|
||||||
if (h->unreadCount) {
|
if (h->unreadCount()) {
|
||||||
clear(true);
|
clear(true);
|
||||||
h->getReadyFor(msgId, fixInScrollMsgId, fixInScrollMsgTop);
|
h->getReadyFor(msgId, fixInScrollMsgId, fixInScrollMsgTop);
|
||||||
return;
|
return;
|
||||||
|
@ -2084,12 +2087,12 @@ void History::setLastMessage(HistoryItem *msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::setChatsListDate(const QDateTime &date) {
|
void History::setChatsListDate(const QDateTime &date) {
|
||||||
bool updateDialog = (App::main() && (!peer->isChannel() || peer->asChannel()->amIn() || !_chatListLinks.isEmpty()));
|
bool updateDialog = (App::main() && (!peer->isChannel() || peer->asChannel()->amIn() || inChatList(Dialogs::Mode::All)));
|
||||||
if (peer->migrateTo() && _chatListLinks.isEmpty()) {
|
if (peer->migrateTo() && !inChatList(Dialogs::Mode::All)) {
|
||||||
updateDialog = false;
|
updateDialog = false;
|
||||||
}
|
}
|
||||||
if (!lastMsgDate.isNull() && lastMsgDate >= date) {
|
if (!lastMsgDate.isNull() && lastMsgDate >= date) {
|
||||||
if (!updateDialog || !_chatListLinks.isEmpty()) {
|
if (!updateDialog || !inChatList(Dialogs::Mode::All)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2225,61 +2228,64 @@ void History::clearOnDestroy() {
|
||||||
clearBlocks(false);
|
clearBlocks(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPair<int32, int32> History::adjustByPosInChatsList(Dialogs::IndexedList *indexed) {
|
QPair<int32, int32> History::adjustByPosInChatList(Dialogs::Mode list, Dialogs::IndexedList *indexed) {
|
||||||
t_assert(indexed != nullptr);
|
t_assert(indexed != nullptr);
|
||||||
Dialogs::Row *lnk = mainChatListLink();
|
Dialogs::Row *lnk = mainChatListLink(list);
|
||||||
int32 movedFrom = lnk->pos() * st::dlgHeight;
|
int32 movedFrom = lnk->pos() * st::dlgHeight;
|
||||||
indexed->adjustByPos(_chatListLinks);
|
indexed->adjustByPos(chatListLinks(list));
|
||||||
int32 movedTo = lnk->pos() * st::dlgHeight;
|
int32 movedTo = lnk->pos() * st::dlgHeight;
|
||||||
return qMakePair(movedFrom, movedTo);
|
return qMakePair(movedFrom, movedTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
int History::posInChatList() const {
|
int History::posInChatList(Dialogs::Mode list) const {
|
||||||
return mainChatListLink()->pos();
|
return mainChatListLink(list)->pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
Dialogs::Row *History::addToChatList(Dialogs::IndexedList *indexed) {
|
Dialogs::Row *History::addToChatList(Dialogs::Mode list, Dialogs::IndexedList *indexed) {
|
||||||
t_assert(indexed != nullptr);
|
t_assert(indexed != nullptr);
|
||||||
if (!inChatList()) {
|
if (!inChatList(list)) {
|
||||||
_chatListLinks = indexed->addToEnd(this);
|
chatListLinks(list) = indexed->addToEnd(this);
|
||||||
if (unreadCount) {
|
if (list == Dialogs::Mode::All && unreadCount()) {
|
||||||
App::histories().unreadIncrement(unreadCount, mute);
|
App::histories().unreadIncrement(unreadCount(), mute());
|
||||||
if (App::wnd()) App::wnd()->updateCounter();
|
if (App::wnd()) App::wnd()->updateCounter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mainChatListLink();
|
return mainChatListLink(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::removeFromChatList(Dialogs::IndexedList *indexed) {
|
void History::removeFromChatList(Dialogs::Mode list, Dialogs::IndexedList *indexed) {
|
||||||
t_assert(indexed != nullptr);
|
t_assert(indexed != nullptr);
|
||||||
if (inChatList()) {
|
if (inChatList(list)) {
|
||||||
indexed->del(peer);
|
indexed->del(peer);
|
||||||
_chatListLinks.clear();
|
chatListLinks(list).clear();
|
||||||
if (unreadCount) {
|
if (list == Dialogs::Mode::All && unreadCount()) {
|
||||||
App::histories().unreadIncrement(-unreadCount, mute);
|
App::histories().unreadIncrement(-unreadCount(), mute());
|
||||||
if (App::wnd()) App::wnd()->updateCounter();
|
if (App::wnd()) App::wnd()->updateCounter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::removeChatListEntryByLetter(QChar letter) {
|
void History::removeChatListEntryByLetter(Dialogs::Mode list, QChar letter) {
|
||||||
t_assert(letter != 0);
|
t_assert(letter != 0);
|
||||||
if (inChatList()) {
|
if (inChatList(list)) {
|
||||||
_chatListLinks.remove(letter);
|
chatListLinks(list).remove(letter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::addChatListEntryByLetter(QChar letter, Dialogs::Row *row) {
|
void History::addChatListEntryByLetter(Dialogs::Mode list, QChar letter, Dialogs::Row *row) {
|
||||||
t_assert(letter != 0);
|
t_assert(letter != 0);
|
||||||
if (inChatList()) {
|
if (inChatList(list)) {
|
||||||
_chatListLinks.insert(letter, row);
|
chatListLinks(list).insert(letter, row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::updateChatListEntry() const {
|
void History::updateChatListEntry() const {
|
||||||
if (MainWidget *m = App::main()) {
|
if (MainWidget *m = App::main()) {
|
||||||
if (inChatList()) {
|
if (inChatList(Dialogs::Mode::All)) {
|
||||||
m->dlgUpdated(mainChatListLink());
|
m->dlgUpdated(Dialogs::Mode::All, mainChatListLink(Dialogs::Mode::All));
|
||||||
|
if (inChatList(Dialogs::Mode::Important)) {
|
||||||
|
m->dlgUpdated(Dialogs::Mode::Important, mainChatListLink(Dialogs::Mode::Important));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2986,8 +2992,8 @@ void HistoryItem::destroy() {
|
||||||
history()->clearLastKeyboard();
|
history()->clearLastKeyboard();
|
||||||
if (App::main()) App::main()->updateBotKeyboard(history());
|
if (App::main()) App::main()->updateBotKeyboard(history());
|
||||||
}
|
}
|
||||||
if ((!out() || isPost()) && unread() && history()->unreadCount > 0) {
|
if ((!out() || isPost()) && unread() && history()->unreadCount() > 0) {
|
||||||
history()->setUnreadCount(history()->unreadCount - 1);
|
history()->setUnreadCount(history()->unreadCount() - 1);
|
||||||
}
|
}
|
||||||
Global::RefPendingRepaintItems().remove(this);
|
Global::RefPendingRepaintItems().remove(this);
|
||||||
delete this;
|
delete this;
|
||||||
|
|
|
@ -65,6 +65,9 @@ public:
|
||||||
int32 unreadBadge() const {
|
int32 unreadBadge() const {
|
||||||
return _unreadFull - (cIncludeMuted() ? 0 : _unreadMuted);
|
return _unreadFull - (cIncludeMuted() ? 0 : _unreadMuted);
|
||||||
}
|
}
|
||||||
|
int32 unreadMutedCount() const {
|
||||||
|
return _unreadMuted;
|
||||||
|
}
|
||||||
bool unreadOnlyMuted() const {
|
bool unreadOnlyMuted() const {
|
||||||
return cIncludeMuted() ? (_unreadMuted >= _unreadFull) : false;
|
return cIncludeMuted() ? (_unreadMuted >= _unreadFull) : false;
|
||||||
}
|
}
|
||||||
|
@ -249,7 +252,13 @@ public:
|
||||||
|
|
||||||
HistoryItem *lastImportantMessage() const;
|
HistoryItem *lastImportantMessage() const;
|
||||||
|
|
||||||
|
int unreadCount() const {
|
||||||
|
return _unreadCount;
|
||||||
|
}
|
||||||
void setUnreadCount(int newUnreadCount, bool psUpdate = true);
|
void setUnreadCount(int newUnreadCount, bool psUpdate = true);
|
||||||
|
bool mute() const {
|
||||||
|
return _mute;
|
||||||
|
}
|
||||||
void setMute(bool newMute);
|
void setMute(bool newMute);
|
||||||
void getNextShowFrom(HistoryBlock *block, int i);
|
void getNextShowFrom(HistoryBlock *block, int i);
|
||||||
void addUnreadBar();
|
void addUnreadBar();
|
||||||
|
@ -266,18 +275,18 @@ public:
|
||||||
void fixLastMessage(bool wasAtBottom);
|
void fixLastMessage(bool wasAtBottom);
|
||||||
|
|
||||||
void setChatsListDate(const QDateTime &date);
|
void setChatsListDate(const QDateTime &date);
|
||||||
QPair<int32, int32> adjustByPosInChatsList(Dialogs::IndexedList *indexed);
|
|
||||||
uint64 sortKeyInChatList() const {
|
uint64 sortKeyInChatList() const {
|
||||||
return _sortKeyInChatList;
|
return _sortKeyInChatList;
|
||||||
}
|
}
|
||||||
bool inChatList() const {
|
QPair<int32, int32> adjustByPosInChatList(Dialogs::Mode list, Dialogs::IndexedList *indexed);
|
||||||
return !_chatListLinks.isEmpty();
|
bool inChatList(Dialogs::Mode list) const {
|
||||||
|
return !chatListLinks(list).isEmpty();
|
||||||
}
|
}
|
||||||
int posInChatList() const;
|
int posInChatList(Dialogs::Mode list) const;
|
||||||
Dialogs::Row *addToChatList(Dialogs::IndexedList *indexed);
|
Dialogs::Row *addToChatList(Dialogs::Mode list, Dialogs::IndexedList *indexed);
|
||||||
void removeFromChatList(Dialogs::IndexedList *indexed);
|
void removeFromChatList(Dialogs::Mode list, Dialogs::IndexedList *indexed);
|
||||||
void removeChatListEntryByLetter(QChar letter);
|
void removeChatListEntryByLetter(Dialogs::Mode list, QChar letter);
|
||||||
void addChatListEntryByLetter(QChar letter, Dialogs::Row *row);
|
void addChatListEntryByLetter(Dialogs::Mode list, QChar letter, Dialogs::Row *row);
|
||||||
void updateChatListEntry() const;
|
void updateChatListEntry() const;
|
||||||
|
|
||||||
MsgId minMsgId() const;
|
MsgId minMsgId() const;
|
||||||
|
@ -334,7 +343,6 @@ public:
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
int32 msgCount = 0;
|
int32 msgCount = 0;
|
||||||
int32 unreadCount = 0;
|
|
||||||
MsgId inboxReadBefore = 1;
|
MsgId inboxReadBefore = 1;
|
||||||
MsgId outboxReadBefore = 1;
|
MsgId outboxReadBefore = 1;
|
||||||
HistoryItem *showFrom = nullptr;
|
HistoryItem *showFrom = nullptr;
|
||||||
|
@ -412,8 +420,6 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bool mute;
|
|
||||||
|
|
||||||
bool lastKeyboardInited = false;
|
bool lastKeyboardInited = false;
|
||||||
bool lastKeyboardUsed = false;
|
bool lastKeyboardUsed = false;
|
||||||
MsgId lastKeyboardId = 0;
|
MsgId lastKeyboardId = 0;
|
||||||
|
@ -536,11 +542,19 @@ private:
|
||||||
return ~QFlags<Flags::enum_type>(f);
|
return ~QFlags<Flags::enum_type>(f);
|
||||||
}
|
}
|
||||||
Flags _flags;
|
Flags _flags;
|
||||||
|
bool _mute;
|
||||||
|
int32 _unreadCount = 0;
|
||||||
|
|
||||||
Dialogs::RowsByLetter _chatListLinks;
|
Dialogs::RowsByLetter _chatListLinks[2];
|
||||||
Dialogs::Row *mainChatListLink() const {
|
Dialogs::RowsByLetter &chatListLinks(Dialogs::Mode list) {
|
||||||
auto it = _chatListLinks.constFind(0);
|
return _chatListLinks[static_cast<int>(list)];
|
||||||
t_assert(it != _chatListLinks.cend());
|
}
|
||||||
|
const Dialogs::RowsByLetter &chatListLinks(Dialogs::Mode list) const {
|
||||||
|
return _chatListLinks[static_cast<int>(list)];
|
||||||
|
}
|
||||||
|
Dialogs::Row *mainChatListLink(Dialogs::Mode list) const {
|
||||||
|
auto it = chatListLinks(list).constFind(0);
|
||||||
|
t_assert(it != chatListLinks(list).cend());
|
||||||
return it.value();
|
return it.value();
|
||||||
}
|
}
|
||||||
uint64 _sortKeyInChatList = 0; // like ((unixtime) << 32) | (incremented counter)
|
uint64 _sortKeyInChatList = 0; // like ((unixtime) << 32) | (incremented counter)
|
||||||
|
|
|
@ -3270,7 +3270,7 @@ void HistoryWidget::notify_migrateUpdated(PeerData *peer) {
|
||||||
showHistory(peer->migrateTo()->id, (_showAtMsgId > 0) ? (-_showAtMsgId) : _showAtMsgId, true);
|
showHistory(peer->migrateTo()->id, (_showAtMsgId > 0) ? (-_showAtMsgId) : _showAtMsgId, true);
|
||||||
} else if ((_migrated ? _migrated->peer : 0) != peer->migrateFrom()) {
|
} else if ((_migrated ? _migrated->peer : 0) != peer->migrateFrom()) {
|
||||||
History *migrated = peer->migrateFrom() ? App::history(peer->migrateFrom()->id) : 0;
|
History *migrated = peer->migrateFrom() ? App::history(peer->migrateFrom()->id) : 0;
|
||||||
if (_migrated || (migrated && migrated->unreadCount > 0)) {
|
if (_migrated || (migrated && migrated->unreadCount() > 0)) {
|
||||||
showHistory(peer->id, peer->migrateFrom() ? _showAtMsgId : ((_showAtMsgId < 0 && -_showAtMsgId < ServerMaxMsgId) ? ShowAtUnreadMsgId : _showAtMsgId), true);
|
showHistory(peer->id, peer->migrateFrom() ? _showAtMsgId : ((_showAtMsgId < 0 && -_showAtMsgId < ServerMaxMsgId) ? ShowAtUnreadMsgId : _showAtMsgId), true);
|
||||||
} else {
|
} else {
|
||||||
_migrated = migrated;
|
_migrated = migrated;
|
||||||
|
@ -3831,7 +3831,7 @@ void HistoryWidget::updateFieldSubmitSettings() {
|
||||||
void HistoryWidget::updateNotifySettings() {
|
void HistoryWidget::updateNotifySettings() {
|
||||||
if (!_peer || !_peer->isChannel()) return;
|
if (!_peer || !_peer->isChannel()) return;
|
||||||
|
|
||||||
_muteUnmute.setText(lang(_history->mute ? lng_channel_unmute : lng_channel_mute));
|
_muteUnmute.setText(lang(_history->mute() ? lng_channel_unmute : lng_channel_mute));
|
||||||
if (_peer->notify != UnknownNotifySettings) {
|
if (_peer->notify != UnknownNotifySettings) {
|
||||||
_silent.setChecked(_peer->notify != EmptyNotifySettings && (_peer->notify->flags & MTPDpeerNotifySettings::Flag::f_silent));
|
_silent.setChecked(_peer->notify != EmptyNotifySettings && (_peer->notify->flags & MTPDpeerNotifySettings::Flag::f_silent));
|
||||||
if (_silent.isHidden() && hasSilentToggle()) {
|
if (_silent.isHidden() && hasSilentToggle()) {
|
||||||
|
@ -4211,7 +4211,7 @@ void HistoryWidget::newUnreadMsg(History *history, HistoryItem *item) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
App::wnd()->notifySchedule(history, item);
|
App::wnd()->notifySchedule(history, item);
|
||||||
history->setUnreadCount(history->unreadCount + 1);
|
history->setUnreadCount(history->unreadCount() + 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_history == history) {
|
if (_history == history) {
|
||||||
|
@ -4220,7 +4220,7 @@ void HistoryWidget::newUnreadMsg(History *history, HistoryItem *item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
App::wnd()->notifySchedule(history, item);
|
App::wnd()->notifySchedule(history, item);
|
||||||
history->setUnreadCount(history->unreadCount + 1);
|
history->setUnreadCount(history->unreadCount() + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4339,7 +4339,7 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
|
||||||
}
|
}
|
||||||
_firstLoadRequest = 0;
|
_firstLoadRequest = 0;
|
||||||
if (_history->loadedAtTop()) {
|
if (_history->loadedAtTop()) {
|
||||||
if (_history->unreadCount > count) {
|
if (_history->unreadCount() > count) {
|
||||||
_history->setUnreadCount(count);
|
_history->setUnreadCount(count);
|
||||||
}
|
}
|
||||||
if (_history->isEmpty() && count > 0) {
|
if (_history->isEmpty() && count > 0) {
|
||||||
|
@ -4373,7 +4373,7 @@ void HistoryWidget::messagesReceived(PeerData *peer, const MTPmessages_Messages
|
||||||
}
|
}
|
||||||
_firstLoadRequest = 0;
|
_firstLoadRequest = 0;
|
||||||
if (_history->loadedAtTop()) {
|
if (_history->loadedAtTop()) {
|
||||||
if (_history->unreadCount > count) {
|
if (_history->unreadCount() > count) {
|
||||||
_history->setUnreadCount(count);
|
_history->setUnreadCount(count);
|
||||||
}
|
}
|
||||||
if (_history->isEmpty() && count > 0) {
|
if (_history->isEmpty() && count > 0) {
|
||||||
|
@ -4429,12 +4429,12 @@ void HistoryWidget::firstLoadMessages() {
|
||||||
PeerData *from = _peer;
|
PeerData *from = _peer;
|
||||||
int32 offset_id = 0, offset = 0, loadCount = MessagesPerPage;
|
int32 offset_id = 0, offset = 0, loadCount = MessagesPerPage;
|
||||||
if (_showAtMsgId == ShowAtUnreadMsgId) {
|
if (_showAtMsgId == ShowAtUnreadMsgId) {
|
||||||
if (_migrated && _migrated->unreadCount) {
|
if (_migrated && _migrated->unreadCount()) {
|
||||||
_history->getReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
|
_history->getReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
|
||||||
from = _migrated->peer;
|
from = _migrated->peer;
|
||||||
offset = -loadCount / 2;
|
offset = -loadCount / 2;
|
||||||
offset_id = _migrated->inboxReadBefore;
|
offset_id = _migrated->inboxReadBefore;
|
||||||
} else if (_history->unreadCount) {
|
} else if (_history->unreadCount()) {
|
||||||
_history->getReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
|
_history->getReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
|
||||||
offset = -loadCount / 2;
|
offset = -loadCount / 2;
|
||||||
offset_id = _history->inboxReadBefore;
|
offset_id = _history->inboxReadBefore;
|
||||||
|
@ -4552,11 +4552,11 @@ void HistoryWidget::delayedShowAt(MsgId showAtMsgId) {
|
||||||
PeerData *from = _peer;
|
PeerData *from = _peer;
|
||||||
int32 offset_id = 0, offset = 0, loadCount = MessagesPerPage;
|
int32 offset_id = 0, offset = 0, loadCount = MessagesPerPage;
|
||||||
if (_delayedShowAtMsgId == ShowAtUnreadMsgId) {
|
if (_delayedShowAtMsgId == ShowAtUnreadMsgId) {
|
||||||
if (_migrated && _migrated->unreadCount) {
|
if (_migrated && _migrated->unreadCount()) {
|
||||||
from = _migrated->peer;
|
from = _migrated->peer;
|
||||||
offset = -loadCount / 2;
|
offset = -loadCount / 2;
|
||||||
offset_id = _migrated->inboxReadBefore;
|
offset_id = _migrated->inboxReadBefore;
|
||||||
} else if (_history->unreadCount) {
|
} else if (_history->unreadCount()) {
|
||||||
offset = -loadCount / 2;
|
offset = -loadCount / 2;
|
||||||
offset_id = _history->inboxReadBefore;
|
offset_id = _history->inboxReadBefore;
|
||||||
} else {
|
} else {
|
||||||
|
@ -4872,7 +4872,7 @@ bool HistoryWidget::joinFail(const RPCError &error, mtpRequestId req) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onMuteUnmute() {
|
void HistoryWidget::onMuteUnmute() {
|
||||||
App::main()->updateNotifySetting(_peer, _history->mute ? NotifySettingSetNotify : NotifySettingSetMuted);
|
App::main()->updateNotifySetting(_peer, _history->mute() ? NotifySettingSetNotify : NotifySettingSetMuted);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onBroadcastSilentChange() {
|
void HistoryWidget::onBroadcastSilentChange() {
|
||||||
|
@ -6720,10 +6720,10 @@ void HistoryWidget::addMessagesToBack(PeerData *peer, const QVector<MTPMessage>
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::countHistoryShowFrom() {
|
void HistoryWidget::countHistoryShowFrom() {
|
||||||
if (_migrated && _showAtMsgId == ShowAtUnreadMsgId && _migrated->unreadCount) {
|
if (_migrated && _showAtMsgId == ShowAtUnreadMsgId && _migrated->unreadCount()) {
|
||||||
_migrated->updateShowFrom();
|
_migrated->updateShowFrom();
|
||||||
}
|
}
|
||||||
if ((_migrated && _migrated->showFrom) || _showAtMsgId != ShowAtUnreadMsgId || !_history->unreadCount) {
|
if ((_migrated && _migrated->showFrom) || _showAtMsgId != ShowAtUnreadMsgId || !_history->unreadCount()) {
|
||||||
_history->showFrom = 0;
|
_history->showFrom = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,7 @@ private:
|
||||||
Gif,
|
Gif,
|
||||||
Article,
|
Article,
|
||||||
Contact,
|
Contact,
|
||||||
|
Geo,
|
||||||
Venue,
|
Venue,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -604,6 +604,7 @@ namespace {
|
||||||
dbiAutoPlay = 0x37,
|
dbiAutoPlay = 0x37,
|
||||||
dbiAdaptiveForWide = 0x38,
|
dbiAdaptiveForWide = 0x38,
|
||||||
dbiHiddenPinnedMessages = 0x39,
|
dbiHiddenPinnedMessages = 0x39,
|
||||||
|
dbiDialogsMode = 0x40,
|
||||||
|
|
||||||
dbiEncryptedWithSalt = 333,
|
dbiEncryptedWithSalt = 333,
|
||||||
dbiEncrypted = 444,
|
dbiEncrypted = 444,
|
||||||
|
@ -981,6 +982,22 @@ namespace {
|
||||||
cSetAutoPlayGif(gif == 1);
|
cSetAutoPlayGif(gif == 1);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case dbiDialogsMode: {
|
||||||
|
qint32 enabled, modeInt;
|
||||||
|
stream >> enabled >> modeInt;
|
||||||
|
if (!_checkStreamStatus(stream)) return false;
|
||||||
|
|
||||||
|
Global::SetDialogsModeEnabled(enabled == 1);
|
||||||
|
Dialogs::Mode mode = Dialogs::Mode::All;
|
||||||
|
if (enabled) {
|
||||||
|
mode = static_cast<Dialogs::Mode>(modeInt);
|
||||||
|
if (mode != Dialogs::Mode::All && mode != Dialogs::Mode::Important) {
|
||||||
|
mode = Dialogs::Mode::All;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Global::SetDialogsMode(mode);
|
||||||
|
} break;
|
||||||
|
|
||||||
case dbiIncludeMuted: {
|
case dbiIncludeMuted: {
|
||||||
qint32 v;
|
qint32 v;
|
||||||
stream >> v;
|
stream >> v;
|
||||||
|
@ -1578,6 +1595,7 @@ namespace {
|
||||||
size += sizeof(quint32) + sizeof(qint32) + (cRecentStickersPreload().isEmpty() ? cGetRecentStickers().size() : cRecentStickersPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
size += sizeof(quint32) + sizeof(qint32) + (cRecentStickersPreload().isEmpty() ? cGetRecentStickers().size() : cRecentStickersPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
||||||
size += sizeof(quint32) + Serialize::stringSize(cDialogLastPath());
|
size += sizeof(quint32) + Serialize::stringSize(cDialogLastPath());
|
||||||
size += sizeof(quint32) + 3 * sizeof(qint32);
|
size += sizeof(quint32) + 3 * sizeof(qint32);
|
||||||
|
size += sizeof(quint32) + 2 * sizeof(qint32);
|
||||||
if (!Global::HiddenPinnedMessages().isEmpty()) {
|
if (!Global::HiddenPinnedMessages().isEmpty()) {
|
||||||
size += sizeof(quint32) + sizeof(qint32) + Global::HiddenPinnedMessages().size() * (sizeof(PeerId) + sizeof(MsgId));
|
size += sizeof(quint32) + sizeof(qint32) + Global::HiddenPinnedMessages().size() * (sizeof(PeerId) + sizeof(MsgId));
|
||||||
}
|
}
|
||||||
|
@ -1601,6 +1619,7 @@ namespace {
|
||||||
data.stream << quint32(dbiDialogLastPath) << cDialogLastPath();
|
data.stream << quint32(dbiDialogLastPath) << cDialogLastPath();
|
||||||
data.stream << quint32(dbiSongVolume) << qint32(qRound(cSongVolume() * 1e6));
|
data.stream << quint32(dbiSongVolume) << qint32(qRound(cSongVolume() * 1e6));
|
||||||
data.stream << quint32(dbiAutoDownload) << qint32(cAutoDownloadPhoto()) << qint32(cAutoDownloadAudio()) << qint32(cAutoDownloadGif());
|
data.stream << quint32(dbiAutoDownload) << qint32(cAutoDownloadPhoto()) << qint32(cAutoDownloadAudio()) << qint32(cAutoDownloadGif());
|
||||||
|
data.stream << quint32(dbiDialogsMode) << qint32(Global::DialogsModeEnabled() ? 1 : 0) << static_cast<qint32>(Global::DialogsMode());
|
||||||
data.stream << quint32(dbiAutoPlay) << qint32(cAutoPlayGif() ? 1 : 0);
|
data.stream << quint32(dbiAutoPlay) << qint32(cAutoPlayGif() ? 1 : 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -844,6 +844,10 @@ void MainWidget::notify_inlineItemLayoutChanged(const InlineBots::Layout::ItemBa
|
||||||
history.notify_inlineItemLayoutChanged(layout);
|
history.notify_inlineItemLayoutChanged(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWidget::notify_historyMuteUpdated(History *history) {
|
||||||
|
dialogs.notify_historyMuteUpdated(history);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWidget::notify_handlePendingHistoryUpdate() {
|
void MainWidget::notify_handlePendingHistoryUpdate() {
|
||||||
history.notify_handlePendingHistoryUpdate();
|
history.notify_handlePendingHistoryUpdate();
|
||||||
}
|
}
|
||||||
|
@ -1509,7 +1513,7 @@ void MainWidget::saveRecentHashtags(const QString &text) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::readServerHistory(History *hist, bool force) {
|
void MainWidget::readServerHistory(History *hist, bool force) {
|
||||||
if (!hist || (!force && !hist->unreadCount)) return;
|
if (!hist || (!force && !hist->unreadCount())) return;
|
||||||
|
|
||||||
MsgId upTo = hist->inboxRead(0);
|
MsgId upTo = hist->inboxRead(0);
|
||||||
if (hist->isChannel() && !hist->peer->asChannel()->amIn()) {
|
if (hist->isChannel() && !hist->peer->asChannel()->amIn()) {
|
||||||
|
@ -2665,14 +2669,18 @@ QRect MainWidget::historyRect() const {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::dlgUpdated(Dialogs::Row *row) {
|
void MainWidget::dlgUpdated() {
|
||||||
if (row) {
|
if (_peerInStack) {
|
||||||
dialogs.dlgUpdated(row);
|
|
||||||
} else if (_peerInStack) {
|
|
||||||
dialogs.dlgUpdated(App::history(_peerInStack->id), _msgIdInStack);
|
dialogs.dlgUpdated(App::history(_peerInStack->id), _msgIdInStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWidget::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) {
|
||||||
|
if (row) {
|
||||||
|
dialogs.dlgUpdated(list, row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWidget::dlgUpdated(History *row, MsgId msgId) {
|
void MainWidget::dlgUpdated(History *row, MsgId msgId) {
|
||||||
if (!row) return;
|
if (!row) return;
|
||||||
if (msgId < 0 && -msgId < ServerMaxMsgId && row->peer->migrateFrom()) {
|
if (msgId < 0 && -msgId < ServerMaxMsgId && row->peer->migrateFrom()) {
|
||||||
|
@ -3113,7 +3121,7 @@ void MainWidget::gotChannelDifference(ChannelData *channel, const MTPupdates_Cha
|
||||||
h->setLastMessage(item);
|
h->setLastMessage(item);
|
||||||
}
|
}
|
||||||
int32 unreadCount = h->isMegagroup() ? d.vunread_count.v : d.vunread_important_count.v;
|
int32 unreadCount = h->isMegagroup() ? d.vunread_count.v : d.vunread_important_count.v;
|
||||||
if (unreadCount >= h->unreadCount) {
|
if (unreadCount >= h->unreadCount()) {
|
||||||
h->setUnreadCount(unreadCount, false);
|
h->setUnreadCount(unreadCount, false);
|
||||||
h->inboxReadBefore = d.vread_inbox_max_id.v + 1;
|
h->inboxReadBefore = d.vread_inbox_max_id.v + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,7 +260,8 @@ public:
|
||||||
|
|
||||||
void createDialog(History *history);
|
void createDialog(History *history);
|
||||||
void removeDialog(History *history);
|
void removeDialog(History *history);
|
||||||
void dlgUpdated(Dialogs::Row *row = nullptr);
|
void dlgUpdated();
|
||||||
|
void dlgUpdated(Dialogs::Mode list, Dialogs::Row *row);
|
||||||
void dlgUpdated(History *row, MsgId msgId);
|
void dlgUpdated(History *row, MsgId msgId);
|
||||||
|
|
||||||
void windowShown();
|
void windowShown();
|
||||||
|
@ -467,6 +468,7 @@ public:
|
||||||
void notify_clipStopperHidden(ClipStopperType type);
|
void notify_clipStopperHidden(ClipStopperType type);
|
||||||
void notify_historyItemLayoutChanged(const HistoryItem *item);
|
void notify_historyItemLayoutChanged(const HistoryItem *item);
|
||||||
void notify_inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout);
|
void notify_inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout);
|
||||||
|
void notify_historyMuteUpdated(History *history);
|
||||||
void notify_handlePendingHistoryUpdate();
|
void notify_handlePendingHistoryUpdate();
|
||||||
|
|
||||||
void cmd_search();
|
void cmd_search();
|
||||||
|
|
|
@ -823,14 +823,22 @@ void SettingsInner::keyPressEvent(QKeyEvent *e) {
|
||||||
} else {
|
} else {
|
||||||
Global::RefDebugLoggingFlags() |= DebugLogging::FileLoaderFlag;
|
Global::RefDebugLoggingFlags() |= DebugLogging::FileLoaderFlag;
|
||||||
}
|
}
|
||||||
Ui::showLayer(new InformBox(DebugLogging::FileLoader() ? "Enabled file download logging" : "Disabled file download logging"));
|
Ui::showLayer(new InformBox(DebugLogging::FileLoader() ? qsl("Enabled file download logging") : qsl("Disabled file download logging")));
|
||||||
} else if (str == qstr("crashplease")) {
|
} else if (str == qstr("crashplease")) {
|
||||||
t_assert(!"Crashed in Settings!");
|
t_assert(!"Crashed in Settings!");
|
||||||
|
} else if (str == qstr("workmode")) {
|
||||||
|
QString text = Global::DialogsModeEnabled() ? qsl("Disable work mode?") : qsl("Enable work mode?");
|
||||||
|
auto box = std_::make_unique<ConfirmBox>(text);
|
||||||
|
connect(box.get(), SIGNAL(confirmed()), App::app(), SLOT(onSwitchWorkMode()));
|
||||||
|
Ui::showLayer(box.release());
|
||||||
|
from = size;
|
||||||
|
break;
|
||||||
} else if (
|
} else if (
|
||||||
qsl("debugmode").startsWith(str) ||
|
qsl("debugmode").startsWith(str) ||
|
||||||
qsl("testmode").startsWith(str) ||
|
qsl("testmode").startsWith(str) ||
|
||||||
qsl("loadlang").startsWith(str) ||
|
qsl("loadlang").startsWith(str) ||
|
||||||
qsl("debugfiles").startsWith(str) ||
|
qsl("debugfiles").startsWith(str) ||
|
||||||
|
qsl("workmode").startsWith(str) ||
|
||||||
qsl("crashplease").startsWith(str)) {
|
qsl("crashplease").startsWith(str)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
35
Telegram/ui/buttons/peer_avatar_button.cpp
Normal file
35
Telegram/ui/buttons/peer_avatar_button.cpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "ui/buttons/peer_avatar_button.h"
|
||||||
|
|
||||||
|
PeerAvatarButton::PeerAvatarButton(QWidget *parent, PeerData *peer, const style::PeerAvatarButton &st) : Button(parent)
|
||||||
|
, _peer(peer)
|
||||||
|
, _st(st) {
|
||||||
|
resize(_st.size, _st.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PeerAvatarButton::paintEvent(QPaintEvent *e) {
|
||||||
|
if (_peer) {
|
||||||
|
Painter p(this);
|
||||||
|
_peer->paintUserpic(p, _st.photoSize, (_st.size - _st.photoSize) / 2, (_st.size - _st.photoSize) / 2);
|
||||||
|
}
|
||||||
|
}
|
40
Telegram/ui/buttons/peer_avatar_button.h
Normal file
40
Telegram/ui/buttons/peer_avatar_button.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ui/button.h"
|
||||||
|
#include "ui/style.h"
|
||||||
|
#include "structs.h"
|
||||||
|
|
||||||
|
class PeerAvatarButton : public Button {
|
||||||
|
public:
|
||||||
|
PeerAvatarButton(QWidget *parent, PeerData *peer, const style::PeerAvatarButton &st);
|
||||||
|
void setPeer(PeerData *peer) {
|
||||||
|
_peer = peer;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
void paintEvent(QPaintEvent *e);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PeerData *_peer;
|
||||||
|
const style::PeerAvatarButton &_st;
|
||||||
|
|
||||||
|
};
|
Loading…
Add table
Reference in a new issue