diff --git a/QTCREATOR.md b/QTCREATOR.md index c4d05c691..6555b05db 100644 --- a/QTCREATOR.md +++ b/QTCREATOR.md @@ -119,7 +119,6 @@ building (**make** command) will take really long time. * Tools > Options > Build & Run > Qt Versions tab > Add > File System /usr/local/Qt-5.5.0/bin/qmake > **Qt 5.5.0 (Qt-5.5.0)** > Apply * Tools > Options > Build & Run > Kits tab > Desktop (default) > change **Qt version** to **Qt 5.5.0 (Qt-5.5.0)** > Apply * Open MetaStyle.pro, configure project with paths **/home/user/TBuild/tdesktop/Linux/DebugIntermediateStyle** and **/home/user/TBuild/tdesktop/Linux/ReleaseIntermediateStyle** and build for Debug -* Open MetaEmoji.pro, configure project with paths **/home/user/TBuild/tdesktop/Linux/DebugIntermediateEmoji** and **/home/user/TBuild/tdesktop/Linux/ReleaseIntermediateEmoji** and build for Debug * Open MetaLang.pro, configure project with paths **/home/user/TBuild/tdesktop/Linux/DebugIntermediateLang** and **/home/user/TBuild/tdesktop/Linux/ReleaseIntermediateLang** and build for Debug * Open Telegram.pro, configure project with paths **/home/user/TBuild/tdesktop/Linux/DebugIntermediate** and **/home/user/TBuild/tdesktop/Linux/ReleaseIntermediate** and build for Debug, if GeneratedFiles are not found click **Run qmake** from **Build** menu and try again * Open Updater.pro, configure project with paths **/home/user/TBuild/tdesktop/Linux/DebugIntermediateUpdater** and **/home/user/TBuild/tdesktop/Linux/ReleaseIntermediateUpdater** and build for Debug diff --git a/Telegram/Resources/lang.strings b/Telegram/Resources/lang.strings index 23fdd7453..ba22a982f 100644 --- a/Telegram/Resources/lang.strings +++ b/Telegram/Resources/lang.strings @@ -93,6 +93,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_chat_status_members" = "{count:no members|# member|# members}"; "lng_chat_status_members_online" = "{count:_not_used_|# member|# members}, {count_online:_not_used_|# online|# online}"; +"lng_channel_status" = "channel"; + "lng_server_error" = "Internal server error."; "lng_flood_error" = "Too many tries. Please try again later."; "lng_deleted" = "Unknown"; @@ -424,6 +426,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_action_changed_photo" = "{from} changed group photo"; "lng_action_changed_title" = "{from} changed group name to «{title}»"; "lng_action_created_chat" = "{from} created group «{title}»"; +"lng_action_created_channel" = "Channel «{title}» created"; "lng_group_invite_bad_link" = "This invite link is broken\nor has expired."; "lng_group_invite_want_join" = "Do you want to join the group «{title}»?"; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 172ad12e8..93dd7abe8 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -103,17 +103,26 @@ void ApiWrap::resolveReplyTo() { void ApiWrap::gotReplyTo(const MTPmessages_Messages &msgs, mtpRequestId req) { switch (msgs.type()) { - case mtpc_messages_messages: - App::feedUsers(msgs.c_messages_messages().vusers); - App::feedChats(msgs.c_messages_messages().vchats); - App::feedMsgs(msgs.c_messages_messages().vmessages, -1); - break; + case mtpc_messages_messages: { + const MTPDmessages_messages &d(msgs.c_messages_messages()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + App::feedMsgs(d.vmessages, -1); + } break; - case mtpc_messages_messagesSlice: - App::feedUsers(msgs.c_messages_messagesSlice().vusers); - App::feedChats(msgs.c_messages_messagesSlice().vchats); - App::feedMsgs(msgs.c_messages_messagesSlice().vmessages, -1); - break; + case mtpc_messages_messagesSlice: { + const MTPDmessages_messagesSlice &d(msgs.c_messages_messagesSlice()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + App::feedMsgs(d.vmessages, -1); + } break; + + case mtpc_messages_channelMessages: { + const MTPDmessages_channelMessages &d(msgs.c_messages_channelMessages()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + App::feedMsgs(d.vmessages, -1); + } break; } for (ReplyToRequests::iterator i = _replyToRequests.begin(); i != _replyToRequests.cend();) { if (i.value().req == req) { @@ -497,32 +506,42 @@ void ApiWrap::resolveWebPages() { void ApiWrap::gotWebPages(const MTPmessages_Messages &msgs, mtpRequestId req) { const QVector *v = 0; switch (msgs.type()) { - case mtpc_messages_messages: - App::feedUsers(msgs.c_messages_messages().vusers); - App::feedChats(msgs.c_messages_messages().vchats); - v = &msgs.c_messages_messages().vmessages.c_vector().v; - break; + case mtpc_messages_messages: { + const MTPDmessages_messages &d(msgs.c_messages_messages()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + v = &d.vmessages.c_vector().v; + } break; - case mtpc_messages_messagesSlice: - App::feedUsers(msgs.c_messages_messagesSlice().vusers); - App::feedChats(msgs.c_messages_messagesSlice().vchats); - v = &msgs.c_messages_messagesSlice().vmessages.c_vector().v; - break; + case mtpc_messages_messagesSlice: { + const MTPDmessages_messagesSlice &d(msgs.c_messages_messagesSlice()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + v = &d.vmessages.c_vector().v; + } break; + + case mtpc_messages_channelMessages: { + const MTPDmessages_channelMessages &d(msgs.c_messages_channelMessages()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + v = &d.vmessages.c_vector().v; + } break; } - QMap msgsIds; // copied from feedMsgs + if (!v) return; + QMap msgsIds; // copied from feedMsgs for (int32 i = 0, l = v->size(); i < l; ++i) { const MTPMessage &msg(v->at(i)); switch (msg.type()) { - case mtpc_message: msgsIds.insert(msg.c_message().vid.v, i); break; - case mtpc_messageEmpty: msgsIds.insert(msg.c_messageEmpty().vid.v, i); break; - case mtpc_messageService: msgsIds.insert(msg.c_messageService().vid.v, i); break; + case mtpc_message: msgsIds.insert((uint64(uint32(msg.c_message().vid.v)) << 32) | uint64(i), i); break; + case mtpc_messageEmpty: msgsIds.insert((uint64(uint32(msg.c_messageEmpty().vid.v)) << 32) | uint64(i), i); break; + case mtpc_messageService: msgsIds.insert((uint64(uint32(msg.c_messageService().vid.v)) << 32) | uint64(i), i); break; } } MainWidget *m = App::main(); - for (QMap::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) { - HistoryItem *item = App::histories().addToBack(v->at(*i), -1); + for (QMap::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) { + HistoryItem *item = App::histories().addToBack(v->at(i.value()), -1); if (item) { item->initDimensions(); if (m) m->itemResized(item); diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 65feace60..035126b7c 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -521,6 +521,8 @@ namespace App { cdata->access = d.vaccess_hash.v; cdata->setPhoto(d.vphoto); cdata->date = d.vdate.v; + cdata->adminned = (d.vflags.v & MTPDchannel_flag_is_admin); + cdata->left = false; cdata->forbidden = false; if (cdata->version < d.vversion.v) { @@ -720,23 +722,23 @@ namespace App { void feedMsgs(const MTPVector &msgs, int msgsState) { const QVector &v(msgs.c_vector().v); - QMap msgsIds; + QMap msgsIds; for (int32 i = 0, l = v.size(); i < l; ++i) { const MTPMessage &msg(v.at(i)); switch (msg.type()) { case mtpc_message: { const MTPDmessage &d(msg.c_message()); - msgsIds.insert(d.vid.v, i); + msgsIds.insert((uint64(uint32(d.vid.v)) << 32) | uint64(i), i); if (msgsState == 1) { // new message, index my forwarded messages to links overview checkEntitiesUpdate(d); } } break; - case mtpc_messageEmpty: msgsIds.insert(msg.c_messageEmpty().vid.v, i); break; - case mtpc_messageService: msgsIds.insert(msg.c_messageService().vid.v, i); break; + case mtpc_messageEmpty: msgsIds.insert((uint64(uint32(msg.c_messageEmpty().vid.v)) << 32) | uint64(i), i); break; + case mtpc_messageService: msgsIds.insert((uint64(uint32(msg.c_messageService().vid.v)) << 32) | uint64(i), i); break; } } - for (QMap::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) { - histories().addToBack(v.at(*i), msgsState); + for (QMap::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) { + histories().addToBack(v.at(i.value()), msgsState); } } @@ -1570,7 +1572,7 @@ namespace App { } QString peerName(const PeerData *peer, bool forDialogs) { - return peer ? (forDialogs ? peer->nameOrPhone : peer->name) : lang(lng_deleted); + return peer ? ((forDialogs && peer->isUser() && !peer->asUser()->nameOrPhone.isEmpty()) ? peer->asUser()->nameOrPhone : peer->name) : lang(lng_deleted); } Histories &histories() { @@ -1704,7 +1706,9 @@ namespace App { } for (ChannelMsgsData::const_iterator j = channelMsgsData.cbegin(), end = channelMsgsData.cend(); j != end; ++j) { for (MsgsData::const_iterator i = j->cbegin(), e = j->cend(); i != e; ++i) { - toDelete.push_back(*i); + if ((*i)->detached()) { + toDelete.push_back(*i); + } } } msgsData.clear(); diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index d82ca6020..ca63885aa 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -267,7 +267,7 @@ void DialogsListWidget::peopleResultPaint(UserData *user, QPainter &p, int32 w, } p.setPen((act ? st::dlgActiveColor : st::dlgNameColor)->p); - history->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); + user->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); } void DialogsListWidget::searchInPeerPaint(QPainter &p, int32 w) const { @@ -292,7 +292,7 @@ void DialogsListWidget::searchInPeerPaint(QPainter &p, int32 w) const { p.drawText(tr.left(), tr.top() + st::dlgHistFont->ascent, st::dlgHistFont->m.elidedText(lang(lng_dlg_search_chat), Qt::ElideRight, tr.width())); p.setPen(st::dlgNameColor->p); - App::history(_searchInPeer->id)->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); + _searchInPeer->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); } void DialogsListWidget::activate() { @@ -414,8 +414,6 @@ void DialogsListWidget::onDialogRowReplaced(DialogRow *oldRow, DialogRow *newRow } void DialogsListWidget::createDialogAtTop(History *history, int32 unreadCount) { - history->updateNameText(); - History::DialogLinks links = dialogs.addToEnd(history); int32 movedFrom = links[0]->pos * st::dlgHeight; dialogs.bringToTop(links); @@ -761,8 +759,9 @@ void DialogsListWidget::itemRemoved(HistoryItem *item) { void DialogsListWidget::dialogsReceived(const QVector &added) { for (QVector::const_iterator i = added.cbegin(), e = added.cend(); i != e; ++i) { - if (i->type() == mtpc_dialog) { - addDialog(i->c_dialog()); + switch (i->type()) { + case mtpc_dialog: addDialog(i->c_dialog()); break; + case mtpc_dialogChannel: addDialogChannel(i->c_dialogChannel()); break; } } if (App::wnd()) App::wnd()->updateCounter(); @@ -959,6 +958,24 @@ void DialogsListWidget::addDialog(const MTPDdialog &dialog) { App::main()->applyNotifySetting(MTP_notifyPeer(dialog.vpeer), dialog.vnotify_settings, history); } +void DialogsListWidget::addDialogChannel(const MTPDdialogChannel &dialogChannel) { + History *history = App::history(peerFromMTP(dialogChannel.vpeer), dialogChannel.vunread_important_count.v, dialogChannel.vread_inbox_max_id.v); + if (history->lastMsg) { + SavedPeersByTime &saved(cRefSavedPeersByTime()); + while (!saved.isEmpty() && history->lastMsg->date < saved.lastKey()) { + History *history = App::history(saved.last()->id); + history->dialogs = dialogs.addToEnd(history); + contactsNoDialogs.del(history->peer); + saved.remove(saved.lastKey(), saved.last()); + } + } + History::DialogLinks links = dialogs.addToEnd(history); + history->dialogs = links; + contactsNoDialogs.del(history->peer); + + App::main()->applyNotifySetting(MTP_notifyPeer(dialogChannel.vpeer), dialogChannel.vnotify_settings, history); +} + void DialogsListWidget::selectSkip(int32 direction) { if (_state == DefaultState) { if (!sel) { @@ -1585,13 +1602,27 @@ void DialogsWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) { void DialogsWidget::unreadCountsReceived(const QVector &dialogs) { for (QVector::const_iterator i = dialogs.cbegin(), e = dialogs.cend(); i != e; ++i) { - const MTPDdialog &d(i->c_dialog()); - Histories::iterator j = App::histories().find(peerFromMTP(d.vpeer)); - if (j != App::histories().end()) { - App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, j.value()); - if (d.vunread_count.v >= j.value()->unreadCount) { - j.value()->setUnreadCount(d.vunread_count.v, false); + switch (i->type()) { + case mtpc_dialog: { + const MTPDdialog &d(i->c_dialog()); + Histories::iterator j = App::histories().find(peerFromMTP(d.vpeer)); + if (j != App::histories().end()) { + App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, j.value()); + if (d.vunread_count.v >= j.value()->unreadCount) { + j.value()->setUnreadCount(d.vunread_count.v, false); + } } + } break; + case mtpc_dialogChannel: { + const MTPDdialogChannel &d(i->c_dialogChannel()); + Histories::iterator j = App::histories().find(peerFromMTP(d.vpeer)); + if (j != App::histories().end()) { + App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, j.value()); + if (d.vunread_important_count.v >= j.value()->unreadCount) { + j.value()->setUnreadCount(d.vunread_important_count.v, false); + } + } + } break; } } if (App::wnd()) App::wnd()->updateCounter(); @@ -1760,7 +1791,7 @@ void DialogsWidget::loadDialogs() { } int32 loadCount = _dialogsOffset ? DialogsPerPage : DialogsFirstLoad; - _dialogsRequest = MTP::send(MTPmessages_GetDialogs(MTP_int(_dialogsOffset), MTP_int(loadCount)), rpcDone(&DialogsWidget::dialogsReceived), rpcFail(&DialogsWidget::dialogsFailed), _channelDialogsRequest ? 0 : 5); + _dialogsRequest = MTP::send(MTPmessages_GetDialogs(MTP_int(_dialogsOffset), MTP_int(loadCount)), rpcDone(&DialogsWidget::dialogsReceived), rpcFail(&DialogsWidget::dialogsFailed), 0, _channelDialogsRequest ? 0 : 5); if (!_channelDialogsRequest) { _channelDialogsRequest = MTP::send(MTPmessages_GetChannelDialogs(MTP_int(0), MTP_int(DialogsPerPage)), rpcDone(&DialogsWidget::dialogsReceived), rpcFail(&DialogsWidget::dialogsFailed)); } @@ -1792,9 +1823,10 @@ void DialogsWidget::searchReceived(bool fromStart, const MTPmessages_Messages &r if (_searchRequest == req) { switch (result.type()) { case mtpc_messages_messages: { - App::feedUsers(result.c_messages_messages().vusers); - App::feedChats(result.c_messages_messages().vchats); - const QVector &msgs(result.c_messages_messages().vmessages.c_vector().v); + const MTPDmessages_messages &d(result.c_messages_messages()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + const QVector &msgs(d.vmessages.c_vector().v); list.searchReceived(msgs, fromStart, msgs.size()); if (msgs.isEmpty()) { _searchFull = true; @@ -1802,10 +1834,22 @@ void DialogsWidget::searchReceived(bool fromStart, const MTPmessages_Messages &r } break; case mtpc_messages_messagesSlice: { - App::feedUsers(result.c_messages_messagesSlice().vusers); - App::feedChats(result.c_messages_messagesSlice().vchats); - const QVector &msgs(result.c_messages_messagesSlice().vmessages.c_vector().v); - list.searchReceived(msgs, fromStart, result.c_messages_messagesSlice().vcount.v); + const MTPDmessages_messagesSlice &d(result.c_messages_messagesSlice()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + const QVector &msgs(d.vmessages.c_vector().v); + list.searchReceived(msgs, fromStart, d.vcount.v); + if (msgs.isEmpty()) { + _searchFull = true; + } + } break; + + case mtpc_messages_channelMessages: { + const MTPDmessages_channelMessages &d(result.c_messages_channelMessages()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + const QVector &msgs(d.vmessages.c_vector().v); + list.searchReceived(msgs, fromStart, d.vcount.v); if (msgs.isEmpty()) { _searchFull = true; } diff --git a/Telegram/SourceFiles/dialogswidget.h b/Telegram/SourceFiles/dialogswidget.h index de68e75d3..ddff8ef42 100644 --- a/Telegram/SourceFiles/dialogswidget.h +++ b/Telegram/SourceFiles/dialogswidget.h @@ -128,6 +128,7 @@ signals: private: void addDialog(const MTPDdialog &dialog); + void addDialogChannel(const MTPDdialogChannel &dialogChannel); void clearSearchResults(bool clearPeople = true); DialogsIndexed dialogs; diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index aec3a786a..514ab3084 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -114,7 +114,7 @@ namespace { } } -const TextParseOptions &itemTextParseOptions(History *h, UserData *f) { +const TextParseOptions &itemTextParseOptions(History *h, PeerData *f) { if ((h->peer->isUser() && h->peer->asUser()->botInfo) || (f->isUser() && f->asUser()->botInfo) || (h->peer->isChat() && h->peer->asChat()->botStatus >= 0) || (h->peer->isChannel() && h->peer->asChannel()->botStatus >= 0)) { return _historyBotOptions; } @@ -236,7 +236,7 @@ void DialogRow::paint(QPainter &p, int32 w, bool act, bool sel) const { } p.setPen((act ? st::dlgActiveColor : st::dlgNameColor)->p); - history->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); + history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); } void FakeDialogRow::paint(QPainter &p, int32 w, bool act, bool sel) const { @@ -297,7 +297,7 @@ void FakeDialogRow::paint(QPainter &p, int32 w, bool act, bool sel) const { _item->drawInDialog(p, QRect(nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgSep, lastWidth, st::dlgFont->height), act, _cacheFor, _cache); p.setPen((act ? st::dlgActiveColor : st::dlgNameColor)->p); - history->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); + history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); } History::History(const PeerId &peerId) : width(0), height(0) @@ -337,10 +337,6 @@ void History::clearLastKeyboard() { lastKeyboardFrom = 0; } -void History::updateNameText() { - nameText.setText(st::msgNameFont, peer->nameOrPhone.isEmpty() ? peer->name : peer->nameOrPhone, _textNameOptions); -} - bool History::updateTyping(uint64 ms, uint32 dots, bool force) { if (!ms) ms = getms(true); bool changed = force; @@ -593,19 +589,26 @@ void Histories::remove(const PeerId &peer) { } +inline bool isImportantChannelMessage(int32 flags) { + return (flags & MTPDmessage_flag_out) || (flags & MTPDmessage_flag_notify_by_from) || !(flags & MTPDmessage::flag_from_id); +} + HistoryItem *Histories::addToBack(const MTPmessage &msg, int msgState) { PeerId from_id = 0, to_id = 0; + int32 flags = 0; switch (msg.type()) { case mtpc_message: - from_id = peerFromUser(msg.c_message().vfrom_id); + from_id = msg.c_message().has_from_id() ? peerFromUser(msg.c_message().vfrom_id) : 0; to_id = peerFromMTP(msg.c_message().vto_id); + flags = msg.c_message().vflags.v; break; case mtpc_messageService: - from_id = peerFromUser(msg.c_messageService().vfrom_id); + from_id = msg.c_messageService().has_from_id() ? peerFromUser(msg.c_messageService().vfrom_id) : 0; to_id = peerFromMTP(msg.c_messageService().vto_id); + flags = msg.c_messageService().vflags.v; break; } - PeerId peer = (peerToUser(to_id) == MTP::authedId()) ? from_id : to_id; + PeerId peer = (from_id && peerToUser(to_id) == MTP::authedId()) ? from_id : to_id; if (!peer) return 0; @@ -613,7 +616,7 @@ HistoryItem *Histories::addToBack(const MTPmessage &msg, int msgState) { if (h == end()) { h = insert(peer, new History(peer)); } - if (msgState < 0) { + if (msgState < 0 || (peerIsChannel(peer) && !isImportantChannelMessage(flags))) { return h.value()->addToHistory(msg); } if (!h.value()->loadedAtBottom()) { @@ -963,14 +966,14 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem * addToOverview(adding, OverviewLinks); } if (adding->from()->id) { - if (peer->isChat()) { + if (peer->isChat() && adding->from()->isUser()) { QList *lastAuthors = &(peer->asChat()->lastAuthors); - int prev = lastAuthors->indexOf(adding->from()); + int prev = lastAuthors->indexOf(adding->from()->asUser()); if (prev > 0) { lastAuthors->removeAt(prev); } if (prev) { - lastAuthors->push_front(adding->from()); + lastAuthors->push_front(adding->from()->asUser()); } } if (adding->hasReplyMarkup()) { @@ -983,7 +986,7 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem * if (lastKeyboardFrom == adding->from()->id || (!lastKeyboardInited && !peer->isChat() && !adding->out())) { clearLastKeyboard(); } - } else if (peer->isChat() && (peer->asChat()->count < 1 || !peer->asChat()->participants.isEmpty()) && !peer->asChat()->participants.contains(adding->from())) { + } else if (peer->isChat() && adding->from()->isUser() && (peer->asChat()->count < 1 || !peer->asChat()->participants.isEmpty()) && !peer->asChat()->participants.contains(adding->from()->asUser())) { clearLastKeyboard(); } else { lastKeyboardInited = true; @@ -1020,9 +1023,9 @@ void History::unregTyping(UserData *from) { void History::newItemAdded(HistoryItem *item) { App::checkImageCacheSize(); - if (item->from()) { - unregTyping(item->from()); - item->from()->madeAction(); + if (item->from() && item->from()->isUser()) { + unregTyping(item->from()->asUser()); + item->from()->asUser()->madeAction(); } if (item->out()) { if (unreadBar) unreadBar->destroy(); @@ -1121,8 +1124,8 @@ void History::addToFront(const QVector &slice) { } if (item->from()->id) { if (lastAuthors) { // chats - if (!lastAuthors->contains(item->from())) { - lastAuthors->push_back(item->from()); + if (item->from()->isUser() && !lastAuthors->contains(item->from()->asUser())) { + lastAuthors->push_back(item->from()->asUser()); } if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) { // chats with bots int32 markupFlags = App::replyMarkup(channelId(), item->id).flags; @@ -1133,7 +1136,7 @@ void History::addToFront(const QVector &slice) { } if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO)) { if (!lastKeyboardInited) { - if (wasKeyboardHide || ((peer->asChat()->count < 1 || !peer->asChat()->participants.isEmpty()) && !peer->asChat()->participants.contains(item->from()))) { + if (wasKeyboardHide || ((peer->asChat()->count < 1 || !peer->asChat()->participants.isEmpty()) && item->from()->isUser() && !peer->asChat()->participants.contains(item->from()->asUser()))) { clearLastKeyboard(); } else { lastKeyboardInited = true; @@ -1755,7 +1758,7 @@ ItemAnimations &itemAnimations() { HistoryItem::HistoryItem(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime msgDate, int32 from) : y(0) , id(msgId) , date(msgDate) -, _from(App::user(from)) +, _from(from ? App::user(from) : history->peer) , _fromVersion(_from->nameVersion) , _history(history) , _block(block) @@ -5764,7 +5767,7 @@ void HistoryMessage::drawInDialog(QPainter &p, const QRect &r, bool act, const H if (!_history->peer->isUser() || out()) { // CHANNELS_UI TextCustomTagsMap custom; custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink())); - msg = lng_message_with_from(lt_from, textRichPrepare((_from == App::self()) ? lang(lng_from_you) : _from->firstName), lt_message, textRichPrepare(msg)); + msg = lng_message_with_from(lt_from, textRichPrepare((_from == App::self()) ? lang(lng_from_you) : _from->shortName()), lt_message, textRichPrepare(msg)); cache.setRichText(st::dlgHistFont, msg, _textDlgOptions, custom); } else { cache.setText(st::dlgHistFont, msg, _textDlgOptions); @@ -6337,6 +6340,11 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) { text = lng_action_created_chat(lt_from, from, lt_title, textClean(qs(d.vtitle))); } break; + case mtpc_messageActionChannelCreate: { + const MTPDmessageActionChannelCreate &d(action.c_messageActionChannelCreate()); + text = lng_action_created_channel(lt_title, textClean(qs(d.vtitle))); + } break; + case mtpc_messageActionChatDeletePhoto: { text = lng_action_removed_photo(lt_from, from); } break; @@ -6379,7 +6387,7 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) { } HistoryServiceMsg::HistoryServiceMsg(History *history, HistoryBlock *block, const MTPDmessageService &msg) : - HistoryItem(history, block, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.vfrom_id.v) + HistoryItem(history, block, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0) , _text(st::msgMinWidth) , _media(0) { diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h index a8cf80b86..f5c596544 100644 --- a/Telegram/SourceFiles/history.h +++ b/Telegram/SourceFiles/history.h @@ -286,10 +286,6 @@ struct History : public QList { mtpRequestId sendRequestId; - // for dialog drawing - Text nameText; - void updateNameText(); - mutable const HistoryItem *textCachedFor; // cache mutable Text lastItemTextCache; @@ -693,7 +689,7 @@ public: const History *history() const { return _history; } - UserData *from() const { + PeerData *from() const { return _from; } HistoryBlock *block() { @@ -837,7 +833,7 @@ public: protected: - UserData *_from; + PeerData *_from; mutable int32 _fromVersion; History *_history; HistoryBlock *_block; @@ -1372,7 +1368,7 @@ public: virtual QDateTime dateForwarded() const { // dynamic_cast optimize return date; } - virtual UserData *fromForwarded() const { // dynamic_cast optimize + virtual PeerData *fromForwarded() const { // dynamic_cast optimize return from(); } @@ -1419,7 +1415,7 @@ public: QDateTime dateForwarded() const { return fwdDate; } - UserData *fromForwarded() const { + PeerData *fromForwarded() const { return fwdFrom; } QString selectedText(uint32 selection) const; @@ -1434,7 +1430,7 @@ public: protected: QDateTime fwdDate; - UserData *fwdFrom; + PeerData *fwdFrom; mutable Text fwdFromName; mutable int32 fwdFromVersion; int32 fromWidth; @@ -1468,7 +1464,7 @@ public: void getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const QRect &r) const; void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const; - UserData *replyTo() const { + PeerData *replyTo() const { return replyToMsg ? replyToMsg->from() : 0; } QString selectedText(uint32 selection) const; @@ -1593,4 +1589,4 @@ protected: bool freezed; }; -const TextParseOptions &itemTextParseOptions(History *h, UserData *f); +const TextParseOptions &itemTextParseOptions(History *h, PeerData *f); diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 009011320..bfeae7139 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -3139,7 +3139,7 @@ void HistoryWidget::messagesReceived(const MTPmessages_Messages &messages, mtpRe } int32 count = 0; - const QVector *histList = 0; + const QVector emptyList, *histList = &emptyList; switch (messages.type()) { case mtpc_messages_messages: { const MTPDmessages_messages &data(messages.c_messages_messages()); @@ -3155,6 +3155,13 @@ void HistoryWidget::messagesReceived(const MTPmessages_Messages &messages, mtpRe histList = &data.vmessages.c_vector().v; count = data.vcount.v; } break; + case mtpc_messages_channelMessages: { + const MTPDmessages_channelMessages &data(messages.c_messages_channelMessages()); + App::feedUsers(data.vusers); + App::feedChats(data.vchats); + histList = &data.vmessages.c_vector().v; + count = data.vcount.v; + } break; } if (_preloadRequest == requestId) { @@ -3251,7 +3258,11 @@ void HistoryWidget::firstLoadMessages() { offset = -loadCount / 2; from = _showAtMsgId; } - _firstLoadRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(offset), MTP_int(from), MTP_int(0), MTP_int(loadCount)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed)); + if (_peer->isChannel()) { + _firstLoadRequest = MTP::send(MTPmessages_GetImportantHistory(_peer->input, MTP_int(from), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed)); + } else { + _firstLoadRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(from), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed)); + } } void HistoryWidget::loadMessages() { @@ -3259,7 +3270,11 @@ void HistoryWidget::loadMessages() { MsgId min = _history->minMsgId(); int32 offset = 0, loadCount = min ? MessagesPerPage : MessagesFirstLoad; - _preloadRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(offset), MTP_int(min), MTP_int(0), MTP_int(loadCount)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed)); + if (_peer->isChannel()) { + _preloadRequest = MTP::send(MTPmessages_GetImportantHistory(_peer->input, MTP_int(min), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed)); + } else { + _preloadRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(min), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed)); + } } void HistoryWidget::loadMessagesDown() { @@ -3269,7 +3284,11 @@ void HistoryWidget::loadMessagesDown() { if (!max) return; int32 loadCount = MessagesPerPage, offset = -loadCount - 1; - _preloadDownRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(offset), MTP_int(max + 1), MTP_int(0), MTP_int(loadCount)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed)); + if (_peer->isChannel()) { + _preloadDownRequest = MTP::send(MTPmessages_GetImportantHistory(_peer->input, MTP_int(max + 1), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed)); + } else { + _preloadDownRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(max + 1), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed)); + } } void HistoryWidget::delayedShowAt(MsgId showAtMsgId) { @@ -3288,7 +3307,11 @@ void HistoryWidget::delayedShowAt(MsgId showAtMsgId) { } else if (_delayedShowAtMsgId > 0) { offset = -loadCount / 2; } - _delayedShowAtRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(offset), MTP_int(from), MTP_int(0), MTP_int(loadCount)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed)); + if (_peer->isChannel()) { + _delayedShowAtRequest = MTP::send(MTPmessages_GetImportantHistory(_peer->input, MTP_int(from), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed)); + } else { + _delayedShowAtRequest = MTP::send(MTPmessages_GetHistory(_peer->input, MTP_int(from), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived), rpcFail(&HistoryWidget::messagesFailed)); + } } void HistoryWidget::onListScroll() { @@ -3407,7 +3430,7 @@ void HistoryWidget::onBotStart() { sendBotCommand(qsl("/start"), 0); } else { uint64 randomId = MTP::nonce(); - MTP::send(MTPmessages_StartBot(_peer->asUser()->inputUser, MTP_inputChat(MTP_int(0)), MTP_long(randomId), MTP_string(token)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::addParticipantFail, _peer->asUser())); + MTP::send(MTPmessages_StartBot(_peer->asUser()->inputUser, MTP_inputChatEmpty(), MTP_long(randomId), MTP_string(token)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::addParticipantFail, _peer->asUser())); _peer->asUser()->botInfo->startToken = QString(); if (_keyboard.hasMarkup()) { @@ -3736,8 +3759,9 @@ void HistoryWidget::sendBotCommand(const QString &cmd, MsgId replyTo) { // reply bool lastKeyboardUsed = (_keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId)) && (_keyboard.forMsgId() == FullMsgId(_channel, replyTo)); QString toSend = cmd; - UserData *bot = _peer->isUser() ? _peer->asUser() : (App::hoveredLinkItem() ? (App::hoveredLinkItem()->toHistoryForwarded() ? App::hoveredLinkItem()->toHistoryForwarded()->fromForwarded() : App::hoveredLinkItem()->from()) : 0); - QString username = (bot && bot->botInfo) ? bot->username : QString(); + PeerData *bot = _peer->isUser() ? _peer : (App::hoveredLinkItem() ? (App::hoveredLinkItem()->toHistoryForwarded() ? App::hoveredLinkItem()->toHistoryForwarded()->fromForwarded() : App::hoveredLinkItem()->from()) : 0); + if (!bot->isUser() || !bot->asUser()->botInfo) bot = 0; + QString username = bot ? bot->asUser()->username : QString(); int32 botStatus = _peer->isChat() ? _peer->asChat()->botStatus : (_peer->isChannel() ? _peer->asChannel()->botStatus : -1); if (!replyTo && toSend.indexOf('@') < 2 && !username.isEmpty() && (botStatus == 0 || botStatus == 2)) { toSend += '@' + username; @@ -3759,8 +3783,9 @@ void HistoryWidget::insertBotCommand(const QString &cmd) { if (!_history) return; QString toInsert = cmd; - UserData *bot = _peer->isUser() ? _peer->asUser() : (App::hoveredLinkItem() ? (App::hoveredLinkItem()->toHistoryForwarded() ? App::hoveredLinkItem()->toHistoryForwarded()->fromForwarded() : App::hoveredLinkItem()->from()) : 0); - QString username = (bot && bot->botInfo) ? bot->username : QString(); + PeerData *bot = _peer->isUser() ? _peer : (App::hoveredLinkItem() ? (App::hoveredLinkItem()->toHistoryForwarded() ? App::hoveredLinkItem()->toHistoryForwarded()->fromForwarded() : App::hoveredLinkItem()->from()) : 0); + if (!bot->isUser() || !bot->asUser()->botInfo) bot = 0; + QString username = bot ? bot->asUser()->username : QString(); int32 botStatus = _peer->isChat() ? _peer->asChat()->botStatus : (_peer->isChannel() ? _peer->asChannel()->botStatus : -1); if (toInsert.indexOf('@') < 2 && !username.isEmpty() && (botStatus == 0 || botStatus == 2)) { toInsert += '@' + username; @@ -4050,7 +4075,7 @@ void HistoryWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) } p.setPen(st::dlgNameColor->p); - _history->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); + _history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); if (cWideMode()) { p.setOpacity(st::topBarForwardAlpha + (1 - st::topBarForwardAlpha) * over); @@ -4105,7 +4130,7 @@ void HistoryWidget::updateOnlineDisplay(int32 x, int32 w) { } } } else if (_peer->isChannel()) { - // CHANNELS_UI + text = lang(lng_channel_status); } if (_titlePeerText != text) { _titlePeerText = text; diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index 019d885cb..58272a3cd 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -2775,8 +2775,8 @@ namespace Local { } else if (peer->isChannel()) { ChannelData *channel = peer->asChannel(); - // name + access + date + version + forbidden + left + invitationUrl - result += _stringSize(channel->name) + sizeof(quint64) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + _stringSize(channel->invitationUrl); + // name + access + date + version + adminned + forbidden + left + invitationUrl + result += _stringSize(channel->name) + sizeof(quint64) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + _stringSize(channel->invitationUrl); } return result; } @@ -2796,7 +2796,7 @@ namespace Local { } else if (peer->isChannel()) { ChannelData *channel = peer->asChannel(); - stream << channel->name << quint64(channel->access) << qint32(channel->date) << qint32(channel->version); + stream << channel->name << quint64(channel->access) << qint32(channel->date) << qint32(channel->version) << qint32(channel->adminned ? 1 : 0); stream << qint32(channel->forbidden ? 1 : 0) << qint32(channel->left ? 1 : 0) << channel->invitationUrl; } } @@ -2862,13 +2862,14 @@ namespace Local { QString name, invitationUrl; quint64 access; - qint32 date, version, forbidden, left; - from.stream >> name >> access >> date >> version >> forbidden >> left >> invitationUrl; + qint32 date, version, adminned, forbidden, left; + from.stream >> name >> access >> date >> version >> adminned >> forbidden >> left >> invitationUrl; channel->updateName(name, QString(), QString()); channel->access = access; channel->date = date; channel->version = version; + channel->adminned = (adminned == 1); channel->forbidden = (forbidden == 1); channel->left = (left == 1); channel->invitationUrl = invitationUrl; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 233a59b0d..55fa0d6ba 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -305,7 +305,11 @@ void TopBarWidget::showAll() { _forward.hide(); _mediaType.hide(); } else { - _edit.hide(); + if (p && p->isChannel() && p->asChannel()->adminned) { + _edit.show(); + } else { + _edit.hide(); + } _leaveGroup.hide(); _addContact.hide(); _deleteContact.hide(); @@ -469,8 +473,8 @@ void MainWidget::updateForwardingTexts() { int32 version = 0; QString from, text; if (!_toForward.isEmpty()) { - QMap fromUsersMap; - QVector fromUsers; + QMap fromUsersMap; + QVector fromUsers; fromUsers.reserve(_toForward.size()); for (SelectedItemSet::const_iterator i = _toForward.cbegin(), e = _toForward.cend(); i != e; ++i) { if (!fromUsersMap.contains(i.value()->from())) { @@ -480,11 +484,11 @@ void MainWidget::updateForwardingTexts() { version += i.value()->from()->nameVersion; } if (fromUsers.size() > 2) { - from = lng_forwarding_from(lt_user, fromUsers.at(0)->firstName, lt_count, fromUsers.size() - 1); + from = lng_forwarding_from(lt_user, fromUsers.at(0)->shortName(), lt_count, fromUsers.size() - 1); } else if (fromUsers.size() < 2) { from = fromUsers.at(0)->name; } else { - from = lng_forwarding_from_two(lt_user, fromUsers.at(0)->firstName, lt_second_user, fromUsers.at(1)->firstName); + from = lng_forwarding_from_two(lt_user, fromUsers.at(0)->shortName(), lt_second_user, fromUsers.at(1)->shortName()); } if (_toForward.size() < 2) { @@ -836,21 +840,36 @@ bool MainWidget::kickParticipantFail(ChatData *chat, const RPCError &error) { } void MainWidget::checkPeerHistory(PeerData *peer) { - MTP::send(MTPmessages_GetHistory(peer->input, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(1)), rpcDone(&MainWidget::checkedHistory, peer)); + if (peer->isChannel()) { + MTP::send(MTPmessages_GetImportantHistory(peer->input, MTP_int(0), MTP_int(0), MTP_int(1), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::checkedHistory, peer)); + } else { + MTP::send(MTPmessages_GetHistory(peer->input, MTP_int(0), MTP_int(0), MTP_int(1), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::checkedHistory, peer)); + } } void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &result) { const QVector *v = 0; - if (result.type() == mtpc_messages_messages) { + switch (result.type()) { + case mtpc_messages_messages: { const MTPDmessages_messages &d(result.c_messages_messages()); App::feedUsers(d.vusers); App::feedChats(d.vchats); v = &d.vmessages.c_vector().v; - } else if (result.type() == mtpc_messages_messagesSlice) { + } break; + + case mtpc_messages_messagesSlice: { const MTPDmessages_messagesSlice &d(result.c_messages_messagesSlice()); App::feedUsers(d.vusers); App::feedChats(d.vchats); v = &d.vmessages.c_vector().v; + } break; + + case mtpc_messages_channelMessages: { // CHANNELS_TODO - all mtpc_messages_channelMessages handle! + const MTPDmessages_channelMessages &d(result.c_messages_channelMessages()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + v = &d.vmessages.c_vector().v; + } break; } if (!v) return; @@ -1194,6 +1213,13 @@ void MainWidget::overviewPreloaded(PeerData *peer, const MTPmessages_Messages &r h->_overviewCount[type] = d.vcount.v; } break; + case mtpc_messages_channelMessages: { + const MTPDmessages_channelMessages &d(result.c_messages_channelMessages()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + h->_overviewCount[type] = d.vcount.v; + } break; + default: return; } @@ -1387,6 +1413,14 @@ void MainWidget::photosLoaded(History *h, const MTPmessages_Messages &msgs, mtpR v = &d.vmessages.c_vector().v; } break; + case mtpc_messages_channelMessages: { + const MTPDmessages_channelMessages &d(msgs.c_messages_channelMessages()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + h->_overviewCount[type] = d.vcount.v; + v = &d.vmessages.c_vector().v; + } break; + default: return; } @@ -1809,17 +1843,26 @@ void MainWidget::serviceNotification(const QString &msg, const MTPMessageMedia & void MainWidget::serviceHistoryDone(const MTPmessages_Messages &msgs) { switch (msgs.type()) { - case mtpc_messages_messages: - App::feedUsers(msgs.c_messages_messages().vusers); - App::feedChats(msgs.c_messages_messages().vchats); - App::feedMsgs(msgs.c_messages_messages().vmessages); - break; + case mtpc_messages_messages: { + const MTPDmessages_messages &d(msgs.c_messages_messages()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + App::feedMsgs(d.vmessages); + } break; - case mtpc_messages_messagesSlice: - App::feedUsers(msgs.c_messages_messagesSlice().vusers); - App::feedChats(msgs.c_messages_messagesSlice().vchats); - App::feedMsgs(msgs.c_messages_messagesSlice().vmessages); - break; + case mtpc_messages_messagesSlice: { + const MTPDmessages_messagesSlice &d(msgs.c_messages_messagesSlice()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + App::feedMsgs(d.vmessages); + } break; + + case mtpc_messages_channelMessages: { + const MTPDmessages_channelMessages &d(msgs.c_messages_channelMessages()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + App::feedMsgs(d.vmessages); + } break; } App::wnd()->showDelayedServiceMsgs(); @@ -3474,6 +3517,22 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { } } break; + case mtpc_updateNewChannelMessage: { + const MTPDupdateNewChannelMessage &d(update.c_updateNewChannelMessage()); + //if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) { // CHANNELS_TODO + // _byPtsUpdate.insert(ptsKey(SkippedUpdate), update); + // return; + //} + if (d.vmessage.type() == mtpc_message) { // index forwarded messages to links overview + App::checkEntitiesUpdate(d.vmessage.c_message()); + } + + HistoryItem *item = App::histories().addToBack(d.vmessage); + if (item) { + history.peerMessagesUpdated(item->history()->peer->id); + } + } break; + case mtpc_updateMessageID: { const MTPDupdateMessageID &d(update.c_updateMessageID()); FullMsgId msg = App::histItemByRandom(d.vrandom_id.v); diff --git a/Telegram/SourceFiles/mediaview.h b/Telegram/SourceFiles/mediaview.h index 15d364382..b4e4835e0 100644 --- a/Telegram/SourceFiles/mediaview.h +++ b/Telegram/SourceFiles/mediaview.h @@ -155,7 +155,7 @@ private: PeerData *_peer; UserData *_user; // if user profile photos overview - UserData *_from; + PeerData *_from; Text _fromName; int32 _index; // index in photos or files array, -1 if just photo diff --git a/Telegram/SourceFiles/mtproto/mtpConnection.h b/Telegram/SourceFiles/mtproto/mtpConnection.h index 0ce618f1d..5c537d74b 100644 --- a/Telegram/SourceFiles/mtproto/mtpConnection.h +++ b/Telegram/SourceFiles/mtproto/mtpConnection.h @@ -50,6 +50,12 @@ enum { MTPDstickerSet_flag_disabled = (1 << 1), MTPDstickerSet_flag_official = (1 << 2), MTPDstickerSet_flag_NOT_LOADED = (1 << 31), // client side flag for not yet loaded set + + MTPDchannel_flag_is_admin = (1 << 0), + + MTPupdates_ChannelDifference_flag_final = (1 << 0), + + MTPDchannelMessagesFilter_flag_only_important = (1 << 0), }; static const MTPReplyMarkup MTPnullMarkup = MTP_replyKeyboardMarkup(MTP_int(0), MTP_vector(0)); diff --git a/Telegram/SourceFiles/mtproto/mtpScheme.cpp b/Telegram/SourceFiles/mtproto/mtpScheme.cpp index ff907b1c9..3c3e73b15 100644 --- a/Telegram/SourceFiles/mtproto/mtpScheme.cpp +++ b/Telegram/SourceFiles/mtproto/mtpScheme.cpp @@ -1291,9 +1291,11 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP case 1: to.add(" read_inbox_max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; case 2: to.add(" unread_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; case 3: to.add(" unread_important_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 4: to.add(" chat_photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 5: to.add(" notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 6: to.add(" exported_invite: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 4: to.add(" inviter_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 5: to.add(" invite_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 6: to.add(" chat_photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 7: to.add(" notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 8: to.add(" exported_invite: "); ++stages.back(); types.push_back(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; } break; @@ -2746,6 +2748,20 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP } break; + case mtpc_updateChannelGroup: + if (stage) { + to.add(",\n").addSpaces(lev); + } else { + to.add("{ updateChannelGroup"); + to.add("\n").addSpaces(lev); + } + switch (stage) { + case 0: to.add(" channel_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" group: "); ++stages.back(); types.push_back(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; + } + break; + case mtpc_updateNewChannelMessage: if (stage) { to.add(",\n").addSpaces(lev); @@ -4626,6 +4642,10 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP } break; + case mtpc_channelMessagesFilterCollapsed: + to.add("{ channelMessagesFilterCollapsed }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); + break; + case mtpc_req_pq: if (stage) { to.add(",\n").addSpaces(lev); @@ -5638,10 +5658,11 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP } 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(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 2: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 3: to.add(" min_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 4: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" offset_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 2: to.add(" add_offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 3: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 4: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 5: to.add(" min_id: "); ++stages.back(); types.push_back(mtpc_int); 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; } break; @@ -5675,9 +5696,11 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP } 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); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; - case 2: to.add(" min_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" offset_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 2: to.add(" add_offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; case 3: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 4: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 5: to.add(" min_id: "); ++stages.back(); types.push_back(mtpc_int); 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; } break; @@ -5983,7 +6006,9 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP to.add("\n").addSpaces(lev); } switch (stage) { - case 0: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); 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_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 1: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; + case 2: to.add(" users: "); ++stages.back(); types.push_back(00); 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; } break; diff --git a/Telegram/SourceFiles/mtproto/mtpScheme.h b/Telegram/SourceFiles/mtproto/mtpScheme.h index 6dccac3d1..95fd58c45 100644 --- a/Telegram/SourceFiles/mtproto/mtpScheme.h +++ b/Telegram/SourceFiles/mtproto/mtpScheme.h @@ -137,7 +137,7 @@ enum { mtpc_chatForbidden = 0xfb0ccc41, mtpc_channel = 0x8dbb1461, mtpc_chatFull = 0x2e02a614, - mtpc_channelFull = 0xeb8a0d68, + mtpc_channelFull = 0xa09d2902, mtpc_chatParticipant = 0xc8d7493e, mtpc_chatParticipantsForbidden = 0xfd2bb8a, mtpc_chatParticipants = 0x7841b415, @@ -253,6 +253,7 @@ enum { mtpc_updateWebPage = 0x2cc36971, mtpc_updateReadMessagesContents = 0x68c13933, mtpc_updateChannelTooLong = 0x60946422, + mtpc_updateChannelGroup = 0xc36c1e3c, mtpc_updateNewChannelMessage = 0x62ba04d9, mtpc_updateReadChannelInbox = 0x87b87b7d, mtpc_updateDeleteChannelMessages = 0x11da3046, @@ -405,6 +406,7 @@ enum { mtpc_updates_channelDifference = 0x2064674e, mtpc_channelMessagesFilterEmpty = 0x94d42ee7, mtpc_channelMessagesFilter = 0xcd77d957, + mtpc_channelMessagesFilterCollapsed = 0xfa01232e, mtpc_invokeAfterMsg = 0xcb9f372d, mtpc_invokeAfterMsgs = 0x3dc4b4f0, mtpc_initConnection = 0x69796de9, @@ -466,7 +468,7 @@ enum { mtpc_contacts_resolveUsername = 0xbf0131c, mtpc_messages_getMessages = 0x4222fa74, mtpc_messages_getDialogs = 0x859b3d3c, - mtpc_messages_getHistory = 0xe1ded325, + mtpc_messages_getHistory = 0x8a8ec2da, mtpc_messages_search = 0x7e9f2ab, mtpc_messages_readHistory = 0xb04f2510, mtpc_messages_deleteHistory = 0xf4f8fb61, @@ -507,9 +509,9 @@ enum { mtpc_messages_uninstallStickerSet = 0xf96e55de, mtpc_messages_startBot = 0xf4cc052d, mtpc_messages_getChannelDialogs = 0x92689583, - mtpc_messages_getImportantHistory = 0x25b7f3b2, + mtpc_messages_getImportantHistory = 0x24af43a5, mtpc_messages_readChannelHistory = 0x36a1210e, - mtpc_messages_createChannel = 0xd9bc5fd2, + mtpc_messages_createChannel = 0xe830f8cb, mtpc_messages_deleteChannelMessages = 0x9995a84f, mtpc_updates_getState = 0xedd4882a, mtpc_updates_getDifference = 0xa041495, @@ -861,6 +863,7 @@ class MTPDupdateReadHistoryOutbox; class MTPDupdateWebPage; class MTPDupdateReadMessagesContents; class MTPDupdateChannelTooLong; +class MTPDupdateChannelGroup; class MTPDupdateNewChannelMessage; class MTPDupdateReadChannelInbox; class MTPDupdateDeleteChannelMessages; @@ -3225,7 +3228,7 @@ private: explicit MTPchatFull(MTPDchannelFull *_data); friend MTPchatFull MTP_chatFull(MTPint _id, const MTPChatParticipants &_participants, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite, const MTPVector &_bot_info); - friend MTPchatFull MTP_channelFull(MTPint _id, MTPint _read_inbox_max_id, MTPint _unread_count, MTPint _unread_important_count, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite); + friend MTPchatFull MTP_channelFull(MTPint _id, MTPint _read_inbox_max_id, MTPint _unread_count, MTPint _unread_important_count, MTPint _inviter_id, MTPint _invite_date, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite); mtpTypeId _type; }; @@ -5251,6 +5254,18 @@ public: return *(const MTPDupdateChannelTooLong*)data; } + MTPDupdateChannelGroup &_updateChannelGroup() { + if (!data) throw mtpErrorUninitialized(); + if (_type != mtpc_updateChannelGroup) throw mtpErrorWrongTypeId(_type, mtpc_updateChannelGroup); + split(); + return *(MTPDupdateChannelGroup*)data; + } + const MTPDupdateChannelGroup &c_updateChannelGroup() const { + if (!data) throw mtpErrorUninitialized(); + if (_type != mtpc_updateChannelGroup) throw mtpErrorWrongTypeId(_type, mtpc_updateChannelGroup); + return *(const MTPDupdateChannelGroup*)data; + } + MTPDupdateNewChannelMessage &_updateNewChannelMessage() { if (!data) throw mtpErrorUninitialized(); if (_type != mtpc_updateNewChannelMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateNewChannelMessage); @@ -5325,6 +5340,7 @@ private: explicit MTPupdate(MTPDupdateWebPage *_data); explicit MTPupdate(MTPDupdateReadMessagesContents *_data); explicit MTPupdate(MTPDupdateChannelTooLong *_data); + explicit MTPupdate(MTPDupdateChannelGroup *_data); explicit MTPupdate(MTPDupdateNewChannelMessage *_data); explicit MTPupdate(MTPDupdateReadChannelInbox *_data); explicit MTPupdate(MTPDupdateDeleteChannelMessages *_data); @@ -5358,6 +5374,7 @@ private: friend MTPupdate MTP_updateWebPage(const MTPWebPage &_webpage); friend MTPupdate MTP_updateReadMessagesContents(const MTPVector &_messages, MTPint _pts, MTPint _pts_count); friend MTPupdate MTP_updateChannelTooLong(MTPint _channel_id); + friend MTPupdate MTP_updateChannelGroup(MTPint _channel_id, const MTPMessageGroup &_group); friend MTPupdate MTP_updateNewChannelMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count); friend MTPupdate MTP_updateReadChannelInbox(const MTPPeer &_peer, MTPint _max_id); friend MTPupdate MTP_updateDeleteChannelMessages(const MTPPeer &_peer, const MTPVector &_messages, MTPint _pts, MTPint _pts_count); @@ -8285,6 +8302,7 @@ private: friend MTPchannelMessagesFilter MTP_channelMessagesFilterEmpty(); friend MTPchannelMessagesFilter MTP_channelMessagesFilter(MTPint _flags, const MTPVector &_ranges); + friend MTPchannelMessagesFilter MTP_channelMessagesFilterCollapsed(); mtpTypeId _type; }; @@ -9206,13 +9224,15 @@ class MTPDchannelFull : public mtpDataImpl { public: MTPDchannelFull() { } - MTPDchannelFull(MTPint _id, MTPint _read_inbox_max_id, MTPint _unread_count, MTPint _unread_important_count, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite) : vid(_id), vread_inbox_max_id(_read_inbox_max_id), vunread_count(_unread_count), vunread_important_count(_unread_important_count), vchat_photo(_chat_photo), vnotify_settings(_notify_settings), vexported_invite(_exported_invite) { + MTPDchannelFull(MTPint _id, MTPint _read_inbox_max_id, MTPint _unread_count, MTPint _unread_important_count, MTPint _inviter_id, MTPint _invite_date, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite) : vid(_id), vread_inbox_max_id(_read_inbox_max_id), vunread_count(_unread_count), vunread_important_count(_unread_important_count), vinviter_id(_inviter_id), vinvite_date(_invite_date), vchat_photo(_chat_photo), vnotify_settings(_notify_settings), vexported_invite(_exported_invite) { } MTPint vid; MTPint vread_inbox_max_id; MTPint vunread_count; MTPint vunread_important_count; + MTPint vinviter_id; + MTPint vinvite_date; MTPPhoto vchat_photo; MTPPeerNotifySettings vnotify_settings; MTPExportedChatInvite vexported_invite; @@ -10327,6 +10347,17 @@ public: MTPint vchannel_id; }; +class MTPDupdateChannelGroup : public mtpDataImpl { +public: + MTPDupdateChannelGroup() { + } + MTPDupdateChannelGroup(MTPint _channel_id, const MTPMessageGroup &_group) : vchannel_id(_channel_id), vgroup(_group) { + } + + MTPint vchannel_id; + MTPMessageGroup vgroup; +}; + class MTPDupdateNewChannelMessage : public mtpDataImpl { public: MTPDupdateNewChannelMessage() { @@ -14629,38 +14660,41 @@ public: class MTPmessages_getHistory { // RPC method 'messages.getHistory' public: MTPInputPeer vpeer; - MTPint voffset; + MTPint voffset_id; + MTPint vadd_offset; + MTPint vlimit; MTPint vmax_id; MTPint vmin_id; - MTPint vlimit; MTPmessages_getHistory() { } MTPmessages_getHistory(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getHistory) { read(from, end, cons); } - MTPmessages_getHistory(const MTPInputPeer &_peer, MTPint _offset, MTPint _max_id, MTPint _min_id, MTPint _limit) : vpeer(_peer), voffset(_offset), vmax_id(_max_id), vmin_id(_min_id), vlimit(_limit) { + MTPmessages_getHistory(const MTPInputPeer &_peer, MTPint _offset_id, MTPint _add_offset, MTPint _limit, MTPint _max_id, MTPint _min_id) : vpeer(_peer), voffset_id(_offset_id), vadd_offset(_add_offset), vlimit(_limit), vmax_id(_max_id), vmin_id(_min_id) { } uint32 innerLength() const { - return vpeer.innerLength() + voffset.innerLength() + vmax_id.innerLength() + vmin_id.innerLength() + vlimit.innerLength(); + return vpeer.innerLength() + voffset_id.innerLength() + vadd_offset.innerLength() + vlimit.innerLength() + vmax_id.innerLength() + vmin_id.innerLength(); } mtpTypeId type() const { return mtpc_messages_getHistory; } void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getHistory) { vpeer.read(from, end); - voffset.read(from, end); + voffset_id.read(from, end); + vadd_offset.read(from, end); + vlimit.read(from, end); vmax_id.read(from, end); vmin_id.read(from, end); - vlimit.read(from, end); } void write(mtpBuffer &to) const { vpeer.write(to); - voffset.write(to); + voffset_id.write(to); + vadd_offset.write(to); + vlimit.write(to); vmax_id.write(to); vmin_id.write(to); - vlimit.write(to); } typedef MTPmessages_Messages ResponseType; @@ -14673,7 +14707,7 @@ public: } MTPmessages_GetHistory(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed(from, end, cons) { } - MTPmessages_GetHistory(const MTPInputPeer &_peer, MTPint _offset, MTPint _max_id, MTPint _min_id, MTPint _limit) : MTPBoxed(MTPmessages_getHistory(_peer, _offset, _max_id, _min_id, _limit)) { + MTPmessages_GetHistory(const MTPInputPeer &_peer, MTPint _offset_id, MTPint _add_offset, MTPint _limit, MTPint _max_id, MTPint _min_id) : MTPBoxed(MTPmessages_getHistory(_peer, _offset_id, _add_offset, _limit, _max_id, _min_id)) { } }; @@ -16423,35 +16457,41 @@ public: class MTPmessages_getImportantHistory { // RPC method 'messages.getImportantHistory' public: MTPInputPeer vpeer; + MTPint voffset_id; + MTPint vadd_offset; + MTPint vlimit; MTPint vmax_id; MTPint vmin_id; - MTPint vlimit; MTPmessages_getImportantHistory() { } MTPmessages_getImportantHistory(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getImportantHistory) { read(from, end, cons); } - MTPmessages_getImportantHistory(const MTPInputPeer &_peer, MTPint _max_id, MTPint _min_id, MTPint _limit) : vpeer(_peer), vmax_id(_max_id), vmin_id(_min_id), vlimit(_limit) { + MTPmessages_getImportantHistory(const MTPInputPeer &_peer, MTPint _offset_id, MTPint _add_offset, MTPint _limit, MTPint _max_id, MTPint _min_id) : vpeer(_peer), voffset_id(_offset_id), vadd_offset(_add_offset), vlimit(_limit), vmax_id(_max_id), vmin_id(_min_id) { } uint32 innerLength() const { - return vpeer.innerLength() + vmax_id.innerLength() + vmin_id.innerLength() + vlimit.innerLength(); + return vpeer.innerLength() + voffset_id.innerLength() + vadd_offset.innerLength() + vlimit.innerLength() + vmax_id.innerLength() + vmin_id.innerLength(); } mtpTypeId type() const { return mtpc_messages_getImportantHistory; } void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getImportantHistory) { vpeer.read(from, end); + voffset_id.read(from, end); + vadd_offset.read(from, end); + vlimit.read(from, end); vmax_id.read(from, end); vmin_id.read(from, end); - vlimit.read(from, end); } void write(mtpBuffer &to) const { vpeer.write(to); + voffset_id.write(to); + vadd_offset.write(to); + vlimit.write(to); vmax_id.write(to); vmin_id.write(to); - vlimit.write(to); } typedef MTPmessages_Messages ResponseType; @@ -16464,7 +16504,7 @@ public: } MTPmessages_GetImportantHistory(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed(from, end, cons) { } - MTPmessages_GetImportantHistory(const MTPInputPeer &_peer, MTPint _max_id, MTPint _min_id, MTPint _limit) : MTPBoxed(MTPmessages_getImportantHistory(_peer, _max_id, _min_id, _limit)) { + MTPmessages_GetImportantHistory(const MTPInputPeer &_peer, MTPint _offset_id, MTPint _add_offset, MTPint _limit, MTPint _max_id, MTPint _min_id) : MTPBoxed(MTPmessages_getImportantHistory(_peer, _offset_id, _add_offset, _limit, _max_id, _min_id)) { } }; @@ -16512,27 +16552,33 @@ public: class MTPmessages_createChannel { // RPC method 'messages.createChannel' public: + MTPint vflags; MTPstring vtitle; + MTPVector vusers; MTPmessages_createChannel() { } MTPmessages_createChannel(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_createChannel) { read(from, end, cons); } - MTPmessages_createChannel(const MTPstring &_title) : vtitle(_title) { + MTPmessages_createChannel(MTPint _flags, const MTPstring &_title, const MTPVector &_users) : vflags(_flags), vtitle(_title), vusers(_users) { } uint32 innerLength() const { - return vtitle.innerLength(); + return vflags.innerLength() + vtitle.innerLength() + vusers.innerLength(); } mtpTypeId type() const { return mtpc_messages_createChannel; } void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_createChannel) { + vflags.read(from, end); vtitle.read(from, end); + vusers.read(from, end); } void write(mtpBuffer &to) const { + vflags.write(to); vtitle.write(to); + vusers.write(to); } typedef MTPUpdates ResponseType; @@ -16545,7 +16591,7 @@ public: } MTPmessages_CreateChannel(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed(from, end, cons) { } - MTPmessages_CreateChannel(const MTPstring &_title) : MTPBoxed(MTPmessages_createChannel(_title)) { + MTPmessages_CreateChannel(MTPint _flags, const MTPstring &_title, const MTPVector &_users) : MTPBoxed(MTPmessages_createChannel(_flags, _title, _users)) { } }; @@ -19848,7 +19894,7 @@ inline uint32 MTPchatFull::innerLength() const { } case mtpc_channelFull: { const MTPDchannelFull &v(c_channelFull()); - return v.vid.innerLength() + v.vread_inbox_max_id.innerLength() + v.vunread_count.innerLength() + v.vunread_important_count.innerLength() + v.vchat_photo.innerLength() + v.vnotify_settings.innerLength() + v.vexported_invite.innerLength(); + return v.vid.innerLength() + v.vread_inbox_max_id.innerLength() + v.vunread_count.innerLength() + v.vunread_important_count.innerLength() + v.vinviter_id.innerLength() + v.vinvite_date.innerLength() + v.vchat_photo.innerLength() + v.vnotify_settings.innerLength() + v.vexported_invite.innerLength(); } } return 0; @@ -19877,6 +19923,8 @@ inline void MTPchatFull::read(const mtpPrime *&from, const mtpPrime *end, mtpTyp v.vread_inbox_max_id.read(from, end); v.vunread_count.read(from, end); v.vunread_important_count.read(from, end); + v.vinviter_id.read(from, end); + v.vinvite_date.read(from, end); v.vchat_photo.read(from, end); v.vnotify_settings.read(from, end); v.vexported_invite.read(from, end); @@ -19901,6 +19949,8 @@ inline void MTPchatFull::write(mtpBuffer &to) const { v.vread_inbox_max_id.write(to); v.vunread_count.write(to); v.vunread_important_count.write(to); + v.vinviter_id.write(to); + v.vinvite_date.write(to); v.vchat_photo.write(to); v.vnotify_settings.write(to); v.vexported_invite.write(to); @@ -19921,8 +19971,8 @@ inline MTPchatFull::MTPchatFull(MTPDchannelFull *_data) : mtpDataOwner(_data), _ inline MTPchatFull MTP_chatFull(MTPint _id, const MTPChatParticipants &_participants, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite, const MTPVector &_bot_info) { return MTPchatFull(new MTPDchatFull(_id, _participants, _chat_photo, _notify_settings, _exported_invite, _bot_info)); } -inline MTPchatFull MTP_channelFull(MTPint _id, MTPint _read_inbox_max_id, MTPint _unread_count, MTPint _unread_important_count, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite) { - return MTPchatFull(new MTPDchannelFull(_id, _read_inbox_max_id, _unread_count, _unread_important_count, _chat_photo, _notify_settings, _exported_invite)); +inline MTPchatFull MTP_channelFull(MTPint _id, MTPint _read_inbox_max_id, MTPint _unread_count, MTPint _unread_important_count, MTPint _inviter_id, MTPint _invite_date, const MTPPhoto &_chat_photo, const MTPPeerNotifySettings &_notify_settings, const MTPExportedChatInvite &_exported_invite) { + return MTPchatFull(new MTPDchannelFull(_id, _read_inbox_max_id, _unread_count, _unread_important_count, _inviter_id, _invite_date, _chat_photo, _notify_settings, _exported_invite)); } inline MTPchatParticipant::MTPchatParticipant() : mtpDataOwner(new MTPDchatParticipant()) { @@ -22241,6 +22291,10 @@ inline uint32 MTPupdate::innerLength() const { const MTPDupdateChannelTooLong &v(c_updateChannelTooLong()); return v.vchannel_id.innerLength(); } + case mtpc_updateChannelGroup: { + const MTPDupdateChannelGroup &v(c_updateChannelGroup()); + return v.vchannel_id.innerLength() + v.vgroup.innerLength(); + } case mtpc_updateNewChannelMessage: { const MTPDupdateNewChannelMessage &v(c_updateNewChannelMessage()); return v.vmessage.innerLength() + v.vpts.innerLength() + v.vpts_count.innerLength(); @@ -22453,6 +22507,12 @@ inline void MTPupdate::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeI MTPDupdateChannelTooLong &v(_updateChannelTooLong()); v.vchannel_id.read(from, end); } break; + case mtpc_updateChannelGroup: _type = cons; { + if (!data) setData(new MTPDupdateChannelGroup()); + MTPDupdateChannelGroup &v(_updateChannelGroup()); + v.vchannel_id.read(from, end); + v.vgroup.read(from, end); + } break; case mtpc_updateNewChannelMessage: _type = cons; { if (!data) setData(new MTPDupdateNewChannelMessage()); MTPDupdateNewChannelMessage &v(_updateNewChannelMessage()); @@ -22640,6 +22700,11 @@ inline void MTPupdate::write(mtpBuffer &to) const { const MTPDupdateChannelTooLong &v(c_updateChannelTooLong()); v.vchannel_id.write(to); } break; + case mtpc_updateChannelGroup: { + const MTPDupdateChannelGroup &v(c_updateChannelGroup()); + v.vchannel_id.write(to); + v.vgroup.write(to); + } break; case mtpc_updateNewChannelMessage: { const MTPDupdateNewChannelMessage &v(c_updateNewChannelMessage()); v.vmessage.write(to); @@ -22691,6 +22756,7 @@ inline MTPupdate::MTPupdate(mtpTypeId type) : mtpDataOwner(0), _type(type) { case mtpc_updateWebPage: setData(new MTPDupdateWebPage()); break; case mtpc_updateReadMessagesContents: setData(new MTPDupdateReadMessagesContents()); break; case mtpc_updateChannelTooLong: setData(new MTPDupdateChannelTooLong()); break; + case mtpc_updateChannelGroup: setData(new MTPDupdateChannelGroup()); break; case mtpc_updateNewChannelMessage: setData(new MTPDupdateNewChannelMessage()); break; case mtpc_updateReadChannelInbox: setData(new MTPDupdateReadChannelInbox()); break; case mtpc_updateDeleteChannelMessages: setData(new MTPDupdateDeleteChannelMessages()); break; @@ -22755,6 +22821,8 @@ inline MTPupdate::MTPupdate(MTPDupdateReadMessagesContents *_data) : mtpDataOwne } inline MTPupdate::MTPupdate(MTPDupdateChannelTooLong *_data) : mtpDataOwner(_data), _type(mtpc_updateChannelTooLong) { } +inline MTPupdate::MTPupdate(MTPDupdateChannelGroup *_data) : mtpDataOwner(_data), _type(mtpc_updateChannelGroup) { +} inline MTPupdate::MTPupdate(MTPDupdateNewChannelMessage *_data) : mtpDataOwner(_data), _type(mtpc_updateNewChannelMessage) { } inline MTPupdate::MTPupdate(MTPDupdateReadChannelInbox *_data) : mtpDataOwner(_data), _type(mtpc_updateReadChannelInbox) { @@ -22848,6 +22916,9 @@ inline MTPupdate MTP_updateReadMessagesContents(const MTPVector &_messag inline MTPupdate MTP_updateChannelTooLong(MTPint _channel_id) { return MTPupdate(new MTPDupdateChannelTooLong(_channel_id)); } +inline MTPupdate MTP_updateChannelGroup(MTPint _channel_id, const MTPMessageGroup &_group) { + return MTPupdate(new MTPDupdateChannelGroup(_channel_id, _group)); +} inline MTPupdate MTP_updateNewChannelMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count) { return MTPupdate(new MTPDupdateNewChannelMessage(_message, _pts, _pts_count)); } @@ -26714,6 +26785,7 @@ inline void MTPchannelMessagesFilter::read(const mtpPrime *&from, const mtpPrime v.vflags.read(from, end); v.vranges.read(from, end); } break; + case mtpc_channelMessagesFilterCollapsed: _type = cons; break; default: throw mtpErrorUnexpected(cons, "MTPchannelMessagesFilter"); } } @@ -26730,6 +26802,7 @@ inline MTPchannelMessagesFilter::MTPchannelMessagesFilter(mtpTypeId type) : mtpD switch (type) { case mtpc_channelMessagesFilterEmpty: break; case mtpc_channelMessagesFilter: setData(new MTPDchannelMessagesFilter()); break; + case mtpc_channelMessagesFilterCollapsed: break; default: throw mtpErrorBadTypeId(type, "MTPchannelMessagesFilter"); } } @@ -26741,6 +26814,9 @@ inline MTPchannelMessagesFilter MTP_channelMessagesFilterEmpty() { inline MTPchannelMessagesFilter MTP_channelMessagesFilter(MTPint _flags, const MTPVector &_ranges) { return MTPchannelMessagesFilter(new MTPDchannelMessagesFilter(_flags, _ranges)); } +inline MTPchannelMessagesFilter MTP_channelMessagesFilterCollapsed() { + return MTPchannelMessagesFilter(mtpc_channelMessagesFilterCollapsed); +} // Human-readable text serialization #if (defined _DEBUG || defined _WITH_DEBUG) diff --git a/Telegram/SourceFiles/mtproto/scheme.tl b/Telegram/SourceFiles/mtproto/scheme.tl index 7855bf012..c3e2dce7d 100644 --- a/Telegram/SourceFiles/mtproto/scheme.tl +++ b/Telegram/SourceFiles/mtproto/scheme.tl @@ -221,7 +221,7 @@ chatForbidden#fb0ccc41 id:int title:string date:int = Chat; channel#8dbb1461 flags:# id:int access_hash:long title:string photo:ChatPhoto date:int version:int = Chat; chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector = ChatFull; -channelFull#eb8a0d68 id:int read_inbox_max_id:int unread_count:int unread_important_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite = ChatFull; +channelFull#a09d2902 id:int read_inbox_max_id:int unread_count:int unread_important_count:int inviter_id:int invite_date:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite = ChatFull; chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant; @@ -376,6 +376,7 @@ updateReadHistoryOutbox#2f2f21bf peer:Peer max_id:int pts:int pts_count:int = Up updateWebPage#2cc36971 webpage:WebPage = Update; updateReadMessagesContents#68c13933 messages:Vector pts:int pts_count:int = Update; updateChannelTooLong#60946422 channel_id:int = Update; +updateChannelGroup#c36c1e3c channel_id:int group:MessageGroup = Update; updateNewChannelMessage#62ba04d9 message:Message pts:int pts_count:int = Update; updateReadChannelInbox#87b87b7d peer:Peer max_id:int = Update; updateDeleteChannelMessages#11da3046 peer:Peer messages:Vector pts:int pts_count:int = Update; @@ -594,6 +595,7 @@ updates.channelDifference#2064674e flags:# pts:int timeout:flags.1?int new_messa channelMessagesFilterEmpty#94d42ee7 = ChannelMessagesFilter; channelMessagesFilter#cd77d957 flags:# ranges:Vector = ChannelMessagesFilter; +channelMessagesFilterCollapsed#fa01232e = ChannelMessagesFilter; ---functions--- @@ -663,7 +665,7 @@ contacts.resolveUsername#bf0131c username:string = User; messages.getMessages#4222fa74 id:Vector = messages.Messages; messages.getDialogs#859b3d3c offset:int limit:int = messages.Dialogs; -messages.getHistory#e1ded325 peer:InputPeer offset:int max_id:int min_id:int limit:int = messages.Messages; +messages.getHistory#8a8ec2da peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages; messages.search#7e9f2ab peer:InputPeer q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = messages.Messages; messages.readHistory#b04f2510 peer:InputPeer max_id:int offset:int = messages.AffectedHistory; messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHistory; @@ -704,9 +706,9 @@ messages.installStickerSet#7b30c3a6 stickerset:InputStickerSet disabled:Bool = B messages.uninstallStickerSet#f96e55de stickerset:InputStickerSet = Bool; messages.startBot#f4cc052d bot:InputUser chat_id:InputChat random_id:long start_param:string = Updates; messages.getChannelDialogs#92689583 offset:int limit:int = messages.Dialogs; -messages.getImportantHistory#25b7f3b2 peer:InputPeer max_id:int min_id:int limit:int = messages.Messages; +messages.getImportantHistory#24af43a5 peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages; messages.readChannelHistory#36a1210e peer:InputPeer max_id:int = Bool; -messages.createChannel#d9bc5fd2 title:string = Updates; +messages.createChannel#e830f8cb flags:# title:string users:Vector = Updates; messages.deleteChannelMessages#9995a84f peer:InputPeer id:Vector = messages.AffectedMessages; updates.getState#edd4882a = updates.State; @@ -728,4 +730,4 @@ help.getAppUpdate#c812ac7e device_model:string system_version:string app_version help.saveAppLog#6f02f748 events:Vector = Bool; help.getInviteText#a4a95186 lang_code:string = help.InviteText; help.getSupport#9cdf08cd = help.Support; -help.getAppChangelog#5bab7fb2 device_model:string system_version:string app_version:string lang_code:string = help.AppChangelog; +help.getAppChangelog#5bab7fb2 device_model:string system_version:string app_version:string lang_code:string = help.AppChangelog; \ No newline at end of file diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index 75ce59fbe..500287138 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -308,17 +308,27 @@ void OverviewInner::searchReceived(bool fromStart, const MTPmessages_Messages &r const QVector *messages = 0; switch (result.type()) { case mtpc_messages_messages: { - App::feedUsers(result.c_messages_messages().vusers); - App::feedChats(result.c_messages_messages().vchats); - messages = &result.c_messages_messages().vmessages.c_vector().v; + const MTPDmessages_messages &d(result.c_messages_messages()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + messages = &d.vmessages.c_vector().v; _searchedCount = messages->size(); } break; case mtpc_messages_messagesSlice: { - App::feedUsers(result.c_messages_messagesSlice().vusers); - App::feedChats(result.c_messages_messagesSlice().vchats); - messages = &result.c_messages_messagesSlice().vmessages.c_vector().v; - _searchedCount = result.c_messages_messagesSlice().vcount.v; + const MTPDmessages_messagesSlice &d(result.c_messages_messagesSlice()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + messages = &d.vmessages.c_vector().v; + _searchedCount = d.vcount.v; + } break; + + case mtpc_messages_channelMessages: { + const MTPDmessages_channelMessages &d(result.c_messages_channelMessages()); + App::feedUsers(d.vusers); + App::feedChats(d.vchats); + messages = &d.vmessages.c_vector().v; + _searchedCount = d.vcount.v; } break; } if (messages) { diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp index 79026862c..53ad8a2f3 100644 --- a/Telegram/SourceFiles/profilewidget.cpp +++ b/Telegram/SourceFiles/profilewidget.cpp @@ -31,7 +31,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const PeerData *peer) : TWidget(0), _profile(profile), _scroll(scroll), _peer(App::peer(peer->id)), _peerUser(_peer->asUser()), _peerChat(_peer->asChat()), _peerChannel(_peer->asChannel()), _hist(App::history(peer->id)), - _chatAdmin(_peerChat ? (_peerChat->admin == MTP::authedId()) : false), + _isAdmin(_peerChat ? (_peerChat->admin == MTP::authedId()) : (_peerChannel ? _peerChannel->adminned : false)), // profile _nameCache(peer->name), @@ -90,7 +90,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee if ((_peerUser->botInfo && !_peerUser->botInfo->inited) || (_peerUser->photoId == UnknownPeerPhotoId) || (_peerUser->photoId && !userPhoto->date) || (_peerUser->blocked == UserBlockUnknown)) { App::api()->requestFullPeer(_peer); } - } else { + } else if (_peerChat) { PhotoData *chatPhoto = (_peerChat->photoId && _peerChat->photoId != UnknownPeerPhotoId) ? App::photo(_peerChat->photoId) : 0; if (chatPhoto && chatPhoto->date) { _photoLink = TextLinkPtr(new PhotoLink(chatPhoto, _peer)); @@ -98,6 +98,14 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee if (_peerChat->photoId == UnknownPeerPhotoId) { App::api()->requestFullPeer(_peer); } + } else if (_peerChannel) { + PhotoData *chatPhoto = (_peerChannel->photoId && _peerChannel->photoId != UnknownPeerPhotoId) ? App::photo(_peerChannel->photoId) : 0; + if (chatPhoto && chatPhoto->date) { + _photoLink = TextLinkPtr(new PhotoLink(chatPhoto, _peer)); + } + if (_peerChannel->photoId == UnknownPeerPhotoId) { + App::api()->requestFullPeer(_peer); + } } // profile @@ -305,6 +313,8 @@ bool ProfileInner::blockFail(const RPCError &error) { } void ProfileInner::onAddParticipant() { + if (!_peerChat) return; + App::wnd()->showLayer(new ContactsBox(_peerChat)); } @@ -360,11 +370,15 @@ void ProfileInner::onMediaLinks() { } void ProfileInner::onInvitationLink() { + if (!_peerChat) return; + QApplication::clipboard()->setText(_peerChat->invitationUrl); App::wnd()->showLayer(new ConfirmBox(lang(lng_group_invite_copied), true)); } void ProfileInner::onCreateInvitationLink() { + if (!_peerChat) return; + ConfirmBox *box = new ConfirmBox(lang(_peerChat->invitationUrl.isEmpty() ? lng_group_invite_about : lng_group_invite_about_new)); connect(box, SIGNAL(confirmed()), this, SLOT(onCreateInvitationLinkSure())); App::wnd()->showLayer(box); @@ -376,6 +390,8 @@ void ProfileInner::onCreateInvitationLinkSure() { } void ProfileInner::chatInviteDone(const MTPExportedChatInvite &result) { + if (!_peerChat) return; + _peerChat->invitationUrl = (result.type() == mtpc_chatInviteExported) ? qs(result.c_chatInviteExported().vlink) : QString(); updateInvitationLink(); showAll(); @@ -405,10 +421,16 @@ void ProfileInner::onFullPeerUpdated(PeerData *peer) { updateInvitationLink(); showAll(); resizeEvent(0); + } else if (_peerChannel) { + updateInvitationLink(); + showAll(); + resizeEvent(0); } } void ProfileInner::onBotSettings() { + if (!_peerUser || !_peerUser->botInfo) return; + for (int32 i = 0, l = _peerUser->botInfo->commands.size(); i != l; ++i) { QString cmd = _peerUser->botInfo->commands.at(i).command; if (!cmd.compare(qsl("settings"), Qt::CaseInsensitive)) { @@ -421,6 +443,8 @@ void ProfileInner::onBotSettings() { } void ProfileInner::onBotHelp() { + if (!_peerUser || !_peerUser->botInfo) return; + for (int32 i = 0, l = _peerUser->botInfo->commands.size(); i != l; ++i) { QString cmd = _peerUser->botInfo->commands.at(i).command; if (!cmd.compare(qsl("help"), Qt::CaseInsensitive)) { @@ -442,8 +466,10 @@ void ProfileInner::peerUpdated(PeerData *data) { _wasBlocked = _peerUser->blocked; _blockUser.setText(lang((_peerUser->blocked == UserIsBlocked) ? (_peerUser->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user) : (_peerUser->botInfo ? lng_profile_block_bot : lng_profile_block_user))); } - } else { + } else if (_peerChat) { if (_peerChat->photoId && _peerChat->photoId != UnknownPeerPhotoId) photo = App::photo(_peerChat->photoId); + } else if (_peerChannel) { + if (_peerChannel->photoId && _peerChannel->photoId != UnknownPeerPhotoId) photo = App::photo(_peerChannel->photoId); } _photoLink = (photo && photo->date) ? TextLinkPtr(new PhotoLink(photo, _peer)) : TextLinkPtr(); if (_peer->name != _nameCache) { @@ -462,7 +488,9 @@ void ProfileInner::updateOnlineDisplay() { void ProfileInner::updateOnlineDisplayTimer() { int32 t = unixtime(), minIn = 86400; - if (_peerChat) { + if (_peerUser) { + minIn = App::onlineWillChangeIn(_peerUser, t); + } else if (_peerChat) { if (_peerChat->participants.isEmpty()) return; for (ChatData::Participants::const_iterator i = _peerChat->participants.cbegin(), e = _peerChat->participants.cend(); i != e; ++i) { @@ -471,8 +499,7 @@ void ProfileInner::updateOnlineDisplayTimer() { minIn = onlineWillChangeIn; } } - } else { - minIn = App::onlineWillChangeIn(_peerUser, t); + } else if (_peerChannel) { } App::main()->updateOnlineDisplayIn(minIn * 1000); } @@ -524,6 +551,8 @@ void ProfileInner::reorderParticipants() { _participants.clear(); if (_peerUser) { _onlineText = App::onlineText(_peerUser, t, true); + } else if (_peerChannel) { + _onlineText = lang(lng_channel_status); } else { _onlineText = lang(lng_chat_status_unaccessible); } @@ -578,7 +607,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) { } p.setPen((_peerUser && App::onlineColorUse(_peerUser, l_time) ? st::profileOnlineColor : st::profileOfflineColor)->p); p.drawText(_left + st::profilePhotoSize + st::profileStatusLeft, top + addbyname + st::profileStatusTop + st::linkFont->ascent, _onlineText); - if (_chatAdmin && !_peerChat->invitationUrl.isEmpty()) { + if (_isAdmin && ((_peerChat && !_peerChat->invitationUrl.isEmpty()) || (_peerChannel && !_peerChannel->invitationUrl.isEmpty()))) { p.setPen(st::black->p); p.drawText(_left + st::profilePhotoSize + st::profilePhoneLeft, _createInvitationLink.y() + st::linkFont->ascent, lang(lng_group_invite_link)); } @@ -606,7 +635,9 @@ void ProfileInner::paintEvent(QPaintEvent *e) { p.setPen(st::profileOfflineColor->p); p.drawText(_left + (_width - w) / 2, top + st::btnShareContact.textTop + st::btnShareContact.font->ascent, lang(lng_profile_chat_unaccessible)); } - top += _shareContact.height(); + if (!_peerChannel || _isAdmin) { + top += _shareContact.height(); + } // about if (!_about.isEmpty()) { @@ -671,7 +702,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) { // actions p.setFont(st::profileHeaderFont->f); p.setPen(st::profileHeaderColor->p); - p.drawText(_left + st::profileHeaderLeft, top + st::profileHeaderTop + st::profileHeaderFont->ascent, lang(lng_profile_actions_section)); + if (!_peerChannel) p.drawText(_left + st::profileHeaderLeft, top + st::profileHeaderTop + st::profileHeaderFont->ascent, lang(lng_profile_actions_section)); top += st::profileHeaderSkip; top += _searchInPeer.height() + st::setLittleSkip + _clearHistory.height() + st::setLittleSkip + _deleteConversation.height(); @@ -712,7 +743,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) { } else { data->online = App::onlineText(user, l_time); } - data->cankick = (user != App::self()) && (_chatAdmin || (_peerChat->cankick.constFind(user) != _peerChat->cankick.cend())); + data->cankick = (user != App::self()) && (_isAdmin || (_peerChat->cankick.constFind(user) != _peerChat->cankick.cend())); } p.setPen(st::profileListNameColor->p); p.setFont(st::linkFont->f); @@ -844,6 +875,8 @@ void ProfileInner::mouseReleaseEvent(QMouseEvent *e) { } void ProfileInner::onKickConfirm() { + if (!_peerChat) return; + App::main()->kickParticipant(_peerChat, _kickConfirm); } @@ -881,8 +914,8 @@ void ProfileInner::resizeEvent(QResizeEvent *e) { // profile top += st::profilePadding.top(); - if (_chatAdmin) { - if (_peerChat->invitationUrl.isEmpty()) { + if (_isAdmin) { + if ((_peerChat && _peerChat->invitationUrl.isEmpty()) || (_peerChannel && _peerChannel->invitationUrl.isEmpty())) { _createInvitationLink.move(_left + st::profilePhotoSize + st::profilePhoneLeft, top + st::profilePhoneTop); } else { _createInvitationLink.move(_left + _width - _createInvitationLink.width(), top + st::profilePhoneTop); @@ -908,7 +941,9 @@ void ProfileInner::resizeEvent(QResizeEvent *e) { _shareContact.setGeometry(_left + _width - btnWidth, top, btnWidth, _shareContact.height()); _inviteToGroup.setGeometry(_left + _width - btnWidth, top, btnWidth, _inviteToGroup.height()); - top += _shareContact.height(); + if (!_peerChannel || _isAdmin) { + top += _shareContact.height(); + } // about if (!_about.isEmpty()) { @@ -1006,6 +1041,7 @@ void ProfileInner::onCopyPhone() { } void ProfileInner::onCopyUsername() { + if (!_peerUser) return; QApplication::clipboard()->setText('@' + _peerUser->username); } @@ -1059,43 +1095,7 @@ void ProfileInner::showAll() { _searchInPeer.show(); _clearHistory.show(); _deleteConversation.show(); - if (_peerChat) { - _sendMessage.hide(); - _shareContact.hide(); - _inviteToGroup.hide(); - if (_peerChat->forbidden) { - _uploadPhoto.hide(); - _cancelPhoto.hide(); - _addParticipant.hide(); - _createInvitationLink.hide(); - _invitationLink.hide(); - } else { - if (App::app()->isPhotoUpdating(_peer->id)) { - _uploadPhoto.hide(); - _cancelPhoto.show(); - } else { - _uploadPhoto.show(); - _cancelPhoto.hide(); - } - if (_chatAdmin) { - _createInvitationLink.show(); - if (_peerChat->invitationUrl.isEmpty()) { - _invitationLink.hide(); - } else { - _invitationLink.show(); - } - } else { - _createInvitationLink.hide(); - _invitationLink.hide(); - } - if (_peerChat->count < cMaxGroupCount()) { - _addParticipant.show(); - } else { - _addParticipant.hide(); - } - } - _blockUser.hide(); - } else { + if (_peerUser) { _uploadPhoto.hide(); _cancelPhoto.hide(); _addParticipant.hide(); @@ -1119,6 +1119,78 @@ void ProfileInner::showAll() { } else { _blockUser.hide(); } + } else if (_peerChat) { + _sendMessage.hide(); + _shareContact.hide(); + _inviteToGroup.hide(); + if (_peerChat->forbidden) { + _uploadPhoto.hide(); + _cancelPhoto.hide(); + _addParticipant.hide(); + _createInvitationLink.hide(); + _invitationLink.hide(); + } else { + if (App::app()->isPhotoUpdating(_peer->id)) { + _uploadPhoto.hide(); + _cancelPhoto.show(); + } else { + _uploadPhoto.show(); + _cancelPhoto.hide(); + } + if (_isAdmin) { + _createInvitationLink.show(); + if (_peerChat && _peerChat->invitationUrl.isEmpty()) { + _invitationLink.hide(); + } else { + _invitationLink.show(); + } + } else { + _createInvitationLink.hide(); + _invitationLink.hide(); + } + if (_peerChat->count < cMaxGroupCount()) { + _addParticipant.show(); + } else { + _addParticipant.hide(); + } + } + _blockUser.hide(); + } else if (_peerChannel) { + _sendMessage.hide(); + _shareContact.hide(); + _inviteToGroup.hide(); + if (_peerChannel->forbidden) { + _uploadPhoto.hide(); + _cancelPhoto.hide(); + _addParticipant.hide(); + _createInvitationLink.hide(); + _invitationLink.hide(); + } else { + if (App::app()->isPhotoUpdating(_peer->id)) { + _uploadPhoto.hide(); + _cancelPhoto.show(); + } else { + if (_isAdmin) { + _uploadPhoto.show(); + } else { + _uploadPhoto.hide(); + } + _cancelPhoto.hide(); + } + if (_isAdmin) { + _createInvitationLink.show(); + if (_peerChannel->invitationUrl.isEmpty()) { + _invitationLink.hide(); + } else { + _invitationLink.show(); + } + } else { + _createInvitationLink.hide(); + _invitationLink.hide(); + } + _addParticipant.hide(); + } + _blockUser.hide(); } _enableNotifications.show(); updateNotifySettings(); @@ -1168,19 +1240,22 @@ void ProfileInner::showAll() { } else { h = _blockUser.y() + _blockUser.height() + st::profileHeaderSkip; } - } else { + } else if (_peerChat) { h = _deleteConversation.y() + _deleteConversation.height() + st::profileHeaderSkip; if (!_participants.isEmpty()) { h += st::profileHeaderSkip + _participants.size() * _pHeight; } else if (_peerChat->count > 0) { h += st::profileHeaderSkip; } + } else if (_peerChannel) { + h = _deleteConversation.y() + _deleteConversation.height() + st::profileHeaderSkip; } resize(width(), h); } void ProfileInner::updateInvitationLink() { if (!_peerChat) return; + if (_peerChat->invitationUrl.isEmpty()) { _createInvitationLink.setText(lang(lng_group_invite_create)); } else { diff --git a/Telegram/SourceFiles/profilewidget.h b/Telegram/SourceFiles/profilewidget.h index 91493bd3e..4bfe1d4aa 100644 --- a/Telegram/SourceFiles/profilewidget.h +++ b/Telegram/SourceFiles/profilewidget.h @@ -123,7 +123,7 @@ private: ChatData *_peerChat; ChannelData *_peerChannel; History *_hist; - bool _chatAdmin; + bool _isAdmin; int32 _width, _left; diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index b6ea1a3ea..30324646b 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -83,7 +83,7 @@ ImagePtr chatDefPhoto(int32 index) { NotifySettings globalNotifyAll, globalNotifyUsers, globalNotifyChats; NotifySettingsPtr globalNotifyAllPtr = UnknownNotifySettings, globalNotifyUsersPtr = UnknownNotifySettings, globalNotifyChatsPtr = UnknownNotifySettings; -PeerData::PeerData(const PeerId &id) : id(id) +PeerData::PeerData(const PeerId &id) : id(id), lnk(new PeerLink(this)) , loaded(false) , colorIndex(peerColorIndex(id)) , color(peerColor(colorIndex)) @@ -92,21 +92,24 @@ PeerData::PeerData(const PeerId &id) : id(id) , nameVersion(0) , notify(UnknownNotifySettings) { + if (!peerIsUser(id)) updateName(QString(), QString(), QString()); } void PeerData::updateName(const QString &newName, const QString &newNameOrPhone, const QString &newUsername) { - if (name == newName && nameOrPhone == newNameOrPhone && (!isUser() || asUser()->username == newUsername) && nameVersion > 0) return; + if (name == newName && (!isUser() || (asUser()->nameOrPhone == newNameOrPhone && asUser()->username == newUsername)) && nameVersion > 0) return; ++nameVersion; name = newName; - nameOrPhone = newNameOrPhone; - if (isUser()) asUser()->username = newUsername; + nameText.setText(st::msgNameFont, name, _textNameOptions); + if (isUser()) { + asUser()->username = newUsername; + asUser()->setNameOrPhone(newNameOrPhone); + } Names oldNames = names; NameFirstChars oldChars = chars; fillNames(); - App::history(id)->updateNameText(); - nameUpdated(); + if (App::main()) { emit App::main()->peerNameChanged(this, oldNames, oldChars); } @@ -148,11 +151,9 @@ void PeerData::fillNames() { names.clear(); chars.clear(); QString toIndex = textAccentFold(name); - if (nameOrPhone != name) { - toIndex += ' ' + textAccentFold(nameOrPhone); - } if (isUser()) { - toIndex += ' ' + textAccentFold(asUser()->username); + if (!asUser()->nameOrPhone.isEmpty() && asUser()->nameOrPhone != name) toIndex += ' ' + textAccentFold(asUser()->nameOrPhone); + if (!asUser()->username.isEmpty()) toIndex += ' ' + textAccentFold(asUser()->username); } if (cRussianLetters().match(toIndex).hasMatch()) { toIndex += ' ' + translitRusEng(toIndex); @@ -166,6 +167,13 @@ void PeerData::fillNames() { } } +const Text &PeerData::dialogName() const { + return (isUser() && !asUser()->phoneText.isEmpty()) ? asUser()->phoneText : nameText; +} + +const QString &PeerData::shortName() const { + return isUser() ? asUser()->firstName : name; +} void UserData::setName(const QString &first, const QString &last, const QString &phoneName, const QString &usern) { bool updName = !first.isEmpty() || !last.isEmpty(), updUsername = (username != usern); @@ -273,8 +281,11 @@ void UserData::setBotInfo(const MTPBotInfo &info) { } } -void UserData::nameUpdated() { - nameText.setText(st::msgNameFont, name, _textNameOptions); +void UserData::setNameOrPhone(const QString &newNameOrPhone) { + if (nameOrPhone != newNameOrPhone) { + nameOrPhone = newNameOrPhone; + phoneText.setText(st::msgNameFont, nameOrPhone, _textNameOptions); + } } void UserData::madeAction() { diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index b4191f0ab..35333ee47 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -179,16 +179,18 @@ public: void fillNames(); - virtual void nameUpdated() { - } + const Text &dialogName() const; + const QString &shortName() const; const PeerId id; int32 bareId() const { return int32(uint32(id & 0xFFFFFFFFULL)); } + TextLinkPtr lnk; + QString name; - QString nameOrPhone; + Text nameText; typedef QSet Names; Names names; // for filtering typedef QSet NameFirstChars; @@ -284,14 +286,16 @@ struct PhotoData; class UserData : public PeerData { public: - UserData(const PeerId &id) : PeerData(id), access(0), lnk(new PeerLink(this)), onlineTill(0), contact(-1), blocked(UserBlockUnknown), photosCount(-1), botInfo(0) { + UserData(const PeerId &id) : PeerData(id), access(0), onlineTill(0), contact(-1), blocked(UserBlockUnknown), photosCount(-1), botInfo(0) { + setName(QString(), QString(), QString(), QString()); } void setPhoto(const MTPUserProfilePhoto &photo); void setName(const QString &first, const QString &last, const QString &phoneName, const QString &username); void setPhone(const QString &newPhone); void setBotInfoVersion(int32 version); void setBotInfo(const MTPBotInfo &info); - void nameUpdated(); + + void setNameOrPhone(const QString &newNameOrPhone); void madeAction(); // pseudo-online @@ -303,8 +307,8 @@ public: QString lastName; QString username; QString phone; - Text nameText; - TextLinkPtr lnk; + QString nameOrPhone; + Text phoneText; int32 onlineTill; int32 contact; // -1 - not contact, cant add (self, empty, deleted, foreign), 0 - not contact, can add (request), 1 - contact UserBlockedStatus blocked; @@ -319,7 +323,7 @@ public: class ChatData : public PeerData { public: - ChatData(const PeerId &id) : PeerData(id), inputChat(MTP_inputChat(MTP_int(bareId()))), count(0), date(0), version(0), left(false), forbidden(true), botStatus(0) { + ChatData(const PeerId &id) : PeerData(id), inputChat(MTP_inputChat(MTP_int(bareId()))), count(0), date(0), version(0), admin(0), left(false), forbidden(true), botStatus(0) { } void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId); @@ -337,7 +341,7 @@ public: CanKick cankick; typedef QList LastAuthors; LastAuthors lastAuthors; - typedef QMap MarkupSenders; + typedef QMap MarkupSenders; MarkupSenders markupSenders; int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other // ImagePtr photoFull; @@ -347,7 +351,7 @@ public: class ChannelData : public PeerData { public: - ChannelData(const PeerId &id) : PeerData(id), access(0), inputChat(MTP_inputChannel(MTP_int(bareId()), MTP_long(0))), date(0), version(0), left(false), forbidden(true), botStatus(-1) { + ChannelData(const PeerId &id) : PeerData(id), access(0), inputChat(MTP_inputChannel(MTP_int(bareId()), MTP_long(0))), date(0), version(0), adminned(false), left(false), forbidden(true), botStatus(-1) { } void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId); @@ -357,6 +361,7 @@ public: int32 date; int32 version; + bool adminned; bool left; bool forbidden; diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index 896bd0312..21123feb0 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -215,7 +215,7 @@ void NotifyWindow::updateNotifyDisplay() { p.setPen(st::dlgNameColor->p); if (!App::passcoded() && cNotifyView() <= dbinvShowName) { - history->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); + history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); } else { p.setFont(st::msgNameFont->f); static QString notifyTitle = st::msgNameFont->m.elidedText(qsl("Telegram Desktop"), Qt::ElideRight, rectForName.width()); @@ -609,7 +609,7 @@ void Window::sendServiceHistoryRequest() { int32 userFlags = MTPDuser::flag_first_name | MTPDuser::flag_phone | MTPDuser::flag_status; user = App::feedUsers(MTP_vector(1, MTP_user(MTP_int(userFlags), MTP_int(ServiceUserId), MTPlong(), MTP_string("Telegram"), MTPstring(), MTPstring(), MTP_string("42777"), MTP_userProfilePhotoEmpty(), MTP_userStatusRecently(), MTPint()))); } - _serviceHistoryRequest = MTP::send(MTPmessages_GetHistory(user->input, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(1)), main->rpcDone(&MainWidget::serviceHistoryDone), main->rpcFail(&MainWidget::serviceHistoryFail)); + _serviceHistoryRequest = MTP::send(MTPmessages_GetHistory(user->input, MTP_int(0), MTP_int(0), MTP_int(1), MTP_int(0), MTP_int(0)), main->rpcDone(&MainWidget::serviceHistoryDone), main->rpcFail(&MainWidget::serviceHistoryFail)); } void Window::setupMain(bool anim, const MTPUser *self) { @@ -1229,7 +1229,7 @@ void Window::quit() { void Window::notifySchedule(History *history, HistoryItem *item) { if (App::quiting() || !history->currentNotification() || !main) return; - UserData *notifyByFrom = (!history->peer->isUser() && item->notifyByFrom()) ? item->from() : 0; + PeerData *notifyByFrom = (!history->peer->isUser() && item->notifyByFrom()) ? item->from() : 0; bool haveSetting = (history->peer->notify != UnknownNotifySettings); if (haveSetting) { @@ -1340,7 +1340,7 @@ void Window::notifySettingGot() { } else { if (history->peer->notify == EmptyNotifySettings || history->peer->notify->mute <= t) { notifyWaiters.insert(i.key(), i.value()); - } else if (UserData *from = i.value().notifyByFrom) { + } else if (PeerData *from = i.value().notifyByFrom) { if (from->notify == UnknownNotifySettings) { ++i; continue; diff --git a/Telegram/SourceFiles/window.h b/Telegram/SourceFiles/window.h index 321cbae27..a63c6044c 100644 --- a/Telegram/SourceFiles/window.h +++ b/Telegram/SourceFiles/window.h @@ -322,18 +322,18 @@ private: typedef QMap NotifyWhenMaps; NotifyWhenMaps notifyWhenMaps; struct NotifyWaiter { - NotifyWaiter(MsgId msg, uint64 when, UserData *notifyByFrom) : msg(msg), when(when), notifyByFrom(notifyByFrom) { + NotifyWaiter(MsgId msg, uint64 when, PeerData *notifyByFrom) : msg(msg), when(when), notifyByFrom(notifyByFrom) { } MsgId msg; uint64 when; - UserData *notifyByFrom; + PeerData *notifyByFrom; }; typedef QMap NotifyWaiters; NotifyWaiters notifyWaiters; NotifyWaiters notifySettingWaiters; SingleTimer notifyWaitTimer; - typedef QMap NotifyWhenAlert; + typedef QMap NotifyWhenAlert; typedef QMap NotifyWhenAlerts; NotifyWhenAlerts notifyWhenAlerts;