Merge branch 'dev' into drafts

Conflicts:
	Telegram/SourceFiles/dialogs/dialogs_layout.cpp
This commit is contained in:
John Preston 2016-06-03 16:44:51 +03:00
commit 307e529ccf
21 changed files with 348 additions and 158 deletions

View file

@ -949,7 +949,7 @@ dlgDateColor: #a8a8a8;
dlgDateSkip: 5px;
dlgUnreadColor: #FFF;
dlgUnreadBG: #6fc766;
dlgUnreadBG: #009ce6;//#6fc766;
dlgUnreadMutedBG: #bbb;
dlgUnreadFont: font(12px bold);
dlgUnreadHeight: 19px;

View file

@ -622,7 +622,7 @@ namespace {
ChannelData *cdata = data->asChannel();
if (minimal) {
int32 mask = MTPDchannel::Flag::f_broadcast | MTPDchannel::Flag::f_verified | MTPDchannel::Flag::f_megagroup | MTPDchannel::Flag::f_democracy;
auto mask = MTPDchannel::Flag::f_broadcast | MTPDchannel::Flag::f_verified | MTPDchannel::Flag::f_megagroup | MTPDchannel::Flag::f_democracy;
cdata->flags = (cdata->flags & ~mask) | (d.vflags.v & mask);
} else {
cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash);
@ -655,6 +655,9 @@ namespace {
ChannelData *cdata = data->asChannel();
cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash);
auto mask = mtpCastFlags(MTPDchannelForbidden::Flag::f_broadcast | MTPDchannelForbidden::Flag::f_megagroup);
cdata->flags = (cdata->flags & ~mask) | (mtpCastFlags(d.vflags) & mask);
cdata->setName(qs(d.vtitle), QString());
cdata->access = d.vaccess_hash.v;
@ -662,6 +665,7 @@ namespace {
cdata->date = 0;
cdata->count = 0;
cdata->isForbidden = true;
cdata->flagsUpdated();
} break;
}
if (!data) continue;

View file

@ -21,5 +21,5 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
using "basic.style";
dialogsDraft: icon {
{ "dialogs_draft", #ffffff, point(5px, 5px) },
{ "dialogs_draft", #ffffff, point(5px, 4px) },
};

View file

@ -136,6 +136,8 @@ QImage colorizeCircleHalf(int size, int half, int xoffset, style::color color) {
return result;
}
} // namepsace
void paintUnreadBadge(Painter &p, const QRect &rect, bool active, bool muted) {
int index = (active ? 0x01 : 0x00) | (muted ? 0x02 : 0x00);
int size = rect.height(), sizehalf = size / 2;
@ -157,16 +159,21 @@ void paintUnreadBadge(Painter &p, const QRect &rect, bool active, bool muted) {
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) {
void paintUnreadCount(Painter &p, const QString &text, int x, int y, style::align align, bool active, bool muted, int *outUnreadWidth) {
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;
int unreadRectLeft = x;
if ((align & Qt::AlignHorizontal_Mask) & style::al_center) {
unreadRectLeft = (x - unreadRectWidth) / 2;
} else if ((align & Qt::AlignHorizontal_Mask) & style::al_right) {
unreadRectLeft = x - unreadRectWidth;
}
int unreadRectTop = y;
if (outUnreadWidth) {
*outUnreadWidth = unreadRectWidth;
}
paintUnreadBadge(p, QRect(unreadRectLeft, unreadRectTop, unreadRectWidth, unreadRectHeight), active, muted);
@ -176,8 +183,6 @@ void paintUnreadCount(Painter &p, const QString &text, int top, int w, bool acti
p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + st::dlgUnreadTop + st::dlgUnreadFont->ascent, text);
}
} // namepsace
void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool selected, bool onlyBackground) {
auto history = row->history();
auto item = history->lastMsg;
@ -199,8 +204,11 @@ void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool sele
counter = QString::number(unread);
mutedCounter = history->mute();
}
int unreadRight = w - st::dlgPaddingHor;
int unreadTop = texttop + st::dlgHistFont->ascent - st::dlgUnreadFont->ascent - st::dlgUnreadTop;
paintUnreadCount(p, counter, unreadTop, w, active, mutedCounter, &availableWidth);
int unreadWidth = 0;
paintUnreadCount(p, counter, unreadRight, unreadTop, style::al_right, active, mutedCounter, &unreadWidth);
availableWidth -= unreadWidth + st::dlgUnreadPaddingHor;
if (!showUnreadCounter) {
st::dialogsDraft.paint(p, QPoint(w - st::dlgPaddingHor - st::dlgUnreadHeight, unreadTop), w);
}
@ -240,7 +248,8 @@ void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool o
if (mutedHidden) {
if (int32 unread = App::histories().unreadMutedCount()) {
paintUnreadCount(p, QString::number(unread), unreadTop, w, false, true, nullptr);
int unreadRight = w - st::dlgPaddingHor;
paintUnreadCount(p, QString::number(unread), unreadRight, unreadTop, style::al_right, false, true, nullptr);
}
}
}

View file

@ -35,6 +35,9 @@ public:
void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool onlyBackground);
void paintUnreadCount(Painter &p, const QString &text, int x, int y, style::align align, bool active, bool muted, int *outUnreadWidth);
void paintUnreadBadge(Painter &p, const QRect &rect, bool active, bool muted);
// This will be moved somewhere outside as soon as anyone starts using that.
class StyleSheet {
public:

View file

@ -1362,6 +1362,8 @@ void History::setUnreadCount(int newUnreadCount) {
} else if (!newUnreadCount) {
showFrom = nullptr;
inboxReadBefore = qMax(inboxReadBefore, msgIdForRead() + 1);
} else {
if (!showFrom && !unreadBar && loadedAtBottom()) updateShowFrom();
}
if (inChatList(Dialogs::Mode::All)) {
App::histories().unreadIncrement(newUnreadCount - _unreadCount, mute());
@ -1370,6 +1372,9 @@ void History::setUnreadCount(int newUnreadCount) {
}
}
_unreadCount = newUnreadCount;
if (auto main = App::main()) {
main->unreadCountChanged(this);
}
if (unreadBar) {
int32 count = _unreadCount;
if (peer->migrateTo()) {
@ -1751,6 +1756,10 @@ const ChannelHistory *History::asChannelHistory() const {
return isChannel() ? static_cast<const ChannelHistory*>(this) : 0;
}
bool History::isDisplayedEmpty() const {
return isEmpty() || (blocks.size() == 1) && blocks.front()->items.size() == 1 && blocks.front()->items.front()->isEmpty();
}
void History::clear(bool leaveItems) {
if (unreadBar) {
unreadBar = nullptr;
@ -7587,6 +7596,10 @@ void HistoryService::setMessageByAction(const MTPmessageAction &action) {
}
} break;
case mtpc_messageActionHistoryClear: {
text = QString();
} break;
case mtpc_messageActionChatDeletePhoto: {
text = isPost() ? lang(lng_action_removed_photo_channel) : lng_action_removed_photo(lt_from, from);
} break;
@ -7893,6 +7906,14 @@ void HistoryService::draw(Painter &p, const QRect &r, TextSelection selection, u
}
int32 HistoryService::resizeGetHeight_(int32 width) {
_height = displayedDateHeight();
if (auto unreadbar = Get<HistoryMessageUnreadBar>()) {
_height += unreadbar->height();
}
if (_text.isEmpty()) {
_textHeight = 0;
} else {
int32 maxwidth = _history->width;
if (Adaptive::Wide()) {
maxwidth = qMin(maxwidth, int32(st::msgMaxWidth + 2 * st::msgPhotoSkip + 2 * st::msgMargin.left()));
@ -7909,18 +7930,16 @@ int32 HistoryService::resizeGetHeight_(int32 width) {
textstyleRestore();
}
if (width >= _maxw) {
_height = _minh;
_height += _minh;
} else {
_height = _textHeight;
_height += _textHeight;
}
_height += st::msgServicePadding.top() + st::msgServicePadding.bottom() + st::msgServiceMargin.top() + st::msgServiceMargin.bottom();
if (_media) {
_height += st::msgServiceMargin.top() + _media->resizeGetHeight(_media->currentWidth());
}
_height += displayedDateHeight();
if (auto unreadbar = Get<HistoryMessageUnreadBar>()) {
_height += unreadbar->height();
}
return _height;
}

View file

@ -227,6 +227,8 @@ public:
bool isEmpty() const {
return blocks.isEmpty();
}
bool isDisplayedEmpty() const;
void clear(bool leaveItems = false);
virtual ~History();
@ -1423,6 +1425,10 @@ public:
return _flags & MTPDmessage_ClientFlag::f_attach_to_previous;
}
bool isEmpty() const {
return _text.isEmpty() && !_media;
}
void clipCallback(ClipReaderNotification notification);
virtual ~HistoryItem();

View file

@ -28,3 +28,4 @@ historyToDownPosition: point(12px, 10px);
historyToDownArrow: icon {
{ "history_down_arrow", #b9b9b9, point(14px, 19px) },
};
historyToDownPaddingTop: 10px;

View file

@ -26,3 +26,8 @@ enum DragState {
DragStatePhotoFiles = 0x02,
DragStateImage = 0x03,
};
enum class ReadServerHistoryChecks {
OnlyIfUnread,
ForceRequest,
};

View file

@ -258,6 +258,8 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
}
uint64 ms = getms();
bool historyDisplayedEmpty = (_history->isDisplayedEmpty() && (!_migrated || _migrated->isDisplayedEmpty()));
bool noHistoryDisplayed = _firstLoading || historyDisplayedEmpty;
if (!_firstLoading && _botAbout && !_botAbout->info->text.isEmpty() && _botAbout->height > 0) {
if (r.y() < _botAbout->rect.y() + _botAbout->rect.height() && r.y() + r.height() > _botAbout->rect.y()) {
textstyleSet(&st::inTextStyle);
@ -271,11 +273,11 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
textstyleRestore();
}
} else if (_firstLoading || (_history->isEmpty() && (!_migrated || _migrated->isEmpty()))) {
} else if (noHistoryDisplayed) {
QPoint dogPos((width() - st::msgDogImg.pxWidth()) / 2, ((height() - st::msgDogImg.pxHeight()) * 4) / 9);
p.drawPixmap(dogPos, *cChatDogImage());
}
if (!_firstLoading) {
if (!noHistoryDisplayed) {
adjustCurrent(r.top());
SelectedItems::const_iterator selEnd = _selected.cend();
@ -3862,6 +3864,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
if (wasHistory) _peer->asUser()->botInfo->inlineReturnPeerId = wasHistory->peer->id;
onBotStart();
}
unreadCountChanged(_history); // set _historyToEnd badge.
} else {
clearFieldText();
doneShow();
@ -4276,26 +4279,18 @@ void HistoryWidget::destroyUnreadBar() {
}
void HistoryWidget::newUnreadMsg(History *history, HistoryItem *item) {
if (App::wnd()->historyIsActive()) {
if (_history == history) {
historyWasRead();
if (_scroll.scrollTop() + 1 > _scroll.scrollTopMax()) {
destroyUnreadBar();
}
} else {
App::wnd()->notifySchedule(history, item);
history->setUnreadCount(history->unreadCount() + 1);
}
} else {
if (_history == history) {
if (_scroll.scrollTop() + 1 > _scroll.scrollTopMax()) {
destroyUnreadBar();
}
if (App::wnd()->doWeReadServerHistory()) {
historyWasRead(ReadServerHistoryChecks::ForceRequest);
return;
}
}
App::wnd()->notifySchedule(history, item);
history->setUnreadCount(history->unreadCount() + 1);
}
}
void HistoryWidget::historyToDown(History *history) {
history->forgetScrollState();
@ -4307,9 +4302,20 @@ void HistoryWidget::historyToDown(History *history) {
}
}
void HistoryWidget::historyWasRead(bool force) {
App::main()->readServerHistory(_history, force);
if (_migrated) App::main()->readServerHistory(_migrated, force);
void HistoryWidget::historyWasRead(ReadServerHistoryChecks checks) {
App::main()->readServerHistory(_history, checks);
if (_migrated) {
App::main()->readServerHistory(_migrated, ReadServerHistoryChecks::OnlyIfUnread);
}
}
void HistoryWidget::unreadCountChanged(History *history) {
if (history == _history || history == _migrated) {
updateToEndVisibility();
if (_historyToEnd) {
_historyToEnd->setUnreadCount(_history->unreadCount() + (_migrated ? _migrated->unreadCount() : 0));
}
}
}
void HistoryWidget::historyCleared(History *history) {
@ -4469,10 +4475,19 @@ void HistoryWidget::windowShown() {
resizeEvent(0);
}
bool HistoryWidget::isActive() const {
if (!_history) return true;
bool HistoryWidget::doWeReadServerHistory() const {
if (!_history || !_list) return true;
if (_firstLoadRequest || _a_show.animating()) return false;
if (_history->loadedAtBottom()) return true;
if (_history->loadedAtBottom()) {
int scrollTop = _scroll.scrollTop();
if (scrollTop + 1 > _scroll.scrollTopMax()) return true;
auto showFrom = (_migrated && _migrated->showFrom) ? _migrated->showFrom : (_history ? _history->showFrom : nullptr);
if (showFrom && !showFrom->detached()) {
int scrollBottom = scrollTop + _scroll.height();
if (scrollBottom > _list->itemTop(showFrom)) return true;
}
}
if (_history->showFrom && !_history->showFrom->detached() && _history->unreadBar) return true;
if (_migrated && _migrated->showFrom && !_migrated->showFrom->detached() && _migrated->unreadBar) return true;
return false;
@ -4604,8 +4619,15 @@ void HistoryWidget::onScroll() {
void HistoryWidget::visibleAreaUpdated() {
if (_list && !_scroll.isHidden()) {
int st = _scroll.scrollTop();
_list->visibleAreaUpdated(st, st + _scroll.height());
int scrollTop = _scroll.scrollTop();
int scrollBottom = scrollTop + _scroll.height();
_list->visibleAreaUpdated(scrollTop, scrollBottom);
if (_history->loadedAtBottom() && (_history->unreadCount() > 0 || (_migrated && _migrated->unreadCount() > 0))) {
auto showFrom = (_migrated && _migrated->showFrom) ? _migrated->showFrom : (_history ? _history->showFrom : nullptr);
if (showFrom && !showFrom->detached() && scrollBottom > _list->itemTop(showFrom) && App::wnd()->doWeReadServerHistory()) {
historyWasRead(ReadServerHistoryChecks::OnlyIfUnread);
}
}
}
}
@ -4872,13 +4894,13 @@ void HistoryWidget::onShareContact(const PeerId &peer, UserData *contact) {
}
void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, int32 userId) {
History *h = App::history(peer);
auto history = App::history(peer);
uint64 randomId = rand_value<uint64>();
FullMsgId newId(peerToChannel(peer), clientMsgId());
App::main()->readServerHistory(h, false);
fastShowAtEnd(h);
App::main()->readServerHistory(history);
fastShowAtEnd(history);
PeerData *p = App::peer(peer);
MTPDmessage::Flags flags = newMessageFlags(p) | MTPDmessage::Flag::f_media; // unread, out
@ -4904,12 +4926,12 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
h->addNewMessage(MTP_message(MTP_flags(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(peer), MTPnullFwdHeader, MTPint(), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname), MTP_int(userId)), MTPnullMarkup, MTPnullEntities, MTP_int(1), MTPint()), NewMessageUnread);
h->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), p->input, MTP_int(replyTo), MTP_inputMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, h->sendRequestId);
history->addNewMessage(MTP_message(MTP_flags(flags), MTP_int(newId.msg), MTP_int(showFromName ? MTP::authedId() : 0), peerToMTP(peer), MTPnullFwdHeader, MTPint(), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname), MTP_int(userId)), MTPnullMarkup, MTPnullEntities, MTP_int(1), MTPint()), NewMessageUnread);
history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), p->input, MTP_int(replyTo), MTP_inputMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, history->sendRequestId);
App::historyRegRandom(randomId, newId);
App::main()->finishForwarding(h, _silent.checked());
App::main()->finishForwarding(history, _silent.checked());
cancelReply(lastKeyboardUsed);
}
@ -6678,7 +6700,7 @@ void HistoryWidget::countHistoryShowFrom() {
_migrated->updateShowFrom();
}
if ((_migrated && _migrated->showFrom) || _showAtMsgId != ShowAtUnreadMsgId || !_history->unreadCount()) {
_history->showFrom = 0;
_history->showFrom = nullptr;
return;
}
_history->updateShowFrom();
@ -6768,7 +6790,22 @@ void HistoryWidget::updateBotKeyboard(History *h, bool force) {
}
void HistoryWidget::updateToEndVisibility() {
bool toEndVisible = !_a_show.animating() && _history && !_firstLoadRequest && (!_history->loadedAtBottom() || _replyReturn || _scroll.scrollTop() + st::wndMinHeight < _scroll.scrollTopMax());
auto isToEndVisible = [this]() {
if (!_history || _a_show.animating() || _firstLoadRequest) {
return false;
}
if (!_history->loadedAtBottom() || _replyReturn) {
return true;
}
if (_scroll.scrollTop() + st::wndMinHeight < _scroll.scrollTopMax()) {
return true;
}
if (_history->unreadCount() > 0 || (_migrated && _migrated->unreadCount() > 0)) {
return true;
}
return false;
};
bool toEndVisible = isToEndVisible();
if (toEndVisible && _historyToEnd->isHidden()) {
_historyToEnd->show();
} else if (!toEndVisible && !_historyToEnd->isHidden()) {
@ -6849,7 +6886,7 @@ void HistoryWidget::onPhotoSend(PhotoData *photo) {
void HistoryWidget::onInlineResultSend(InlineBots::Result *result, UserData *bot) {
if (!_history || !result || !canSendMessages(_peer)) return;
App::main()->readServerHistory(_history, false);
App::main()->readServerHistory(_history);
fastShowAtEnd(_history);
uint64 randomId = rand_value<uint64>();
@ -7029,7 +7066,7 @@ void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &capti
return;
}
App::main()->readServerHistory(_history, false);
App::main()->readServerHistory(_history);
fastShowAtEnd(_history);
uint64 randomId = rand_value<uint64>();
@ -7084,7 +7121,7 @@ void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &capti
void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption) {
if (!_history || !photo || !canSendMessages(_peer)) return;
App::main()->readServerHistory(_history, false);
App::main()->readServerHistory(_history);
fastShowAtEnd(_history);
uint64 randomId = rand_value<uint64>();

View file

@ -498,7 +498,7 @@ public:
void historyLoaded();
void windowShown();
bool isActive() const;
bool doWeReadServerHistory() const;
void resizeEvent(QResizeEvent *e) override;
void keyPressEvent(QKeyEvent *e) override;
@ -527,8 +527,9 @@ public:
void newUnreadMsg(History *history, HistoryItem *item);
void historyToDown(History *history);
void historyWasRead(bool force = true);
void historyWasRead(ReadServerHistoryChecks checks);
void historyCleared(History *history);
void unreadCountChanged(History *history);
QRect historyRect() const;

View file

@ -254,18 +254,18 @@ void MainWidget::cancelForwarding() {
_history->cancelForwarding();
}
void MainWidget::finishForwarding(History *hist, bool silent) {
if (!hist) return;
void MainWidget::finishForwarding(History *history, bool silent) {
if (!history) return;
if (!_toForward.isEmpty()) {
bool genClientSideMessage = (_toForward.size() < 2);
PeerData *forwardFrom = 0;
App::main()->readServerHistory(hist, false);
App::main()->readServerHistory(history);
MTPDmessage::Flags flags = 0;
MTPmessages_ForwardMessages::Flags sendFlags = 0;
bool channelPost = hist->peer->isChannel() && !hist->peer->isMegagroup();
bool showFromName = !channelPost || hist->peer->asChannel()->addsSignature();
bool channelPost = history->peer->isChannel() && !history->peer->isMegagroup();
bool showFromName = !channelPost || history->peer->asChannel()->addsSignature();
bool silentPost = channelPost && silent;
if (channelPost) {
flags |= MTPDmessage::Flag::f_views;
@ -285,9 +285,9 @@ void MainWidget::finishForwarding(History *hist, bool silent) {
for (SelectedItemSet::const_iterator i = _toForward.cbegin(), e = _toForward.cend(); i != e; ++i) {
uint64 randomId = rand_value<uint64>();
if (genClientSideMessage) {
FullMsgId newId(peerToChannel(hist->peer->id), clientMsgId());
FullMsgId newId(peerToChannel(history->peer->id), clientMsgId());
HistoryMessage *msg = static_cast<HistoryMessage*>(_toForward.cbegin().value());
hist->addNewForwarded(newId.msg, flags, date(MTP_int(unixtime())), showFromName ? MTP::authedId() : 0, msg);
history->addNewForwarded(newId.msg, flags, date(MTP_int(unixtime())), showFromName ? MTP::authedId() : 0, msg);
if (HistoryMedia *media = msg->getMedia()) {
if (media->type() == MediaTypeSticker) {
App::main()->incrementSticker(media->getDocument());
@ -297,7 +297,7 @@ void MainWidget::finishForwarding(History *hist, bool silent) {
}
if (forwardFrom != i.value()->history()->peer) {
if (forwardFrom) {
hist->sendRequestId = MTP::send(MTPmessages_ForwardMessages(MTP_flags(sendFlags), forwardFrom->input, MTP_vector<MTPint>(ids), MTP_vector<MTPlong>(randomIds), hist->peer->input), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
history->sendRequestId = MTP::send(MTPmessages_ForwardMessages(MTP_flags(sendFlags), forwardFrom->input, MTP_vector<MTPint>(ids), MTP_vector<MTPlong>(randomIds), history->peer->input), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, history->sendRequestId);
ids.resize(0);
randomIds.resize(0);
}
@ -306,18 +306,18 @@ void MainWidget::finishForwarding(History *hist, bool silent) {
ids.push_back(MTP_int(i.value()->id));
randomIds.push_back(MTP_long(randomId));
}
hist->sendRequestId = MTP::send(MTPmessages_ForwardMessages(MTP_flags(sendFlags), forwardFrom->input, MTP_vector<MTPint>(ids), MTP_vector<MTPlong>(randomIds), hist->peer->input), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
history->sendRequestId = MTP::send(MTPmessages_ForwardMessages(MTP_flags(sendFlags), forwardFrom->input, MTP_vector<MTPint>(ids), MTP_vector<MTPlong>(randomIds), history->peer->input), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, history->sendRequestId);
if (_history->peer() == hist->peer) {
if (_history->peer() == history->peer) {
_history->peerMessagesUpdated();
}
cancelForwarding();
}
historyToDown(hist);
historyToDown(history);
dialogsToUp();
_history->peerMessagesUpdated(hist->peer->id);
_history->peerMessagesUpdated(history->peer->id);
}
void MainWidget::webPageUpdated(WebPageData *data) {
@ -676,7 +676,9 @@ void MainWidget::deleteHistoryAfterLeave(PeerData *peer, const MTPUpdates &updat
deleteConversation(peer);
}
void MainWidget::deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result) {
void MainWidget::deleteHistoryPart(DeleteHistoryRequest request, const MTPmessages_AffectedHistory &result) {
auto peer = request.peer;
const auto &d(result.c_messages_affectedHistory());
if (peer && peer->isChannel()) {
if (peer->asChannel()->ptsUpdated(d.vpts.v, d.vpts_count.v)) {
@ -698,7 +700,11 @@ void MainWidget::deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHis
return;
}
MTP::send(MTPmessages_DeleteHistory(peer->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, peer));
MTPmessages_DeleteHistory::Flags flags = 0;
if (request.justClearHistory) {
flags |= MTPmessages_DeleteHistory::Flag::f_just_clear;
}
MTP::send(MTPmessages_DeleteHistory(MTP_flags(flags), peer->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, request));
}
void MainWidget::deleteMessages(PeerData *peer, const QVector<MTPint> &ids) {
@ -743,7 +749,9 @@ void MainWidget::deleteConversation(PeerData *peer, bool deleteHistory) {
peer->asChannel()->ptsWaitingForShortPoll(-1);
}
if (deleteHistory) {
MTP::send(MTPmessages_DeleteHistory(peer->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, peer));
DeleteHistoryRequest request = { peer, false };
MTPmessages_DeleteHistory::Flags flags = 0;
MTP::send(MTPmessages_DeleteHistory(MTP_flags(flags), peer->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, request));
}
}
@ -795,7 +803,9 @@ void MainWidget::clearHistory(PeerData *peer) {
h->newLoaded = h->oldLoaded = true;
}
Ui::showPeerHistory(peer->id, ShowAtUnreadMsgId);
MTP::send(MTPmessages_DeleteHistory(peer->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, peer));
MTPmessages_DeleteHistory::Flags flags = MTPmessages_DeleteHistory::Flag::f_just_clear;
DeleteHistoryRequest request = { peer, true };
MTP::send(MTPmessages_DeleteHistory(MTP_flags(flags), peer->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, request));
}
void MainWidget::addParticipants(PeerData *chatOrChannel, const QVector<UserData*> &users) {
@ -1046,7 +1056,7 @@ void MainWidget::sendMessage(const MessageToSend &message) {
auto history = message.history;
const auto &textWithTags = message.textWithTags;
readServerHistory(history, false);
readServerHistory(history);
_history->fastShowAtEnd(history);
if (!history || !_history->canSendMessages(history->peer)) {
@ -1143,27 +1153,34 @@ void MainWidget::saveRecentHashtags(const QString &text) {
}
}
void MainWidget::readServerHistory(History *hist, bool force) {
if (!hist || (!force && !hist->unreadCount())) return;
void MainWidget::readServerHistory(History *history, ReadServerHistoryChecks checks) {
if (!history) return;
if (checks == ReadServerHistoryChecks::OnlyIfUnread && !history->unreadCount()) return;
MsgId upTo = hist->inboxRead(0);
if (hist->isChannel() && !hist->peer->asChannel()->amIn()) {
auto peer = history->peer;
MsgId upTo = history->inboxRead(0);
if (auto channel = peer->asChannel()) {
if (!channel->amIn()) {
return; // no read request for channels that I didn't koin
}
}
ReadRequests::const_iterator i = _readRequests.constFind(hist->peer);
if (i == _readRequests.cend()) {
sendReadRequest(hist->peer, upTo);
} else {
ReadRequestsPending::iterator i = _readRequestsPending.find(hist->peer);
if (_readRequests.contains(peer)) {
auto i = _readRequestsPending.find(peer);
if (i == _readRequestsPending.cend()) {
_readRequestsPending.insert(hist->peer, upTo);
_readRequestsPending.insert(peer, upTo);
} else if (i.value() < upTo) {
i.value() = upTo;
}
} else {
sendReadRequest(peer, upTo);
}
}
void MainWidget::unreadCountChanged(History *history) {
_history->unreadCountChanged(history);
}
uint64 MainWidget::animActiveTimeStart(const HistoryItem *msg) const {
return _history->animActiveTimeStart(msg);
}
@ -1386,17 +1403,17 @@ void MainWidget::overviewLoaded(History *history, const MTPmessages_Messages &re
void MainWidget::sendReadRequest(PeerData *peer, MsgId upTo) {
if (!MTP::authedId()) return;
if (peer->isChannel()) {
_readRequests.insert(peer, qMakePair(MTP::send(MTPchannels_ReadHistory(peer->asChannel()->inputChannel, MTP_int(upTo)), rpcDone(&MainWidget::channelWasRead, peer), rpcFail(&MainWidget::readRequestFail, peer)), upTo));
_readRequests.insert(peer, qMakePair(MTP::send(MTPchannels_ReadHistory(peer->asChannel()->inputChannel, MTP_int(upTo)), rpcDone(&MainWidget::channelReadDone, peer), rpcFail(&MainWidget::readRequestFail, peer)), upTo));
} else {
_readRequests.insert(peer, qMakePair(MTP::send(MTPmessages_ReadHistory(peer->input, MTP_int(upTo)), rpcDone(&MainWidget::historyWasRead, peer), rpcFail(&MainWidget::readRequestFail, peer)), upTo));
_readRequests.insert(peer, qMakePair(MTP::send(MTPmessages_ReadHistory(peer->input, MTP_int(upTo)), rpcDone(&MainWidget::historyReadDone, peer), rpcFail(&MainWidget::readRequestFail, peer)), upTo));
}
}
void MainWidget::channelWasRead(PeerData *peer, const MTPBool &result) {
void MainWidget::channelReadDone(PeerData *peer, const MTPBool &result) {
readRequestDone(peer);
}
void MainWidget::historyWasRead(PeerData *peer, const MTPmessages_AffectedMessages &result) {
void MainWidget::historyReadDone(PeerData *peer, const MTPmessages_AffectedMessages &result) {
messagesAffected(peer, result);
readRequestDone(peer);
}
@ -2342,24 +2359,24 @@ void MainWidget::onActiveChannelUpdateFull() {
}
}
void MainWidget::historyToDown(History *hist) {
_history->historyToDown(hist);
void MainWidget::historyToDown(History *history) {
_history->historyToDown(history);
}
void MainWidget::dialogsToUp() {
_dialogs->dialogsToUp();
}
void MainWidget::newUnreadMsg(History *hist, HistoryItem *item) {
_history->newUnreadMsg(hist, item);
void MainWidget::newUnreadMsg(History *history, HistoryItem *item) {
_history->newUnreadMsg(history, item);
}
void MainWidget::historyWasRead() {
_history->historyWasRead(false);
void MainWidget::markActiveHistoryAsRead() {
_history->historyWasRead(ReadServerHistoryChecks::OnlyIfUnread);
}
void MainWidget::historyCleared(History *hist) {
_history->historyCleared(hist);
void MainWidget::historyCleared(History *history) {
_history->historyCleared(history);
}
void MainWidget::animShow(const QPixmap &bgAnimCache, bool back) {
@ -3624,8 +3641,8 @@ bool MainWidget::isActive() const {
return !_isIdle && isVisible() && !_a_show.animating();
}
bool MainWidget::historyIsActive() const {
return isActive() && !_profile && !_overview && _history->isActive();
bool MainWidget::doWeReadServerHistory() const {
return isActive() && !_profile && !_overview && _history->doWeReadServerHistory();
}
bool MainWidget::lastWasOnline() const {

View file

@ -199,7 +199,7 @@ public:
void historyToDown(History *hist);
void dialogsToUp();
void newUnreadMsg(History *history, HistoryItem *item);
void historyWasRead();
void markActiveHistoryAsRead();
void historyCleared(History *history);
void peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg);
@ -228,7 +228,7 @@ public:
void updateOnlineDisplayIn(int32 msecs);
bool isActive() const;
bool historyIsActive() const;
bool doWeReadServerHistory() const;
bool lastWasOnline() const;
uint64 lastSetOnline() const;
@ -291,7 +291,8 @@ public:
void sendMessage(const MessageToSend &message);
void saveRecentHashtags(const QString &text);
void readServerHistory(History *history, bool force = true);
void readServerHistory(History *history, ReadServerHistoryChecks checks = ReadServerHistoryChecks::OnlyIfUnread);
void unreadCountChanged(History *history);
uint64 animActiveTimeStart(const HistoryItem *msg) const;
void stopAnimActive();
@ -480,8 +481,8 @@ public slots:
private:
void sendReadRequest(PeerData *peer, MsgId upTo);
void channelWasRead(PeerData *peer, const MTPBool &result);
void historyWasRead(PeerData *peer, const MTPmessages_AffectedMessages &result);
void channelReadDone(PeerData *peer, const MTPBool &result);
void historyReadDone(PeerData *peer, const MTPmessages_AffectedMessages &result);
bool readRequestFail(PeerData *peer, const RPCError &error);
void readRequestDone(PeerData *peer);
@ -521,7 +522,11 @@ private:
void feedUpdateVector(const MTPVector<MTPUpdate> &updates, bool skipMessageIds = false);
void feedMessageIds(const MTPVector<MTPUpdate> &updates);
void deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result);
struct DeleteHistoryRequest {
PeerData *peer;
bool justClearHistory;
};
void deleteHistoryPart(DeleteHistoryRequest request, const MTPmessages_AffectedHistory &result);
struct DeleteAllFromUserParams {
ChannelData *channel;
UserData *from;

View file

@ -904,13 +904,13 @@ void MainWindow::hideConnecting() {
if (settings) settings->update();
}
bool MainWindow::historyIsActive() const {
return isActive(false) && main && main->historyIsActive() && (!settings || !settings->isVisible());
bool MainWindow::doWeReadServerHistory() const {
return isActive(false) && main && (!settings || !settings->isVisible()) && main->doWeReadServerHistory();
}
void MainWindow::checkHistoryActivation() {
if (main && MTP::authedId() && historyIsActive()) {
main->historyWasRead();
if (main && MTP::authedId() && doWeReadServerHistory()) {
main->markActiveHistoryAsRead();
}
QTimer::singleShot(1, this, SLOT(updateTrayMenu()));
}

View file

@ -185,7 +185,7 @@ public:
void showPhoto(PhotoData *photo, PeerData *item);
void showDocument(DocumentData *doc, HistoryItem *item);
bool historyIsActive() const;
bool doWeReadServerHistory() const;
void activate();

View file

@ -38,6 +38,7 @@ addChildParentFlags('MTPDreplyKeyboardHide', 'MTPDreplyKeyboardMarkup');
addChildParentFlags('MTPDreplyKeyboardForceReply', 'MTPDreplyKeyboardMarkup');
addChildParentFlags('MTPDinputPeerNotifySettings', 'MTPDpeerNotifySettings');
addChildParentFlags('MTPDpeerNotifySettings', 'MTPDinputPeerNotifySettings');
addChildParentFlags('MTPDchannelForbidden', 'MTPDchannel');
# this is a map (key flags -> map (flag name -> flag bit))
# each key flag of parentFlags should be a subset of the value flag here

View file

@ -210,7 +210,7 @@ chatEmpty#9ba2d800 id:int = Chat;
chat#d91cdd54 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true admins_enabled:flags.3?true admin:flags.4?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel = Chat;
chatForbidden#7328bdb id:int title:string = Chat;
channel#a14dca52 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true editor:flags.3?true moderator:flags.4?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true democracy:flags.10?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string = Chat;
channelForbidden#2d85832c id:int access_hash:long title:string = Chat;
channelForbidden#8537784f flags:# broadcast:flags.5?true megagroup:flags.8?true id:int access_hash:long title:string = Chat;
chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> = ChatFull;
channelFull#c3d5512f flags:# can_view_participants:flags.3?true can_set_username:flags.6?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int = ChatFull;
@ -250,6 +250,7 @@ messageActionChannelCreate#95d2ac92 title:string = MessageAction;
messageActionChatMigrateTo#51bdb021 channel_id:int = MessageAction;
messageActionChannelMigrateFrom#b055eaee title:string chat_id:int = MessageAction;
messageActionPinMessage#94bd38ed = MessageAction;
messageActionHistoryClear#9fbab604 = MessageAction;
dialog#66ffba14 flags:# peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage = Dialog;
@ -768,11 +769,11 @@ messages.getDialogs#6b47f94d offset_date:int offset_id:int offset_peer:InputPeer
messages.getHistory#afa92846 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
messages.search#d4569248 flags:# peer:InputPeer q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = messages.Messages;
messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages;
messages.deleteHistory#b7c13bd9 peer:InputPeer max_id:int = messages.AffectedHistory;
messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true peer:InputPeer max_id:int = messages.AffectedHistory;
messages.deleteMessages#a5f18925 id:Vector<int> = messages.AffectedMessages;
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
messages.sendMessage#fa88427a flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
messages.sendMessage#fa88427a flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
messages.sendMedia#c8f16791 flags:# silent:flags.5?true background:flags.6?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates;
messages.forwardMessages#708e0195 flags:# silent:flags.5?true background:flags.6?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer = Updates;
messages.reportSpam#cf1592db peer:InputPeer = Bool;

View file

@ -1179,6 +1179,8 @@ void _serialize_channel(MTPStringLogger &to, int32 stage, int32 lev, Types &type
}
void _serialize_channelForbidden(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
MTPDchannelForbidden::Flags flag(iflag);
if (stage) {
to.add(",\n").addSpaces(lev);
} else {
@ -1186,9 +1188,12 @@ void _serialize_channelForbidden(MTPStringLogger &to, int32 stage, int32 lev, Ty
to.add("\n").addSpaces(lev);
}
switch (stage) {
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 1: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 2: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 1: to.add(" broadcast: "); ++stages.back(); if (flag & MTPDchannelForbidden::Flag::f_broadcast) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
case 2: to.add(" megagroup: "); ++stages.back(); if (flag & MTPDchannelForbidden::Flag::f_megagroup) { to.add("YES [ BY BIT 8 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 8 IN FIELD flags ]"); } break;
case 3: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 4: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 5: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
}
}
@ -1634,6 +1639,10 @@ void _serialize_messageActionPinMessage(MTPStringLogger &to, int32 stage, int32
to.add("{ messageActionPinMessage }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
}
void _serialize_messageActionHistoryClear(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
to.add("{ messageActionHistoryClear }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
}
void _serialize_dialog(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
MTPDdialog::Flags flag(iflag);
@ -7146,6 +7155,8 @@ void _serialize_channels_deleteMessages(MTPStringLogger &to, int32 stage, int32
}
void _serialize_messages_deleteHistory(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
MTPmessages_deleteHistory::Flags flag(iflag);
if (stage) {
to.add(",\n").addSpaces(lev);
} else {
@ -7153,8 +7164,10 @@ void _serialize_messages_deleteHistory(MTPStringLogger &to, int32 stage, int32 l
to.add("\n").addSpaces(lev);
}
switch (stage) {
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 1: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 1: to.add(" just_clear: "); ++stages.back(); if (flag & MTPmessages_deleteHistory::Flag::f_just_clear) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 2: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 3: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
}
}
@ -7200,12 +7213,13 @@ void _serialize_messages_sendMessage(MTPStringLogger &to, int32 stage, int32 lev
case 1: to.add(" no_webpage: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_no_webpage) { to.add("YES [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
case 2: to.add(" silent: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_silent) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
case 3: to.add(" background: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_background) { to.add("YES [ BY BIT 6 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
case 4: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 5: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_reply_to_msg_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 6: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 7: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 8: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
case 9: to.add(" entities: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
case 4: to.add(" clear_draft: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_clear_draft) { to.add("YES [ BY BIT 7 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
case 5: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 6: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_reply_to_msg_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 7: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 8: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 9: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
case 10: to.add(" entities: "); ++stages.back(); if (flag & MTPmessages_sendMessage::Flag::f_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
}
}
@ -8358,6 +8372,7 @@ namespace {
_serializers.insert(mtpc_messageActionChatMigrateTo, _serialize_messageActionChatMigrateTo);
_serializers.insert(mtpc_messageActionChannelMigrateFrom, _serialize_messageActionChannelMigrateFrom);
_serializers.insert(mtpc_messageActionPinMessage, _serialize_messageActionPinMessage);
_serializers.insert(mtpc_messageActionHistoryClear, _serialize_messageActionHistoryClear);
_serializers.insert(mtpc_dialog, _serialize_dialog);
_serializers.insert(mtpc_photoEmpty, _serialize_photoEmpty);
_serializers.insert(mtpc_photo, _serialize_photo);

View file

@ -145,7 +145,7 @@ enum {
mtpc_chat = 0xd91cdd54,
mtpc_chatForbidden = 0x7328bdb,
mtpc_channel = 0xa14dca52,
mtpc_channelForbidden = 0x2d85832c,
mtpc_channelForbidden = 0x8537784f,
mtpc_chatFull = 0x2e02a614,
mtpc_channelFull = 0xc3d5512f,
mtpc_chatParticipant = 0xc8d7493e,
@ -178,6 +178,7 @@ enum {
mtpc_messageActionChatMigrateTo = 0x51bdb021,
mtpc_messageActionChannelMigrateFrom = 0xb055eaee,
mtpc_messageActionPinMessage = 0x94bd38ed,
mtpc_messageActionHistoryClear = 0x9fbab604,
mtpc_dialog = 0x66ffba14,
mtpc_photoEmpty = 0x2331b22d,
mtpc_photo = 0xcded42fe,
@ -566,7 +567,7 @@ enum {
mtpc_messages_getHistory = 0xafa92846,
mtpc_messages_search = 0xd4569248,
mtpc_messages_readHistory = 0xe306d3a,
mtpc_messages_deleteHistory = 0xb7c13bd9,
mtpc_messages_deleteHistory = 0x1c015b09,
mtpc_messages_deleteMessages = 0xa5f18925,
mtpc_messages_receivedMessages = 0x5a954c0,
mtpc_messages_setTyping = 0xa3825e50,
@ -10441,11 +10442,24 @@ public:
class MTPDchannelForbidden : public mtpDataImpl<MTPDchannelForbidden> {
public:
enum class Flag : int32 {
f_broadcast = (1 << 5),
f_megagroup = (1 << 8),
MAX_FIELD = (1 << 8),
};
Q_DECLARE_FLAGS(Flags, Flag);
friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
bool is_broadcast() const { return vflags.v & Flag::f_broadcast; }
bool is_megagroup() const { return vflags.v & Flag::f_megagroup; }
MTPDchannelForbidden() {
}
MTPDchannelForbidden(MTPint _id, const MTPlong &_access_hash, const MTPstring &_title) : vid(_id), vaccess_hash(_access_hash), vtitle(_title) {
MTPDchannelForbidden(const MTPflags<MTPDchannelForbidden::Flags> &_flags, MTPint _id, const MTPlong &_access_hash, const MTPstring &_title) : vflags(_flags), vid(_id), vaccess_hash(_access_hash), vtitle(_title) {
}
MTPflags<MTPDchannelForbidden::Flags> vflags;
MTPint vid;
MTPlong vaccess_hash;
MTPstring vtitle;
@ -17554,6 +17568,17 @@ public:
class MTPmessages_deleteHistory { // RPC method 'messages.deleteHistory'
public:
enum class Flag : int32 {
f_just_clear = (1 << 0),
MAX_FIELD = (1 << 0),
};
Q_DECLARE_FLAGS(Flags, Flag);
friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
bool is_just_clear() const { return vflags.v & Flag::f_just_clear; }
MTPflags<MTPmessages_deleteHistory::Flags> vflags;
MTPInputPeer vpeer;
MTPint vmax_id;
@ -17562,26 +17587,30 @@ public:
MTPmessages_deleteHistory(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_deleteHistory) {
read(from, end, cons);
}
MTPmessages_deleteHistory(const MTPInputPeer &_peer, MTPint _max_id) : vpeer(_peer), vmax_id(_max_id) {
MTPmessages_deleteHistory(const MTPflags<MTPmessages_deleteHistory::Flags> &_flags, const MTPInputPeer &_peer, MTPint _max_id) : vflags(_flags), vpeer(_peer), vmax_id(_max_id) {
}
uint32 innerLength() const {
return vpeer.innerLength() + vmax_id.innerLength();
return vflags.innerLength() + vpeer.innerLength() + vmax_id.innerLength();
}
mtpTypeId type() const {
return mtpc_messages_deleteHistory;
}
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_deleteHistory) {
vflags.read(from, end);
vpeer.read(from, end);
vmax_id.read(from, end);
}
void write(mtpBuffer &to) const {
vflags.write(to);
vpeer.write(to);
vmax_id.write(to);
}
typedef MTPmessages_AffectedHistory ResponseType;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(MTPmessages_deleteHistory::Flags)
class MTPmessages_DeleteHistory : public MTPBoxed<MTPmessages_deleteHistory> {
public:
MTPmessages_DeleteHistory() {
@ -17590,7 +17619,7 @@ public:
}
MTPmessages_DeleteHistory(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPmessages_deleteHistory>(from, end, cons) {
}
MTPmessages_DeleteHistory(const MTPInputPeer &_peer, MTPint _max_id) : MTPBoxed<MTPmessages_deleteHistory>(MTPmessages_deleteHistory(_peer, _max_id)) {
MTPmessages_DeleteHistory(const MTPflags<MTPmessages_deleteHistory::Flags> &_flags, const MTPInputPeer &_peer, MTPint _max_id) : MTPBoxed<MTPmessages_deleteHistory>(MTPmessages_deleteHistory(_flags, _peer, _max_id)) {
}
};
@ -17720,12 +17749,13 @@ public:
f_no_webpage = (1 << 1),
f_silent = (1 << 5),
f_background = (1 << 6),
f_clear_draft = (1 << 7),
f_reply_to_msg_id = (1 << 0),
f_reply_markup = (1 << 2),
f_entities = (1 << 3),
MAX_FIELD = (1 << 6),
MAX_FIELD = (1 << 7),
};
Q_DECLARE_FLAGS(Flags, Flag);
friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
@ -17733,6 +17763,7 @@ public:
bool is_no_webpage() const { return vflags.v & Flag::f_no_webpage; }
bool is_silent() const { return vflags.v & Flag::f_silent; }
bool is_background() const { return vflags.v & Flag::f_background; }
bool is_clear_draft() const { return vflags.v & Flag::f_clear_draft; }
bool has_reply_to_msg_id() const { return vflags.v & Flag::f_reply_to_msg_id; }
bool has_reply_markup() const { return vflags.v & Flag::f_reply_markup; }
bool has_entities() const { return vflags.v & Flag::f_entities; }
@ -22491,8 +22522,8 @@ public:
inline static MTPchat new_channel(const MTPflags<MTPDchannel::Flags> &_flags, MTPint _id, const MTPlong &_access_hash, const MTPstring &_title, const MTPstring &_username, const MTPChatPhoto &_photo, MTPint _date, MTPint _version, const MTPstring &_restriction_reason) {
return MTPchat(new MTPDchannel(_flags, _id, _access_hash, _title, _username, _photo, _date, _version, _restriction_reason));
}
inline static MTPchat new_channelForbidden(MTPint _id, const MTPlong &_access_hash, const MTPstring &_title) {
return MTPchat(new MTPDchannelForbidden(_id, _access_hash, _title));
inline static MTPchat new_channelForbidden(const MTPflags<MTPDchannelForbidden::Flags> &_flags, MTPint _id, const MTPlong &_access_hash, const MTPstring &_title) {
return MTPchat(new MTPDchannelForbidden(_flags, _id, _access_hash, _title));
}
inline static MTPchatFull new_chatFull(MTPint _id, const MTPChatParticipants &_participants, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite, const MTPVector<MTPBotInfo> &_bot_info) {
return MTPchatFull(new MTPDchatFull(_id, _participants, _chat_photo, _notify_settings, _exported_invite, _bot_info));
@ -22590,6 +22621,9 @@ public:
inline static MTPmessageAction new_messageActionPinMessage() {
return MTPmessageAction(mtpc_messageActionPinMessage);
}
inline static MTPmessageAction new_messageActionHistoryClear() {
return MTPmessageAction(mtpc_messageActionHistoryClear);
}
inline static MTPdialog new_dialog(const MTPflags<MTPDdialog::Flags> &_flags, const MTPPeer &_peer, MTPint _top_message, MTPint _read_inbox_max_id, MTPint _read_outbox_max_id, MTPint _unread_count, const MTPPeerNotifySettings &_notify_settings, MTPint _pts, const MTPDraftMessage &_draft) {
return MTPdialog(new MTPDdialog(_flags, _peer, _top_message, _read_inbox_max_id, _read_outbox_max_id, _unread_count, _notify_settings, _pts, _draft));
}
@ -25853,7 +25887,7 @@ inline uint32 MTPchat::innerLength() const {
}
case mtpc_channelForbidden: {
const MTPDchannelForbidden &v(c_channelForbidden());
return v.vid.innerLength() + v.vaccess_hash.innerLength() + v.vtitle.innerLength();
return v.vflags.innerLength() + v.vid.innerLength() + v.vaccess_hash.innerLength() + v.vtitle.innerLength();
}
}
return 0;
@ -25904,6 +25938,7 @@ inline void MTPchat::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId
case mtpc_channelForbidden: _type = cons; {
if (!data) setData(new MTPDchannelForbidden());
MTPDchannelForbidden &v(_channelForbidden());
v.vflags.read(from, end);
v.vid.read(from, end);
v.vaccess_hash.read(from, end);
v.vtitle.read(from, end);
@ -25947,6 +25982,7 @@ inline void MTPchat::write(mtpBuffer &to) const {
} break;
case mtpc_channelForbidden: {
const MTPDchannelForbidden &v(c_channelForbidden());
v.vflags.write(to);
v.vid.write(to);
v.vaccess_hash.write(to);
v.vtitle.write(to);
@ -25987,8 +26023,9 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(MTPDchannel::Flags)
inline MTPchat MTP_channel(const MTPflags<MTPDchannel::Flags> &_flags, MTPint _id, const MTPlong &_access_hash, const MTPstring &_title, const MTPstring &_username, const MTPChatPhoto &_photo, MTPint _date, MTPint _version, const MTPstring &_restriction_reason) {
return MTP::internal::TypeCreator::new_channel(_flags, _id, _access_hash, _title, _username, _photo, _date, _version, _restriction_reason);
}
inline MTPchat MTP_channelForbidden(MTPint _id, const MTPlong &_access_hash, const MTPstring &_title) {
return MTP::internal::TypeCreator::new_channelForbidden(_id, _access_hash, _title);
Q_DECLARE_OPERATORS_FOR_FLAGS(MTPDchannelForbidden::Flags)
inline MTPchat MTP_channelForbidden(const MTPflags<MTPDchannelForbidden::Flags> &_flags, MTPint _id, const MTPlong &_access_hash, const MTPstring &_title) {
return MTP::internal::TypeCreator::new_channelForbidden(_flags, _id, _access_hash, _title);
}
inline uint32 MTPchatFull::innerLength() const {
@ -26695,6 +26732,7 @@ inline void MTPmessageAction::read(const mtpPrime *&from, const mtpPrime *end, m
v.vchat_id.read(from, end);
} break;
case mtpc_messageActionPinMessage: _type = cons; break;
case mtpc_messageActionHistoryClear: _type = cons; break;
default: throw mtpErrorUnexpected(cons, "MTPmessageAction");
}
}
@ -26754,6 +26792,7 @@ inline MTPmessageAction::MTPmessageAction(mtpTypeId type) : mtpDataOwner(0), _ty
case mtpc_messageActionChatMigrateTo: setData(new MTPDmessageActionChatMigrateTo()); break;
case mtpc_messageActionChannelMigrateFrom: setData(new MTPDmessageActionChannelMigrateFrom()); break;
case mtpc_messageActionPinMessage: break;
case mtpc_messageActionHistoryClear: break;
default: throw mtpErrorBadTypeId(type, "MTPmessageAction");
}
}
@ -26811,6 +26850,9 @@ inline MTPmessageAction MTP_messageActionChannelMigrateFrom(const MTPstring &_ti
inline MTPmessageAction MTP_messageActionPinMessage() {
return MTP::internal::TypeCreator::new_messageActionPinMessage();
}
inline MTPmessageAction MTP_messageActionHistoryClear() {
return MTP::internal::TypeCreator::new_messageActionHistoryClear();
}
inline MTPdialog::MTPdialog() : mtpDataOwner(new MTPDdialog()) {
}
@ -34884,6 +34926,8 @@ inline MTPDpeerNotifySettings::Flags mtpCastFlags(MTPDinputPeerNotifySettings::F
inline MTPDpeerNotifySettings::Flags mtpCastFlags(MTPflags<MTPDinputPeerNotifySettings::Flags> flags) { return mtpCastFlags(flags.v); }
inline MTPDinputPeerNotifySettings::Flags mtpCastFlags(MTPDpeerNotifySettings::Flags flags) { return MTPDinputPeerNotifySettings::Flags(QFlag(flags)); }
inline MTPDinputPeerNotifySettings::Flags mtpCastFlags(MTPflags<MTPDpeerNotifySettings::Flags> flags) { return mtpCastFlags(flags.v); }
inline MTPDchannel::Flags mtpCastFlags(MTPDchannelForbidden::Flags flags) { return MTPDchannel::Flags(QFlag(flags)); }
inline MTPDchannel::Flags mtpCastFlags(MTPflags<MTPDchannelForbidden::Flags> flags) { return mtpCastFlags(flags.v); }
// Human-readable text serialization
void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons);

View file

@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "ui/buttons/history_down_button.h"
#include "styles/style_history.h"
#include "dialogs/dialogs_layout.h"
namespace Ui {
@ -29,16 +30,25 @@ HistoryDownButton::HistoryDownButton(QWidget *parent) : Button(parent)
, a_arrowOpacity(st::btnAttachEmoji.opacity, st::btnAttachEmoji.opacity)
, _a_arrowOver(animation(this, &HistoryDownButton::step_arrowOver)) {
setCursor(style::cur_pointer);
resize(st::historyToDown.width(), st::historyToDown.height());
resize(st::historyToDown.width(), st::historyToDownPaddingTop + st::historyToDown.height());
connect(this, SIGNAL(stateChanged(int,ButtonStateChangeSource)), this, SLOT(onStateChange(int,ButtonStateChangeSource)));
}
void HistoryDownButton::paintEvent(QPaintEvent *e) {
Painter p(this);
st::historyToDown.paint(p, QPoint(0, 0), width());
st::historyToDown.paint(p, QPoint(0, st::historyToDownPaddingTop), width());
p.setOpacity(a_arrowOpacity.current());
st::historyToDownArrow.paint(p, QPoint(0, 0), width());
st::historyToDownArrow.paint(p, QPoint(0, st::historyToDownPaddingTop), width());
if (_unreadCount > 0) {
p.setOpacity(1);
bool active = false, muted = false;
auto unreadString = QString::number(_unreadCount);
if (unreadString.size() > 4) {
unreadString = qsl("..") + unreadString.mid(unreadString.size() - 4);
}
Dialogs::Layout::paintUnreadCount(p, unreadString, width(), 0, style::al_center, active, muted, nullptr);
}
}
void HistoryDownButton::onStateChange(int oldState, ButtonStateChangeSource source) {
@ -53,6 +63,11 @@ void HistoryDownButton::onStateChange(int oldState, ButtonStateChangeSource sour
}
}
void HistoryDownButton::setUnreadCount(int unreadCount) {
_unreadCount = unreadCount;
update();
}
void HistoryDownButton::step_arrowOver(float64 ms, bool timer) {
float64 dt = ms / st::btnAttachEmoji.duration;
if (dt >= 1) {

View file

@ -30,6 +30,11 @@ class HistoryDownButton : public Button {
public:
HistoryDownButton(QWidget *parent);
void setUnreadCount(int unreadCount);
int unreadCount() const {
return _unreadCount;
}
protected:
void paintEvent(QPaintEvent *e) override;
@ -42,6 +47,8 @@ private:
anim::fvalue a_arrowOpacity;
Animation _a_arrowOver;
int _unreadCount = 0;
};
} // namespace Ui