Scheme updated. Pinned dialogs support added.

This commit is contained in:
John Preston 2016-12-13 10:59:57 +03:00
parent 90234cb7a0
commit 85b434bee4
32 changed files with 4512 additions and 350 deletions

View File

@ -177,7 +177,7 @@ dialogsVerifiedIconFgActive: dialogsBgActive;
dialogsSendingIconFgActive: #ffffff99;
dialogsSentIconFgActive: dialogsTextFgActive;
dialogsUnreadBgActive: dialogsTextFgActive;
dialogsUnreadBgMutedActive: #d3e2ee;
dialogsUnreadBgMutedActive: dialogsDraftFgActive;
dialogsUnreadFgActive: dialogsBgActive;
dialogsForwardBg: dialogsBgActive;

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 B

After

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 B

After

Width:  |  Height:  |  Size: 149 B

View File

@ -842,6 +842,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_context_view_profile" = "View profile";
"lng_context_view_group" = "View group info";
"lng_context_view_channel" = "View channel info";
"lng_context_pin_to_top" = "Pin to top";
"lng_context_unpin_from_top" = "Unpin from top";
"lng_context_copy_link" = "Copy Link";
"lng_context_copy_post_link" = "Copy Post Link";

View File

@ -149,7 +149,7 @@ dialogsVerifiedIconFgActive: dialogsBgActive;
dialogsSendingIconFgActive: #ffffff99;
dialogsSentIconFgActive: dialogsTextFgActive;
dialogsUnreadBgActive: dialogsTextFgActive;
dialogsUnreadBgMutedActive: #d3e2ee;
dialogsUnreadBgMutedActive: dialogsDraftFgActive;
dialogsUnreadFgActive: dialogsBgActive;
dialogsForwardBg: dialogsBgActive;
dialogsForwardFg: dialogsNameFgActive;

View File

@ -1513,7 +1513,7 @@ namespace {
return page;
} break;
case mtpc_webPagePending: return App::feedWebPage(webpage.c_webPagePending());
// case mtpc_webPageNotModified: LOG(("API Error: webPageNotModified is unexpected in feedWebPage().")); break; // TODO
case mtpc_webPageNotModified: LOG(("API Error: webPageNotModified is unexpected in feedWebPage().")); break;
}
return nullptr;
}

View File

@ -1069,7 +1069,7 @@ void AppClass::checkMapVersion() {
}
if (!versionFeatures.isEmpty()) {
versionFeatures = lng_new_version_wrap(lt_version, QString::fromLatin1(AppVersionStr.c_str()), lt_changes, versionFeatures, lt_link, qsl("https://desktop.telegram.org/#changelog"));
_window->serviceNotification(versionFeatures);
_window->serviceNotificationLocal(versionFeatures);
}
}
}

View File

@ -44,7 +44,7 @@ SessionsBox::SessionsBox() : ScrollableBox(st::sessionsScroll)
connect(_inner, SIGNAL(oneTerminated()), this, SLOT(onOneTerminated()));
connect(_inner, SIGNAL(allTerminated()), this, SLOT(onAllTerminated()));
connect(_inner, SIGNAL(terminateAll()), this, SLOT(onTerminateAll()));
connect(App::wnd(), SIGNAL(newAuthorization()), this, SLOT(onNewAuthorization()));
connect(App::wnd(), SIGNAL(checkNewAuthorization()), this, SLOT(onCheckNewAuthorization()));
connect(&_shortPollTimer, SIGNAL(timeout()), this, SLOT(onShortPollAuthorizations()));
init(_inner, st::boxButtonPadding.bottom() + _done->height() + st::boxButtonPadding.top(), titleHeight());
@ -216,7 +216,7 @@ void SessionsBox::onShortPollAuthorizations() {
}
}
void SessionsBox::onNewAuthorization() {
void SessionsBox::onCheckNewAuthorization() {
onShortPollAuthorizations();
// _shortPollTimer.start(1000);
}

View File

@ -42,7 +42,7 @@ public slots:
void onAllTerminated();
void onTerminateAll();
void onShortPollAuthorizations();
void onNewAuthorization();
void onCheckNewAuthorization();
protected:
void resizeEvent(QResizeEvent *e) override;

View File

@ -167,8 +167,6 @@ enum {
ChoosePeerByDragTimeout = 1000, // 1 second mouse not moved to choose dialog when dragging a file
ReloadChannelMembersTimeout = 1000, // 1 second wait before reload members in channel after adding
PinnedMessageTextLimit = 16,
};
inline bool isNotificationsUser(uint64 id) {

View File

@ -152,6 +152,9 @@ dialogsSentIconActive: icon {{ "dialogs_sent", dialogsSentIconFgActive, point(10
dialogsReceivedIcon: icon {{ "dialogs_received", dialogsSentIconFg, point(5px, 4px) }};
dialogsReceivedIconOver: icon {{ "dialogs_received", dialogsSentIconFgOver, point(5px, 4px) }};
dialogsReceivedIconActive: icon {{ "dialogs_received", dialogsSentIconFgActive, point(5px, 4px) }};
dialogsPinnedIcon: icon {{ "dialogs_pinned", dialogsUnreadBgMuted }};
dialogsPinnedIconOver: icon {{ "dialogs_pinned", dialogsUnreadBgMutedOver }};
dialogsPinnedIconActive: icon {{ "dialogs_pinned", dialogsUnreadBgMutedActive }};
dialogsVerifiedIcon: icon {
{ "dialogs_verified_star", dialogsVerifiedIconBg, point(4px, 2px) },

View File

@ -283,6 +283,10 @@ void RowPainter::paint(Painter &p, const Row *row, int fullWidth, bool active, b
st.muted = history->mute();
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth);
availableWidth -= unreadWidth + st.padding;
} else if (history->isPinnedDialog()) {
auto &icon = (active ? st::dialogsPinnedIconActive : (selected ? st::dialogsPinnedIconOver : st::dialogsPinnedIcon));
icon.paint(p, fullWidth - st::dialogsPadding.x() - icon.width(), texttop, fullWidth);
availableWidth -= icon.width() + st::dialogsUnreadPadding;
}
auto &color = active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService);
if (!history->paintSendAction(p, nameleft, texttop, availableWidth, fullWidth, color, ms)) {

View File

@ -1129,7 +1129,7 @@ void DialogsInner::dialogsReceived(const QVector<MTPDialog> &added) {
}
App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, history);
if (!history->lastMsgDate.isNull()) {
if (!history->isPinnedDialog() && !history->lastMsgDate.isNull()) {
addSavedPeersAfter(history->lastMsgDate);
}
_contactsNoDialogs->del(peer);
@ -2058,14 +2058,14 @@ void DialogsWidget::notify_historyMuteUpdated(History *history) {
void DialogsWidget::unreadCountsReceived(const QVector<MTPDialog> &dialogs) {
}
void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpRequestId req) {
if (_dialogsRequest != req) return;
void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpRequestId requestId) {
if (_dialogsRequestId != requestId) return;
const QVector<MTPDialog> *dialogsList = 0;
const QVector<MTPMessage> *messagesList = 0;
switch (dialogs.type()) {
case mtpc_messages_dialogs: {
const auto &data(dialogs.c_messages_dialogs());
auto &data = dialogs.c_messages_dialogs();
App::feedUsers(data.vusers);
App::feedChats(data.vchats);
messagesList = &data.vmessages.c_vector().v;
@ -2073,7 +2073,7 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque
_dialogsFull = true;
} break;
case mtpc_messages_dialogsSlice: {
const auto &data(dialogs.c_messages_dialogsSlice());
auto &data = dialogs.c_messages_dialogsSlice();
App::feedUsers(data.vusers);
App::feedChats(data.vchats);
messagesList = &data.vmessages.c_vector().v;
@ -2081,18 +2081,11 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque
} break;
}
if (!_contactsRequest) {
_contactsRequest = MTP::send(MTPcontacts_GetContacts(MTP_string("")), rpcDone(&DialogsWidget::contactsReceived), rpcFail(&DialogsWidget::contactsFailed));
if (!cContactsReceived() && !_contactsRequestId) {
_contactsRequestId = MTP::send(MTPcontacts_GetContacts(MTP_string("")), rpcDone(&DialogsWidget::contactsReceived), rpcFail(&DialogsWidget::contactsFailed));
}
if (messagesList) {
App::feedMsgs(*messagesList, NewMessageLast);
}
if (dialogsList) {
unreadCountsReceived(*dialogsList);
_inner->dialogsReceived(*dialogsList);
onListScroll();
TimeId lastDate = 0;
PeerId lastPeer = 0;
MsgId lastMsgId = 0;
@ -2102,20 +2095,25 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque
continue;
}
if (auto peer = peerFromMTP(dialog.c_dialog().vpeer)) {
if (!lastPeer) lastPeer = peer;
if (auto msgId = dialog.c_dialog().vtop_message.v) {
if (!lastMsgId) lastMsgId = msgId;
for (int j = messagesList->size(); j > 0;) {
auto &message = messagesList->at(--j);
if (idFromMessage(message) == msgId && peerFromMessage(message) == peer) {
if (auto date = dateFromMessage(message)) {
lastDate = date;
auto &dialogData = dialog.c_dialog();
if (auto peer = peerFromMTP(dialogData.vpeer)) {
auto history = App::history(peer);
history->setPinnedDialog(dialogData.is_pinned());
if (!lastDate) {
if (!lastPeer) lastPeer = peer;
if (auto msgId = dialogData.vtop_message.v) {
if (!lastMsgId) lastMsgId = msgId;
for (int j = messagesList->size(); j > 0;) {
auto &message = messagesList->at(--j);
if (idFromMessage(message) == msgId && peerFromMessage(message) == peer) {
if (auto date = dateFromMessage(message)) {
lastDate = date;
}
break;
}
break;
}
}
if (lastDate) break;
}
}
}
@ -2126,20 +2124,61 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque
} else {
_dialogsFull = true;
}
t_assert(messagesList != nullptr);
App::feedMsgs(*messagesList, NewMessageLast);
unreadCountsReceived(*dialogsList);
_inner->dialogsReceived(*dialogsList);
onListScroll();
} else {
_dialogsFull = true;
}
_dialogsRequest = 0;
_dialogsRequestId = 0;
loadDialogs();
}
bool DialogsWidget::dialogsFailed(const RPCError &error, mtpRequestId req) {
void DialogsWidget::pinnedDialogsReceived(const MTPmessages_PeerDialogs &dialogs, mtpRequestId requestId) {
if (_pinnedDialogsRequestId != requestId) return;
if (dialogs.type() == mtpc_messages_peerDialogs) {
App::histories().clearPinned();
auto &dialogsData = dialogs.c_messages_peerDialogs();
App::feedUsers(dialogsData.vusers);
App::feedChats(dialogsData.vchats);
auto &list = dialogsData.vdialogs.c_vector().v;
for (auto i = list.size(); i > 0;) {
auto &dialog = list[--i];
if (dialog.type() != mtpc_dialog) {
continue;
}
auto &dialogData = dialog.c_dialog();
if (auto peer = peerFromMTP(dialogData.vpeer)) {
auto history = App::history(peer);
history->setPinnedDialog(dialogData.is_pinned());
}
}
App::feedMsgs(dialogsData.vmessages, NewMessageLast);
unreadCountsReceived(list);
_inner->dialogsReceived(list);
onListScroll();
}
_pinnedDialogsRequestId = 0;
_pinnedDialogsReceived = true;
}
bool DialogsWidget::dialogsFailed(const RPCError &error, mtpRequestId requestId) {
if (MTP::isDefaultHandledError(error)) return false;
LOG(("RPC Error: %1 %2: %3").arg(error.code()).arg(error.type()).arg(error.description()));
if (_dialogsRequest == req) {
_dialogsRequest = 0;
if (_dialogsRequestId == requestId) {
_dialogsRequestId = 0;
} else if (_pinnedDialogsRequestId == requestId) {
_pinnedDialogsRequestId = 0;
}
return true;
}
@ -2245,18 +2284,31 @@ void DialogsWidget::onSearchMore() {
}
void DialogsWidget::loadDialogs() {
if (_dialogsRequest) return;
if (_dialogsRequestId) return;
if (_dialogsFull) {
_inner->addAllSavedPeers();
cSetDialogsReceived(true);
return;
}
int32 loadCount = _dialogsOffsetDate ? DialogsPerPage : DialogsFirstLoad;
_dialogsRequest = MTP::send(MTPmessages_GetDialogs(MTP_int(_dialogsOffsetDate), MTP_int(_dialogsOffsetId), _dialogsOffsetPeer ? _dialogsOffsetPeer->input : MTP_inputPeerEmpty(), MTP_int(loadCount)), rpcDone(&DialogsWidget::dialogsReceived), rpcFail(&DialogsWidget::dialogsFailed));
auto firstLoad = !_dialogsOffsetDate;
auto loadCount = firstLoad ? DialogsFirstLoad : DialogsPerPage;
auto flags = qFlags(MTPmessages_GetDialogs::Flag::f_exclude_pinned);
_dialogsRequestId = MTP::send(MTPmessages_GetDialogs(MTP_flags(flags), MTP_int(_dialogsOffsetDate), MTP_int(_dialogsOffsetId), _dialogsOffsetPeer ? _dialogsOffsetPeer->input : MTP_inputPeerEmpty(), MTP_int(loadCount)), rpcDone(&DialogsWidget::dialogsReceived), rpcFail(&DialogsWidget::dialogsFailed));
if (!_pinnedDialogsReceived) {
loadPinnedDialogs();
}
}
void DialogsWidget::loadPinnedDialogs() {
if (_pinnedDialogsRequestId) return;
_pinnedDialogsReceived = false;
_pinnedDialogsRequestId = MTP::send(MTPmessages_GetPinnedDialogs(), rpcDone(&DialogsWidget::pinnedDialogsReceived), rpcFail(&DialogsWidget::dialogsFailed));
}
void DialogsWidget::contactsReceived(const MTPcontacts_Contacts &result) {
_contactsRequestId = 0;
cSetContactsReceived(true);
if (result.type() == mtpc_contacts_contacts) {
auto &d = result.c_contacts_contacts();
@ -2268,7 +2320,7 @@ void DialogsWidget::contactsReceived(const MTPcontacts_Contacts &result) {
bool DialogsWidget::contactsFailed(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
_contactsRequestId = 0;
return true;
}

View File

@ -280,6 +280,7 @@ public:
void searchInPeer(PeerData *peer);
void loadDialogs();
void loadPinnedDialogs();
void createDialog(History *history);
void dlgUpdated(Dialogs::Mode list, Dialogs::Row *row);
void dlgUpdated(PeerData *peer, MsgId msgId);
@ -350,10 +351,11 @@ protected:
private:
void animationCallback();
void dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpRequestId req);
void dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpRequestId requestId);
void pinnedDialogsReceived(const MTPmessages_PeerDialogs &dialogs, mtpRequestId requestId);
void contactsReceived(const MTPcontacts_Contacts &result);
void searchReceived(DialogsSearchRequestType type, const MTPmessages_Messages &result, mtpRequestId req);
void peerSearchReceived(const MTPcontacts_Found &result, mtpRequestId req);
void searchReceived(DialogsSearchRequestType type, const MTPmessages_Messages &result, mtpRequestId requestId);
void peerSearchReceived(const MTPcontacts_Found &result, mtpRequestId requestId);
void setSearchInPeer(PeerData *peer);
void showMainMenu();
@ -375,8 +377,10 @@ private:
int32 _dialogsOffsetDate = 0;
MsgId _dialogsOffsetId = 0;
PeerData *_dialogsOffsetPeer = nullptr;
mtpRequestId _dialogsRequest = 0;
mtpRequestId _contactsRequest = 0;
mtpRequestId _dialogsRequestId = 0;
mtpRequestId _pinnedDialogsRequestId = 0;
mtpRequestId _contactsRequestId = 0;
bool _pinnedDialogsReceived = false;
ChildWidget<Ui::IconButton> _forwardCancel = { nullptr };
ChildWidget<Ui::IconButton> _mainMenuToggle;

View File

@ -633,6 +633,7 @@ struct Data {
int32 SavedGifsLimit = 200;
int32 EditTimeLimit = 172800;
int32 StickersRecentLimit = 30;
int32 PinnedDialogsCountMax = 5;
HiddenPinnedMessagesMap HiddenPinnedMessages;
@ -751,6 +752,7 @@ DefineVar(Global, int32, PushChatLimit);
DefineVar(Global, int32, SavedGifsLimit);
DefineVar(Global, int32, EditTimeLimit);
DefineVar(Global, int32, StickersRecentLimit);
DefineVar(Global, int32, PinnedDialogsCountMax);
DefineVar(Global, HiddenPinnedMessagesMap, HiddenPinnedMessages);

View File

@ -328,6 +328,7 @@ DeclareVar(int32, PushChatLimit);
DeclareVar(int32, SavedGifsLimit);
DeclareVar(int32, EditTimeLimit);
DeclareVar(int32, StickersRecentLimit);
DeclareVar(int32, PinnedDialogsCountMax);
typedef QMap<PeerId, MsgId> HiddenPinnedMessagesMap;
DeclareVar(HiddenPinnedMessagesMap, HiddenPinnedMessages);

View File

@ -46,6 +46,8 @@ constexpr int kStatusShowClientsideChooseContact = 6000;
constexpr int kStatusShowClientsidePlayGame = 10000;
constexpr int kSetMyActionForMs = 10000;
auto GlobalPinnedIndex = 0;
} // namespace
void historyInit() {
@ -203,12 +205,12 @@ bool History::updateSendActionNeedsAnimating(UserData *user, const MTPSendMessag
case mtpc_sendMessageUploadDocumentAction: _sendActions.insert(user, { Type::UploadFile, ms + kStatusShowClientsideUploadFile, action.c_sendMessageUploadDocumentAction().vprogress.v }); break;
case mtpc_sendMessageGeoLocationAction: _sendActions.insert(user, { Type::ChooseLocation, ms + kStatusShowClientsideChooseLocation }); break;
case mtpc_sendMessageChooseContactAction: _sendActions.insert(user, { Type::ChooseContact, ms + kStatusShowClientsideChooseContact }); break;
//case mtpc_sendMessageGamePlayAction: { // TODO
// auto it = _sendActions.find(user);
// if (it == _sendActions.end() || it->type == Type::PlayGame || it->until <= ms) {
// _sendActions.insert(user, { Type::PlayGame, ms + kStatusShowClientsidePlayGame });
// }
//} break;
case mtpc_sendMessageGamePlayAction: {
auto it = _sendActions.find(user);
if (it == _sendActions.end() || it->type == Type::PlayGame || it->until <= ms) {
_sendActions.insert(user, { Type::PlayGame, ms + kStatusShowClientsidePlayGame });
}
} break;
default: return false;
}
return updateSendActionNeedsAnimating(ms, true);
@ -622,8 +624,8 @@ History *Histories::findOrInsert(const PeerId &peerId, int32 unreadCount, int32
void Histories::clear() {
App::historyClearMsgs();
Map temp;
std::swap(temp, map);
_pinnedDialogs.clear();
auto temp = base::take(map);
for_const (auto history, temp) {
delete history;
}
@ -712,6 +714,32 @@ bool Histories::unreadOnlyMuted() const {
return Global::IncludeMuted() ? (_unreadMuted >= _unreadFull) : false;
}
void Histories::setIsPinned(History *history, bool isPinned) {
if (isPinned) {
_pinnedDialogs.insert(history);
if (_pinnedDialogs.size() > Global::PinnedDialogsCountMax()) {
auto minIndex = GlobalPinnedIndex + 1;
auto minIndexHistory = (History*)nullptr;
for_const (auto pinned, _pinnedDialogs) {
if (pinned->getPinnedIndex() < minIndex) {
minIndex = pinned->getPinnedIndex();
minIndexHistory = pinned;
}
}
t_assert(minIndexHistory != nullptr);
minIndexHistory->setPinnedDialog(false);
}
} else {
_pinnedDialogs.remove(history);
}
}
void Histories::clearPinned() {
for (auto pinned : base::take(_pinnedDialogs)) {
pinned->setPinnedDialog(false);
}
}
HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction, bool detachExistingItem) {
MsgId msgId = 0;
switch (msg.type()) {
@ -779,7 +807,7 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
case mtpc_webPage:
case mtpc_webPageEmpty:
case mtpc_webPagePending: break;
// case mtpc_webPageNotModified: // TODO
case mtpc_webPageNotModified:
default: badMedia = 1; break;
}
break;
@ -1810,6 +1838,10 @@ inline uint64 dialogPosFromDate(const QDateTime &date) {
return (uint64(date.toTime_t()) << 32) | (++_dialogsPosToTopShift);
}
inline uint64 pinnedDialogPos(int pinnedIndex) {
return 0xFFFFFFFF00000000ULL + pinnedIndex;
}
void History::setLastMessage(HistoryItem *msg) {
if (msg) {
if (!lastMsg) Local::removeSavedPeer(peer);
@ -1822,7 +1854,7 @@ void History::setLastMessage(HistoryItem *msg) {
}
bool History::needUpdateInChatList() const {
if (inChatList(Dialogs::Mode::All)) {
if (inChatList(Dialogs::Mode::All) || isPinnedDialog()) {
return true;
} else if (peer->migrateTo()) {
return false;
@ -1831,9 +1863,8 @@ bool History::needUpdateInChatList() const {
}
void History::setChatsListDate(const QDateTime &date) {
bool updateDialog = needUpdateInChatList();
if (!lastMsgDate.isNull() && lastMsgDate >= date) {
if (!updateDialog || !inChatList(Dialogs::Mode::All)) {
if (!needUpdateInChatList() || !inChatList(Dialogs::Mode::All)) {
return;
}
}
@ -1851,7 +1882,7 @@ void History::updateChatListSortPosition() {
return lastMsgDate;
};
_sortKeyInChatList = dialogPosFromDate(chatListDate());
_sortKeyInChatList = isPinnedDialog() ? pinnedDialogPos(_pinnedIndex) : dialogPosFromDate(chatListDate());
if (auto m = App::main()) {
if (needUpdateInChatList()) {
if (_sortKeyInChatList) {
@ -2071,6 +2102,20 @@ void History::updateChatListEntry() const {
}
}
void History::setPinnedDialog(bool isPinned) {
auto pinnedIndex = isPinned ? (++GlobalPinnedIndex) : 0;
if (_pinnedIndex != pinnedIndex) {
auto wasPinned = isPinnedDialog();
_pinnedIndex = pinnedIndex;
updateChatListSortPosition();
updateChatListEntry();
if (wasPinned != isPinnedDialog()) {
Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::PinnedChanged);
}
App::histories().setIsPinned(this, isPinnedDialog());
}
}
void History::overviewSliceDone(int32 overviewIndex, const MTPmessages_Messages &result, bool onlyCounts) {
const QVector<MTPMessage> *v = 0;
switch (result.type()) {

View File

@ -82,6 +82,9 @@ public:
}
}
void setIsPinned(History *history, bool isPinned);
void clearPinned();
struct SendActionAnimationUpdate {
History *history;
int width;
@ -93,8 +96,10 @@ public:
}
private:
int _unreadFull, _unreadMuted;
int _unreadFull = 0;
int _unreadMuted = 0;
base::Observable<SendActionAnimationUpdate> _sendActionAnimationUpdated;
OrderedSet<History*> _pinnedDialogs;
};
@ -281,6 +286,14 @@ public:
void addChatListEntryByLetter(Dialogs::Mode list, QChar letter, Dialogs::Row *row);
void updateChatListEntry() const;
bool isPinnedDialog() const {
return (_pinnedIndex > 0);
}
void setPinnedDialog(bool isPinned);
int getPinnedIndex() const {
return _pinnedIndex;
}
MsgId minMsgId() const;
MsgId maxMsgId() const;
MsgId msgIdForRead() const;
@ -564,6 +577,7 @@ private:
Ui::SendActionAnimation _sendActionAnimation;
QMap<SendAction::Type, TimeMs> _mySendActions;
int _pinnedIndex = 0; // > 0 for pinned dialogs
};

View File

@ -68,12 +68,14 @@ MediaOverviewType serviceMediaToOverviewType(HistoryMedia *media) {
ApiWrap::RequestMessageDataCallback historyDependentItemCallback(const FullMsgId &msgId) {
return [dependent = msgId](ChannelData *channel, MsgId msgId) {
if (HistoryItem *item = App::histItemById(dependent)) {
if (auto item = App::histItemById(dependent)) {
item->updateDependencyItem();
}
};
}
constexpr auto kPinnedMessageTextLimit = 16;
} // namespace
void historyInitMessages() {
@ -687,7 +689,7 @@ void HistoryMessage::initMedia(const MTPMessageMedia *media) {
case mtpc_webPage: {
_media.reset(new HistoryWebPage(this, App::feedWebPage(d.c_webPage())));
} break;
// case mtpc_webPageNotModified: LOG(("API Error: webPageNotModified is unexpected in message media.")); break; // TODO
case mtpc_webPageNotModified: LOG(("API Error: webPageNotModified is unexpected in message media.")); break;
}
} break;
case mtpc_messageMediaGame: {
@ -1975,19 +1977,21 @@ bool HistoryService::preparePinnedText(const QString &from, QString *outText, Li
} break;
}
if (mediaText.isEmpty()) {
QString original = pinned->msg->originalText().text;
int32 cutat = 0, limit = PinnedMessageTextLimit, size = original.size();
for (; limit > 0;) {
auto original = pinned->msg->originalText().text;
auto cutAt = 0;
auto limit = kPinnedMessageTextLimit;
auto size = original.size();
for (; limit != 0;) {
--limit;
if (cutat >= size) break;
if (original.at(cutat).isLowSurrogate() && cutat + 1 < size && original.at(cutat + 1).isHighSurrogate()) {
cutat += 2;
if (cutAt >= size) break;
if (original.at(cutAt).isLowSurrogate() && cutAt + 1 < size && original.at(cutAt + 1).isHighSurrogate()) {
cutAt += 2;
} else {
++cutat;
++cutAt;
}
}
if (!limit && cutat + 5 < size) {
original = original.mid(0, cutat) + qstr("...");
if (!limit && cutAt + 5 < size) {
original = original.mid(0, cutAt) + qstr("...");
}
text = lng_action_pinned_message(lt_from, from, lt_text, textcmdLink(2, original));
} else {

View File

@ -3456,7 +3456,7 @@ void HistoryWidget::updateSendAction(History *history, SendAction::Type type, in
case Type::UploadFile: action = MTP_sendMessageUploadDocumentAction(MTP_int(progress)); break;
case Type::ChooseLocation: action = MTP_sendMessageGeoLocationAction(); break;
case Type::ChooseContact: action = MTP_sendMessageChooseContactAction(); break;
case Type::PlayGame: return;// action = MTP_sendMessageGamePlayAction(); break; // TODO
case Type::PlayGame: action = MTP_sendMessageGamePlayAction(); break;
}
_sendActionRequests.insert(qMakePair(history, type), MTP::send(MTPmessages_SetTyping(history->peer->input, action), rpcDone(&HistoryWidget::sendActionDone)));
if (type == Type::Typing) _sendActionStopTimer.start(5000);

View File

@ -834,10 +834,11 @@ void MainWidget::deleteConversation(PeerData *peer, bool deleteHistory) {
if (activePeer() == peer) {
Ui::showChatsList();
}
if (History *h = App::historyLoaded(peer->id)) {
removeDialog(h);
if (auto history = App::historyLoaded(peer->id)) {
history->setPinnedDialog(false);
removeDialog(history);
if (peer->isMegagroup() && peer->asChannel()->mgInfo->migrateFromPtr) {
if (History *migrated = App::historyLoaded(peer->asChannel()->mgInfo->migrateFromPtr->id)) {
if (auto migrated = App::historyLoaded(peer->asChannel()->mgInfo->migrateFromPtr->id)) {
if (migrated->lastMsg) { // return initial dialog
migrated->setLastMessage(migrated->lastMsg);
} else {
@ -845,9 +846,9 @@ void MainWidget::deleteConversation(PeerData *peer, bool deleteHistory) {
}
}
}
h->clear();
h->newLoaded = true;
h->oldLoaded = deleteHistory;
history->clear();
history->newLoaded = true;
history->oldLoaded = deleteHistory;
}
if (peer->isChannel()) {
peer->asChannel()->ptsWaitingForShortPoll(-1);
@ -1149,10 +1150,10 @@ void executeParsedCommand(const QString &command) {
return;
}
if (command == qsl("new_version_text")) {
App::wnd()->serviceNotification(langNewVersionText());
App::wnd()->serviceNotificationLocal(langNewVersionText());
} else if (command == qsl("all_new_version_texts")) {
for (int i = 0; i < languageCount; ++i) {
App::wnd()->serviceNotification(langNewVersionTextForLang(i));
App::wnd()->serviceNotificationLocal(langNewVersionTextForLang(i));
}
}
}
@ -1795,15 +1796,14 @@ void MainWidget::dialogsCancelled() {
_history->activate();
}
void MainWidget::serviceNotification(const QString &msg, const MTPMessageMedia &media) {
void MainWidget::serviceNotification(const TextWithEntities &message, const MTPMessageMedia &media, int32 date) {
MTPDmessage::Flags flags = MTPDmessage::Flag::f_entities | MTPDmessage::Flag::f_from_id | MTPDmessage_ClientFlag::f_clientside_unread;
QString sendingText, leftText = msg;
EntitiesInText sendingEntities, leftEntities;
textParseEntities(leftText, _historyTextNoMonoOptions.flags, &leftEntities);
HistoryItem *item = 0;
QString sendingText, leftText = message.text;
EntitiesInText sendingEntities, leftEntities = message.entities;
HistoryItem *item = nullptr;
while (textSplit(sendingText, sendingEntities, leftText, leftEntities, MaxMessageSize)) {
MTPVector<MTPMessageEntity> localEntities = linksToMTP(sendingEntities);
item = App::histories().addNewMessage(MTP_message(MTP_flags(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPnullFwdHeader, MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(sendingText), media, MTPnullMarkup, localEntities, MTPint(), MTPint()), NewMessageUnread);
item = App::histories().addNewMessage(MTP_message(MTP_flags(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPnullFwdHeader, MTPint(), MTPint(), MTP_int(date), MTP_string(sendingText), media, MTPnullMarkup, localEntities, MTPint(), MTPint()), NewMessageUnread);
}
if (item) {
_history->peerMessagesUpdated(item->history()->peer->id);
@ -1990,6 +1990,32 @@ void MainWidget::scheduleViewIncrement(HistoryItem *item) {
}
void MainWidget::fillPeerMenu(PeerData *peer, base::lambda<QAction*(const QString &text, base::lambda<void()> &&handler)> &&callback) {
auto isPinned = false;
if (auto history = App::historyLoaded(peer)) {
isPinned = history->isPinnedDialog();
}
auto pinSubscription = MakeShared<base::Subscription>();
auto pinAction = callback(lang(isPinned ? lng_context_unpin_from_top : lng_context_pin_to_top), [peer, pinSubscription] {
auto history = App::history(peer);
auto isPinned = !history->isPinnedDialog();
history->setPinnedDialog(isPinned);
auto flags = MTPmessages_ToggleDialogPin::Flags(0);
if (isPinned) {
flags |= MTPmessages_ToggleDialogPin::Flag::f_pinned;
}
MTP::send(MTPmessages_ToggleDialogPin(MTP_flags(flags), peer->input));
if (isPinned) {
if (auto main = App::main()) {
main->dialogsToUp();
}
}
});
auto pinChangedHandler = Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::PinnedChanged, [pinAction, peer](const Notify::PeerUpdate &update) {
if (update.peer != peer) return;
pinAction->setText(lang(App::history(peer)->isPinnedDialog() ? lng_context_unpin_from_top : lng_context_pin_to_top));
});
*pinSubscription = Notify::PeerUpdated().add_subscription(std_::move(pinChangedHandler));
callback(lang((peer->isChat() || peer->isMegagroup()) ? lng_context_view_group : (peer->isUser() ? lng_context_view_profile : lng_context_view_channel)), [peer] {
Ui::showPeerProfile(peer);
});
@ -4734,6 +4760,10 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
auto &d = update.c_updateEncryptedMessagesRead();
} break;
case mtpc_updatePhoneCall: {
auto &d = update.c_updatePhoneCall();
} break;
case mtpc_updateUserBlocked: {
auto &d = update.c_updateUserBlocked();
if (auto user = App::userLoaded(d.vuser_id.v)) {
@ -4742,25 +4772,13 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
}
} break;
case mtpc_updateNewAuthorization: {
auto &d = update.c_updateNewAuthorization();
QDateTime datetime = date(d.vdate);
QString name = App::self()->firstName;
QString day = langDayOfWeekFull(datetime.date()), date = langDayOfMonthFull(datetime.date()), time = datetime.time().toString(cTimeFormat());
QString device = qs(d.vdevice), location = qs(d.vlocation);
LangString text = lng_new_authorization(lt_name, App::self()->firstName, lt_day, day, lt_date, date, lt_time, time, lt_device, device, lt_location, location);
App::wnd()->serviceNotification(text);
emit App::wnd()->newAuthorization();
} break;
case mtpc_updateServiceNotification: {
auto &d = update.c_updateServiceNotification();
if (mtpIsTrue(d.vpopup)) {
if (d.is_popup()) {
Ui::showLayer(new InformBox(qs(d.vmessage)));
} else {
App::wnd()->serviceNotification(qs(d.vmessage), d.vmedia);
App::wnd()->serviceNotification({ qs(d.vmessage), entitiesFromMTP(d.ventities.c_vector().v) }, d.vmedia);
emit App::wnd()->checkNewAuthorization();
}
} break;
@ -4768,6 +4786,45 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
auto &d = update.c_updatePrivacy();
} break;
case mtpc_updatePinnedDialogs: {
auto &d = update.c_updatePinnedDialogs();
if (d.has_order()) {
auto allLoaded = true;
auto &order = d.vorder.c_vector().v;
for_const (auto &peer, order) {
auto peerId = peerFromMTP(peer);
if (!App::historyLoaded(peerId)) {
allLoaded = false;
DEBUG_LOG(("API Error: pinned chat not loaded for peer %1").arg(peerId));
break;
}
}
if (allLoaded) {
App::histories().clearPinned();
for (auto i = order.size(); i != 0;) {
auto history = App::historyLoaded(peerFromMTP(order[--i]));
t_assert(history != nullptr);
history->setPinnedDialog(true);
}
} else {
_dialogs->loadPinnedDialogs();
}
} else {
_dialogs->loadPinnedDialogs();
}
} break;
case mtpc_updateDialogPinned: {
auto &d = update.c_updateDialogPinned();
auto peerId = peerFromMTP(d.vpeer);
if (auto history = App::historyLoaded(peerId)) {
history->setPinnedDialog(d.is_pinned());
} else {
DEBUG_LOG(("API Error: pinned chat not loaded for peer %1").arg(peerId));
_dialogs->loadPinnedDialogs();
}
} break;
/////// Channel updates
case mtpc_updateChannel: {
auto &d = update.c_updateChannel();

View File

@ -309,7 +309,7 @@ public:
void checkLastUpdate(bool afterSleep);
void serviceNotification(const QString &msg, const MTPMessageMedia &media);
void serviceNotification(const TextWithEntities &message, const MTPMessageMedia &media, int32 date);
void serviceHistoryDone(const MTPmessages_Messages &msgs);
bool serviceHistoryFail(const RPCError &error);

View File

@ -329,21 +329,26 @@ void MainWindow::setupIntro() {
}
}
void MainWindow::serviceNotification(const QString &msg, const MTPMessageMedia &media, bool force) {
History *h = (_main && App::userLoaded(ServiceUserId)) ? App::history(ServiceUserId) : 0;
void MainWindow::serviceNotification(const TextWithEntities &message, const MTPMessageMedia &media, int32 date, bool force) {
if (date <= 0) date = unixtime();
auto h = (_main && App::userLoaded(ServiceUserId)) ? App::history(ServiceUserId) : nullptr;
if (!h || (!force && h->isEmpty())) {
_delayedServiceMsgs.push_back(DelayedServiceMsg(msg, media));
_delayedServiceMsgs.push_back(DelayedServiceMsg(message, media, date));
return sendServiceHistoryRequest();
}
_main->serviceNotification(msg, media);
_main->serviceNotification(message, media, date);
}
void MainWindow::serviceNotificationLocal(QString text) {
EntitiesInText entities;
textParseEntities(text, _historyTextNoMonoOptions.flags, &entities);
serviceNotification({ text, entities });
}
void MainWindow::showDelayedServiceMsgs() {
QVector<DelayedServiceMsg> toAdd = _delayedServiceMsgs;
_delayedServiceMsgs.clear();
for (QVector<DelayedServiceMsg>::const_iterator i = toAdd.cbegin(), e = toAdd.cend(); i != e; ++i) {
serviceNotification(i->first, i->second, true);
for (auto &delayed : base::take(_delayedServiceMsgs)) {
serviceNotification(delayed.message, delayed.media, delayed.date, true);
}
}

View File

@ -96,7 +96,8 @@ public:
void checkAutoLockIn(int msec);
void setupIntro();
void setupMain(const MTPUser *user = 0);
void serviceNotification(const QString &msg, const MTPMessageMedia &media = MTP_messageMediaEmpty(), bool force = false);
void serviceNotification(const TextWithEntities &message, const MTPMessageMedia &media = MTP_messageMediaEmpty(), int32 date = 0, bool force = false);
void serviceNotificationLocal(QString text);
void sendServiceHistoryRequest();
void showDelayedServiceMsgs();
@ -215,7 +216,7 @@ public slots:
signals:
void tempDirCleared(int task);
void tempDirClearFailed(int task);
void newAuthorization();
void checkNewAuthorization();
private slots:
void onStateChanged(Qt::WindowState state);
@ -236,8 +237,14 @@ private:
void placeSmallCounter(QImage &img, int size, int count, const style::color &bg, const QPoint &shift, const style::color &color) override;
QImage icon16, icon32, icon64, iconbig16, iconbig32, iconbig64;
typedef QPair<QString, MTPMessageMedia> DelayedServiceMsg;
QVector<DelayedServiceMsg> _delayedServiceMsgs;
struct DelayedServiceMsg {
DelayedServiceMsg(const TextWithEntities &message, const MTPMessageMedia &media, int32 date) : message(message), media(media), date(date) {
}
TextWithEntities message;
MTPMessageMedia media;
int32 date;
};
QList<DelayedServiceMsg> _delayedServiceMsgs;
mtpRequestId _serviceHistoryRequest = 0;
ChildWidget<PasscodeWidget> _passcode = { nullptr };

View File

@ -145,45 +145,50 @@ void Dcenter::destroyKey() {
}
namespace {
ConfigLoader *_configLoader = nullptr;
bool loadingConfig = false;
void configLoaded(const MTPConfig &result) {
loadingConfig = false;
const auto &data(result.c_config());
ConfigLoader *_configLoader = nullptr;
auto loadingConfig = false;
DEBUG_LOG(("MTP Info: got config, chat_size_max: %1, date: %2, test_mode: %3, this_dc: %4, dc_options.length: %5").arg(data.vchat_size_max.v).arg(data.vdate.v).arg(mtpIsTrue(data.vtest_mode)).arg(data.vthis_dc.v).arg(data.vdc_options.c_vector().v.size()));
void configLoaded(const MTPConfig &result) {
loadingConfig = false;
updateDcOptions(data.vdc_options.c_vector().v);
auto &data = result.c_config();
Global::SetChatSizeMax(data.vchat_size_max.v);
Global::SetMegagroupSizeMax(data.vmegagroup_size_max.v);
Global::SetForwardedCountMax(data.vforwarded_count_max.v);
Global::SetOnlineUpdatePeriod(data.vonline_update_period_ms.v);
Global::SetOfflineBlurTimeout(data.voffline_blur_timeout_ms.v);
Global::SetOfflineIdleTimeout(data.voffline_idle_timeout_ms.v);
Global::SetOnlineCloudTimeout(data.vonline_cloud_timeout_ms.v);
Global::SetNotifyCloudDelay(data.vnotify_cloud_delay_ms.v);
Global::SetNotifyDefaultDelay(data.vnotify_default_delay_ms.v);
Global::SetChatBigSize(data.vchat_big_size.v); // ?
Global::SetPushChatPeriod(data.vpush_chat_period_ms.v); // ?
Global::SetPushChatLimit(data.vpush_chat_limit.v); // ?
Global::SetSavedGifsLimit(data.vsaved_gifs_limit.v);
Global::SetEditTimeLimit(data.vedit_time_limit.v); // ?
Global::SetStickersRecentLimit(data.vstickers_recent_limit.v);
DEBUG_LOG(("MTP Info: got config, chat_size_max: %1, date: %2, test_mode: %3, this_dc: %4, dc_options.length: %5").arg(data.vchat_size_max.v).arg(data.vdate.v).arg(mtpIsTrue(data.vtest_mode)).arg(data.vthis_dc.v).arg(data.vdc_options.c_vector().v.size()));
configLoadedOnce = true;
Local::writeSettings();
updateDcOptions(data.vdc_options.c_vector().v);
configLoader()->done();
}
bool configFailed(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
Global::SetChatSizeMax(data.vchat_size_max.v);
Global::SetMegagroupSizeMax(data.vmegagroup_size_max.v);
Global::SetForwardedCountMax(data.vforwarded_count_max.v);
Global::SetOnlineUpdatePeriod(data.vonline_update_period_ms.v);
Global::SetOfflineBlurTimeout(data.voffline_blur_timeout_ms.v);
Global::SetOfflineIdleTimeout(data.voffline_idle_timeout_ms.v);
Global::SetOnlineCloudTimeout(data.vonline_cloud_timeout_ms.v);
Global::SetNotifyCloudDelay(data.vnotify_cloud_delay_ms.v);
Global::SetNotifyDefaultDelay(data.vnotify_default_delay_ms.v);
Global::SetChatBigSize(data.vchat_big_size.v); // ?
Global::SetPushChatPeriod(data.vpush_chat_period_ms.v); // ?
Global::SetPushChatLimit(data.vpush_chat_limit.v); // ?
Global::SetSavedGifsLimit(data.vsaved_gifs_limit.v);
Global::SetEditTimeLimit(data.vedit_time_limit.v); // ?
Global::SetStickersRecentLimit(data.vstickers_recent_limit.v);
Global::SetPinnedDialogsCountMax(data.vpinned_dialogs_count_max.v);
configLoadedOnce = true;
Local::writeSettings();
configLoader()->done();
}
bool configFailed(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
loadingConfig = false;
LOG(("MTP Error: failed to get config!"));
return false;
}
loadingConfig = false;
LOG(("MTP Error: failed to get config!"));
return false;
}
};
void updateDcOptions(const QVector<MTPDcOption> &options) {

View File

@ -254,7 +254,7 @@ messageActionPinMessage#94bd38ed = MessageAction;
messageActionHistoryClear#9fbab604 = MessageAction;
messageActionGameScore#92a72876 game_id:long score:int = 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;
dialog#66ffba14 flags:# pinned:flags.2?true 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;
photoEmpty#2331b22d id:long = Photo;
photo#9288dd29 flags:# has_stickers:flags.0?true id:long access_hash:long date:int sizes:Vector<PhotoSize> = Photo;
@ -328,7 +328,7 @@ messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<C
messages.channelMessages#99262e37 flags:# pts:int count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
messages.chatsSlice#78f69146 count:int chats:Vector<Chat> users:Vector<User> = messages.Chats;
messages.chatsSlice#9cd81144 count:int chats:Vector<Chat> = messages.Chats;
messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
@ -357,7 +357,6 @@ updateUserName#a7332b73 user_id:int first_name:string last_name:string username:
updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bool = Update;
updateContactRegistered#2575bbb9 user_id:int date:int = Update;
updateContactLink#9d2e67c5 user_id:int my_link:ContactLink foreign_link:ContactLink = Update;
updateNewAuthorization#8f06529a auth_key_id:long date:int device:string location:string = Update;
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
updateEncryptedChatTyping#1710f156 chat_id:int = Update;
updateEncryption#b4a2e88d chat:EncryptedChat date:int = Update;
@ -367,7 +366,7 @@ updateChatParticipantDelete#6e5f8c22 chat_id:int user_id:int version:int = Updat
updateDcOptions#8e5e9873 dc_options:Vector<DcOption> = Update;
updateUserBlocked#80ece81a user_id:int blocked:Bool = Update;
updateNotifySettings#bec268ef peer:NotifyPeer notify_settings:PeerNotifySettings = Update;
updateServiceNotification#382dd3e4 type:string message:string media:MessageMedia popup:Bool = Update;
updateServiceNotification#ebe46819 flags:# popup:flags.0?true inbox_date:flags.1?int type:string message:string media:MessageMedia entities:Vector<MessageEntity> = Update;
updatePrivacy#ee3b272a key:PrivacyKey rules:Vector<PrivacyRule> = Update;
updateUserPhone#12b9417b user_id:int phone:string = Update;
updateReadHistoryInbox#9961fd5c peer:Peer max_id:int pts:int pts_count:int = Update;
@ -400,6 +399,9 @@ updateRecentStickers#9a422c20 = Update;
updateConfig#a229dd06 = Update;
updatePtsChanged#3354678f = Update;
updateChannelWebPage#40771900 channel_id:int webpage:WebPage pts:int pts_count:int = Update;
updatePhoneCall#ab0f6b1e phone_call:PhoneCall = Update;
updateDialogPinned#d711a2cc flags:# pinned:flags.0?true peer:Peer = Update;
updatePinnedDialogs#d8caf68d flags:# order:flags.0?Vector<Peer> = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@ -425,7 +427,7 @@ upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
dcOption#5d8c6cc flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true id:int ip_address:string port:int = DcOption;
config#9a6b2e2a flags:# date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int chat_big_size:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int rating_e_decay:int stickers_recent_limit:int tmp_sessions:flags.0?int disabled_features:Vector<DisabledFeature> = Config;
config#3af6fb5f flags:# phonecalls_enabled:flags.1?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int chat_big_size:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int rating_e_decay:int stickers_recent_limit:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int disabled_features:Vector<DisabledFeature> = Config;
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
@ -482,14 +484,17 @@ sendMessageUploadPhotoAction#d1d34a26 progress:int = SendMessageAction;
sendMessageUploadDocumentAction#aa0cd9e4 progress:int = SendMessageAction;
sendMessageGeoLocationAction#176f8ba1 = SendMessageAction;
sendMessageChooseContactAction#628cbc6f = SendMessageAction;
sendMessageGamePlayAction#dd6a8f48 = SendMessageAction;
contacts.found#1aa1f784 results:Vector<Peer> chats:Vector<Chat> users:Vector<User> = contacts.Found;
inputPrivacyKeyStatusTimestamp#4f96cb18 = InputPrivacyKey;
inputPrivacyKeyChatInvite#bdfb0426 = InputPrivacyKey;
inputPrivacyKeyPhoneCall#fabadc5f = InputPrivacyKey;
privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey;
privacyKeyChatInvite#500e6dfa = PrivacyKey;
privacyKeyPhoneCall#3d662b7b = PrivacyKey;
inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule;
inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule;
@ -536,7 +541,8 @@ contactLinkContact#d502c2d0 = ContactLink;
webPageEmpty#eb1477e8 id:long = WebPage;
webPagePending#c586da1c id:long date:int = WebPage;
webPage#ca820ed7 flags:# id:long url:string display_url:string type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document = WebPage;
webPage#5f07b4bc flags:# id:long url:string display_url:string hash:int type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document cached_page:flags.10?Page = WebPage;
webPageNotModified#85849473 = WebPage;
authorization#7bf2e6f6 hash:long flags:int device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
@ -587,7 +593,7 @@ replyKeyboardMarkup#3502758c flags:# resize:flags.0?true single_use:flags.1?true
replyInlineMarkup#48a30254 rows:Vector<KeyboardButtonRow> = ReplyMarkup;
help.appChangelogEmpty#af7e0394 = help.AppChangelog;
help.appChangelog#4668e6bd text:string = help.AppChangelog;
help.appChangelog#2a137e7c message:string media:MessageMedia entities:Vector<MessageEntity> = help.AppChangelog;
messageEntityUnknown#bb92ba95 offset:int length:int = MessageEntity;
messageEntityMention#fa04579d offset:int length:int = MessageEntity;
@ -737,6 +743,61 @@ highScore#58fffcd0 pos:int user_id:int score:int = HighScore;
messages.highScores#9a3bfd99 scores:Vector<HighScore> users:Vector<User> = messages.HighScores;
textEmpty#dc3d824f = RichText;
textPlain#744694e0 text:string = RichText;
textBold#6724abc4 text:RichText = RichText;
textItalic#d912a59c text:RichText = RichText;
textUnderline#c12622c4 text:RichText = RichText;
textStrike#9bf8bb95 text:RichText = RichText;
textFixed#6c3f19b9 text:RichText = RichText;
textUrl#3c2884c1 text:RichText url:string webpage_id:long = RichText;
textEmail#de5a0dd6 text:RichText email:string = RichText;
textConcat#7e6260d7 texts:Vector<RichText> = RichText;
pageBlockUnsupported#13567e8a = PageBlock;
pageBlockTitle#70abc3fd text:RichText = PageBlock;
pageBlockSubtitle#8ffa9a1f text:RichText = PageBlock;
pageBlockAuthorDate#baafe5e0 author:RichText published_date:int = PageBlock;
pageBlockHeader#bfd064ec text:RichText = PageBlock;
pageBlockSubheader#f12bb6e1 text:RichText = PageBlock;
pageBlockParagraph#467a0766 text:RichText = PageBlock;
pageBlockPreformatted#c070d93e text:RichText language:string = PageBlock;
pageBlockFooter#48870999 text:RichText = PageBlock;
pageBlockDivider#db20b188 = PageBlock;
pageBlockAnchor#ce0d37b0 name:string = PageBlock;
pageBlockList#3a58c7f4 ordered:Bool items:Vector<RichText> = PageBlock;
pageBlockBlockquote#263d7c26 text:RichText caption:RichText = PageBlock;
pageBlockPullquote#4f4456d3 text:RichText caption:RichText = PageBlock;
pageBlockPhoto#e9c69982 photo_id:long caption:RichText = PageBlock;
pageBlockVideo#d9d71866 flags:# autoplay:flags.0?true loop:flags.1?true video_id:long caption:RichText = PageBlock;
pageBlockCover#39f23300 cover:PageBlock = PageBlock;
pageBlockEmbed#cde200d1 flags:# full_width:flags.0?true allow_scrolling:flags.3?true url:flags.1?string html:flags.2?string poster_photo_id:flags.4?long w:int h:int caption:RichText = PageBlock;
pageBlockEmbedPost#292c7be9 url:string webpage_id:long author_photo_id:long author:string date:int blocks:Vector<PageBlock> caption:RichText = PageBlock;
pageBlockCollage#8b31c4f items:Vector<PageBlock> caption:RichText = PageBlock;
pageBlockSlideshow#130c8963 items:Vector<PageBlock> caption:RichText = PageBlock;
pagePart#8dee6c44 blocks:Vector<PageBlock> photos:Vector<Photo> videos:Vector<Document> = Page;
pageFull#d7a19d69 blocks:Vector<PageBlock> photos:Vector<Photo> videos:Vector<Document> = Page;
inputPhoneCall#1e36fded id:long access_hash:long = InputPhoneCall;
phoneCallEmpty#5366c915 id:long = PhoneCall;
phoneCallWaiting#1b8f4ad1 flags:# id:long access_hash:long date:int admin_id:int participant_id:int protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall;
phoneCallRequested#6c448ae8 id:long access_hash:long date:int admin_id:int participant_id:int g_a:bytes protocol:PhoneCallProtocol = PhoneCall;
phoneCall#ffe6ab67 id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connection:PhoneConnection alternative_connections:Vector<PhoneConnection> start_date:int = PhoneCall;
phoneCallDiscarded#50ca4de1 flags:# id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall;
phoneConnection#9d4c17c0 id:long ip:string ipv6:string port:int peer_tag:bytes = PhoneConnection;
phoneCallProtocol#a2bb35cb flags:# udp_p2p:flags.0?true udp_reflector:flags.1?true min_layer:int max_layer:int = PhoneCallProtocol;
phone.phoneCall#ec82e140 phone_call:PhoneCall users:Vector<User> = phone.PhoneCall;
phoneCallDiscardReasonMissed#85e42301 = PhoneCallDiscardReason;
phoneCallDiscardReasonDisconnect#e095c1a0 = PhoneCallDiscardReason;
phoneCallDiscardReasonHangup#57adc690 = PhoneCallDiscardReason;
phoneCallDiscardReasonBusy#faf7e8c9 = PhoneCallDiscardReason;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -809,7 +870,7 @@ contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.
contacts.resetTopPeerRating#1ae373ac category:TopPeerCategory peer:InputPeer = Bool;
messages.getMessages#4222fa74 id:Vector<int> = messages.Messages;
messages.getDialogs#6b47f94d offset_date:int offset_id:int offset_peer:InputPeer limit:int = messages.Dialogs;
messages.getDialogs#191ba9c5 flags:# exclude_pinned:flags.0?true offset_date:int offset_id:int offset_peer:InputPeer limit:int = messages.Dialogs;
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;
@ -880,12 +941,16 @@ messages.clearRecentStickers#8999602d flags:# attached:flags.0?true = Bool;
messages.getArchivedStickers#57f17692 flags:# masks:flags.0?true offset_id:long limit:int = messages.ArchivedStickers;
messages.getMaskStickers#65b8c79f hash:int = messages.AllStickers;
messages.getAttachedStickers#cc5b67cc media:InputStickeredMedia = Vector<StickerSetCovered>;
messages.setGameScore#8ef8ecc0 flags:# edit_message:flags.0?true peer:InputPeer id:int user_id:InputUser score:int = Updates;
messages.setInlineGameScore#15ad9f64 flags:# edit_message:flags.0?true id:InputBotInlineMessageID user_id:InputUser score:int = Bool;
messages.setGameScore#8ef8ecc0 flags:# edit_message:flags.0?true force:flags.1?true peer:InputPeer id:int user_id:InputUser score:int = Updates;
messages.setInlineGameScore#15ad9f64 flags:# edit_message:flags.0?true force:flags.1?true id:InputBotInlineMessageID user_id:InputUser score:int = Bool;
messages.getGameHighScores#e822649d peer:InputPeer id:int user_id:InputUser = messages.HighScores;
messages.getInlineGameHighScores#f635e1b id:InputBotInlineMessageID user_id:InputUser = messages.HighScores;
messages.getCommonChats#d0a48c4 user_id:InputUser max_id:int limit:int = messages.Chats;
messages.getAllChats#eba80ff0 except_ids:Vector<int> = messages.Chats;
messages.getWebPage#32ca8f91 url:string hash:int = WebPage;
messages.toggleDialogPin#3289be6a flags:# pinned:flags.0?true peer:InputPeer = Bool;
messages.reorderPinnedDialogs#959ff644 flags:# force:flags.0?true order:Vector<InputPeer> = Bool;
messages.getPinnedDialogs#e254d64e = messages.PeerDialogs;
updates.getState#edd4882a = updates.State;
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
@ -938,4 +1003,9 @@ channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
channels.updatePinnedMessage#a72ded52 flags:# silent:flags.0?true channel:InputChannel id:int = Updates;
channels.getAdminedPublicChannels#8d8d82d7 = messages.Chats;
// LAYER 58
phone.requestCall#a41aa5e4 user_id:InputUser random_id:int g_a:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
phone.acceptCall#220f0b20 peer:InputPhoneCall g_b:bytes key_fingerprint:long protocol:PhoneCallProtocol = phone.PhoneCall;
phone.discardCall#5dfbcddc peer:InputPhoneCall duration:int reason:PhoneCallDiscardReason connection_id:long = Bool;
phone.receivedCall#17d54f61 peer:InputPhoneCall = Bool;
// LAYER 61

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -42,11 +42,12 @@ struct PeerUpdate {
NotificationsEnabled = 0x00000010U,
SharedMediaChanged = 0x00000020U,
MigrationChanged = 0x00000040U,
PinnedChanged = 0x00000080U,
// For chats and channels
InviteLinkChanged = 0x00000020U,
MembersChanged = 0x00000040U,
AdminsChanged = 0x00000080U,
InviteLinkChanged = 0x00000100U,
MembersChanged = 0x00000200U,
AdminsChanged = 0x00000400U,
// For users
UserCanShareContact = 0x00010000U,

View File

@ -265,9 +265,6 @@ void CoverWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
if (update.flags & Notify::PeerUpdate::Flag::NameChanged) {
refreshNameText();
}
//if (update.flags & UpdateFlag::UserOnlineChanged) { // TODO
// refreshStatusText();
//}
}
void CoverWidget::refreshNameText() {