mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Common groups profile block done. Moved to layer 59.
Also profile block modules were renamed.
This commit is contained in:
parent
a3c406dd00
commit
7bb3b4d807
47 changed files with 4539 additions and 1041 deletions
|
@ -434,6 +434,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
"lng_profile_create_public_link" = "Create public link";
|
||||
"lng_profile_edit_public_link" = "Edit public link";
|
||||
"lng_profile_manage_admins" = "Manage administrators";
|
||||
"lng_profile_common_groups" = "{count:_not_used_|# group|# groups} in common";
|
||||
"lng_profile_common_groups_section" = "Groups in common";
|
||||
"lng_profile_participants_section" = "Members";
|
||||
"lng_profile_info_section" = "Info";
|
||||
"lng_profile_mobile_number" = "Mobile:";
|
||||
|
|
|
@ -325,7 +325,10 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
|||
}
|
||||
|
||||
void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestId req) {
|
||||
const auto &d(result.c_userFull());
|
||||
auto user = peer->asUser();
|
||||
t_assert(user != nullptr);
|
||||
|
||||
auto &d = result.c_userFull();
|
||||
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser));
|
||||
if (d.has_profile_photo()) {
|
||||
App::feedPhoto(d.vprofile_photo);
|
||||
|
@ -336,12 +339,13 @@ void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestI
|
|||
}
|
||||
|
||||
if (d.has_bot_info()) {
|
||||
peer->asUser()->setBotInfo(d.vbot_info);
|
||||
user->setBotInfo(d.vbot_info);
|
||||
} else {
|
||||
peer->asUser()->setBotInfoVersion(-1);
|
||||
user->setBotInfoVersion(-1);
|
||||
}
|
||||
peer->asUser()->setBlockStatus(d.is_blocked() ? UserData::BlockStatus::Blocked : UserData::BlockStatus::NotBlocked);
|
||||
peer->asUser()->setAbout(d.has_about() ? qs(d.vabout) : QString());
|
||||
user->setBlockStatus(d.is_blocked() ? UserData::BlockStatus::Blocked : UserData::BlockStatus::NotBlocked);
|
||||
user->setAbout(d.has_about() ? qs(d.vabout) : QString());
|
||||
user->setCommonChatsCount(d.vcommon_chats_count.v);
|
||||
|
||||
if (req) {
|
||||
QMap<PeerData*, mtpRequestId>::iterator i = _fullPeerRequests.find(peer);
|
||||
|
@ -422,15 +426,15 @@ void ApiWrap::requestBots(ChannelData *peer) {
|
|||
void ApiWrap::gotChat(PeerData *peer, const MTPmessages_Chats &result) {
|
||||
_peerRequests.remove(peer);
|
||||
|
||||
if (result.type() == mtpc_messages_chats) {
|
||||
const auto &v(result.c_messages_chats().vchats.c_vector().v);
|
||||
if (auto chats = Api::getChatsFromMessagesChats(result)) {
|
||||
auto &v = chats->c_vector().v;
|
||||
bool badVersion = false;
|
||||
if (peer->isChat()) {
|
||||
badVersion = (!v.isEmpty() && v.at(0).type() == mtpc_chat && v.at(0).c_chat().vversion.v < peer->asChat()->version);
|
||||
} else if (peer->isChannel()) {
|
||||
badVersion = (!v.isEmpty() && v.at(0).type() == mtpc_channel && v.at(0).c_chat().vversion.v < peer->asChannel()->version);
|
||||
}
|
||||
PeerData *chat = App::feedChats(result.c_messages_chats().vchats);
|
||||
auto chat = App::feedChats(*chats);
|
||||
if (chat == peer) {
|
||||
if (badVersion) {
|
||||
if (peer->isChat()) {
|
||||
|
@ -453,9 +457,8 @@ void ApiWrap::gotUser(PeerData *peer, const MTPVector<MTPUser> &result) {
|
|||
}
|
||||
|
||||
void ApiWrap::gotChats(const MTPmessages_Chats &result) {
|
||||
if (result.type() == mtpc_messages_chats) {
|
||||
auto &d = result.c_messages_chats();
|
||||
App::feedChats(d.vchats);
|
||||
if (auto chats = Api::getChatsFromMessagesChats(result)) {
|
||||
App::feedChats(*chats);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,18 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include "core/single_timer.h"
|
||||
|
||||
namespace Api {
|
||||
|
||||
inline const MTPVector<MTPChat> *getChatsFromMessagesChats(const MTPmessages_Chats &chats) {
|
||||
switch (chats.type()) {
|
||||
case mtpc_messages_chats: return &chats.c_messages_chats().vchats;
|
||||
case mtpc_messages_chatsSlice: return &chats.c_messages_chatsSlice().vchats;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace Api
|
||||
|
||||
class ApiWrap : public QObject, public RPCSender {
|
||||
Q_OBJECT
|
||||
|
||||
|
|
|
@ -1513,6 +1513,7 @@ namespace {
|
|||
return page;
|
||||
} break;
|
||||
case mtpc_webPagePending: return App::feedWebPage(webpage.c_webPagePending());
|
||||
case mtpc_webPageNotModified: LOG(("API Error: webPageNotModified is unexpected in feedWebPage().")); break;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -1255,9 +1255,8 @@ void RevokePublicLinkBox::paintChat(Painter &p, const ChatRow &row, bool selecte
|
|||
}
|
||||
|
||||
void RevokePublicLinkBox::getPublicDone(const MTPmessages_Chats &result) {
|
||||
if (result.type() == mtpc_messages_chats) {
|
||||
auto &chats = result.c_messages_chats().vchats;
|
||||
for_const (auto &chat, chats.c_vector().v) {
|
||||
if (auto chats = Api::getChatsFromMessagesChats(result)) {
|
||||
for_const (auto &chat, chats->c_vector().v) {
|
||||
if (auto peer = App::feedChat(chat)) {
|
||||
if (!peer->isChannel() || peer->userName().isEmpty()) continue;
|
||||
|
||||
|
|
|
@ -999,8 +999,8 @@ void shareGameScoreByHash(const QString &hash) {
|
|||
auto requestChannelIds = MTP_vector<MTPInputChannel>(1, MTP_inputChannel(MTP_int(channelId), MTP_long(channelAccessHash)));
|
||||
auto requestChannel = MTPchannels_GetChannels(requestChannelIds);
|
||||
MTP::send(requestChannel, rpcDone([channelId, resolveMessageAndShareScore](const MTPmessages_Chats &result) {
|
||||
if (result.type() == mtpc_messages_chats) {
|
||||
App::feedChats(result.c_messages_chats().vchats);
|
||||
if (auto chats = Api::getChatsFromMessagesChats(result)) {
|
||||
App::feedChats(*chats);
|
||||
}
|
||||
if (auto channel = App::channelLoaded(channelId)) {
|
||||
resolveMessageAndShareScore(channel);
|
||||
|
|
|
@ -393,18 +393,23 @@ public:
|
|||
|
||||
namespace internal {
|
||||
|
||||
template <typename FunctionType>
|
||||
struct lambda_type_helper;
|
||||
template <typename FunctionType>
|
||||
struct lambda_type_resolver;
|
||||
|
||||
template <typename Lambda, typename R, typename ...Args>
|
||||
struct lambda_type_helper<R(Lambda::*)(Args...) const> {
|
||||
using type = lambda<R(Args...)>;
|
||||
};
|
||||
template <typename Lambda, typename R, typename ...Args>
|
||||
struct lambda_type_resolver<R(Lambda::*)(Args...) const> {
|
||||
using type = lambda<R(Args...)>;
|
||||
};
|
||||
|
||||
template <typename FunctionType>
|
||||
struct lambda_type_helper {
|
||||
using type = typename lambda_type_resolver<decltype(&FunctionType::operator())>::type;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename FunctionType>
|
||||
using lambda_type = typename internal::lambda_type_helper<decltype(&FunctionType::operator())>::type;
|
||||
using lambda_type = typename internal::lambda_type_helper<FunctionType>::type;
|
||||
|
||||
// Guard lambda call by one or many QObject* weak pointers.
|
||||
|
||||
|
@ -489,6 +494,11 @@ struct lambda_guard_type_helper {
|
|||
template <typename ...PointersAndLambda>
|
||||
using lambda_guard_t = typename lambda_guard_type_helper<PointersAndLambda...>::type;
|
||||
|
||||
template <int N, typename Lambda>
|
||||
struct lambda_type_helper<lambda_guard<N, Lambda>> {
|
||||
using type = typename lambda_type_helper<Lambda>::type;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename ...PointersAndLambda>
|
||||
|
|
|
@ -190,12 +190,6 @@ bool History::updateSendActionNeedsAnimating(UserData *user, const MTPSendMessag
|
|||
if (action.type() == mtpc_sendMessageCancelAction) {
|
||||
unregSendAction(user);
|
||||
return false;
|
||||
} else if (action.type() == mtpc_sendMessageGameStopAction) {
|
||||
auto it = _sendActions.find(user);
|
||||
if (it != _sendActions.end() && it->type == Type::PlayGame) {
|
||||
unregSendAction(user);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ms = getms();
|
||||
|
@ -251,12 +245,6 @@ bool History::paintSendAction(Painter &p, int x, int y, int availableWidth, int
|
|||
availableWidth -= animationWidth;
|
||||
p.setPen(color);
|
||||
_sendActionText.drawElided(p, x, y, availableWidth);
|
||||
// App::histories().sendActionAnimationUpdated().notify({
|
||||
// this,
|
||||
// animationWidth,
|
||||
// st::normalFont->height,
|
||||
// false
|
||||
// });
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -393,8 +381,11 @@ void ChannelHistory::getRangeDifference() {
|
|||
void ChannelHistory::getRangeDifferenceNext(int32 pts) {
|
||||
if (!App::main() || _rangeDifferenceToId < _rangeDifferenceFromId) return;
|
||||
|
||||
int32 limit = _rangeDifferenceToId + 1 - _rangeDifferenceFromId;
|
||||
_rangeDifferenceRequestId = MTP::send(MTPupdates_GetChannelDifference(peer->asChannel()->inputChannel, MTP_channelMessagesFilter(MTP_flags(MTPDchannelMessagesFilter::Flags(0)), MTP_vector<MTPMessageRange>(1, MTP_messageRange(MTP_int(_rangeDifferenceFromId), MTP_int(_rangeDifferenceToId)))), MTP_int(pts), MTP_int(limit)), App::main()->rpcDone(&MainWidget::gotRangeDifference, peer->asChannel()));
|
||||
int limit = _rangeDifferenceToId + 1 - _rangeDifferenceFromId;
|
||||
|
||||
auto filter = MTP_channelMessagesFilter(MTP_flags(MTPDchannelMessagesFilter::Flags(0)), MTP_vector<MTPMessageRange>(1, MTP_messageRange(MTP_int(_rangeDifferenceFromId), MTP_int(_rangeDifferenceToId))));
|
||||
MTPupdates_GetChannelDifference::Flags flags = MTPupdates_GetChannelDifference::Flag::f_force;
|
||||
_rangeDifferenceRequestId = MTP::send(MTPupdates_GetChannelDifference(MTP_flags(flags), peer->asChannel()->inputChannel, filter, MTP_int(pts), MTP_int(limit)), App::main()->rpcDone(&MainWidget::gotRangeDifference, peer->asChannel()));
|
||||
}
|
||||
|
||||
HistoryJoined *ChannelHistory::insertJoinedMessage(bool unread) {
|
||||
|
@ -788,6 +779,7 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
|
|||
case mtpc_webPage:
|
||||
case mtpc_webPageEmpty:
|
||||
case mtpc_webPagePending: break;
|
||||
case mtpc_webPageNotModified:
|
||||
default: badMedia = 1; break;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -83,10 +83,10 @@ public:
|
|||
}
|
||||
|
||||
struct SendActionAnimationUpdate {
|
||||
History *history = nullptr;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
bool textUpdated = 0;
|
||||
History *history;
|
||||
int width;
|
||||
int height;
|
||||
bool textUpdated;
|
||||
};
|
||||
base::Observable<SendActionAnimationUpdate> &sendActionAnimationUpdated() {
|
||||
return _sendActionAnimationUpdated;
|
||||
|
|
|
@ -687,6 +687,7 @@ void HistoryMessage::initMedia(const MTPMessageMedia *media) {
|
|||
case mtpc_webPage: {
|
||||
_media.reset(new HistoryWebPage(this, App::feedWebPage(d.c_webPage())));
|
||||
} break;
|
||||
case mtpc_webPageNotModified: LOG(("API Error: webPageNotModified is unexpected in message media.")); break;
|
||||
}
|
||||
} break;
|
||||
case mtpc_messageMediaGame: {
|
||||
|
|
|
@ -39,7 +39,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "history/history_service_layout.h"
|
||||
#include "history/history_media_types.h"
|
||||
#include "history/history_drag_area.h"
|
||||
#include "profile/profile_members_widget.h"
|
||||
#include "profile/profile_block_group_members.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "stickers/emoji_pan.h"
|
||||
#include "lang.h"
|
||||
|
@ -6266,7 +6266,7 @@ void HistoryWidget::setMembersShowAreaActive(bool active) {
|
|||
void HistoryWidget::onMembersDropdownShow() {
|
||||
if (!_membersDropdown) {
|
||||
_membersDropdown.create(this, st::membersInnerDropdown);
|
||||
_membersDropdown->setOwnedWidget(new Profile::MembersWidget(_membersDropdown, _peer, Profile::MembersWidget::TitleVisibility::Hidden));
|
||||
_membersDropdown->setOwnedWidget(new Profile::GroupMembersWidget(_membersDropdown, _peer, Profile::GroupMembersWidget::TitleVisibility::Hidden));
|
||||
_membersDropdown->resizeToWidth(st::membersInnerWidth);
|
||||
|
||||
_membersDropdown->setMaxHeight(countMembersDropdownHeightMax());
|
||||
|
|
|
@ -3291,12 +3291,12 @@ void MainWidget::gotState(const MTPupdates_State &state) {
|
|||
updateOnline();
|
||||
}
|
||||
|
||||
void MainWidget::gotDifference(const MTPupdates_Difference &diff) {
|
||||
void MainWidget::gotDifference(const MTPupdates_Difference &difference) {
|
||||
_failDifferenceTimeout = 1;
|
||||
|
||||
switch (diff.type()) {
|
||||
switch (difference.type()) {
|
||||
case mtpc_updates_differenceEmpty: {
|
||||
const auto &d(diff.c_updates_differenceEmpty());
|
||||
auto &d = difference.c_updates_differenceEmpty();
|
||||
updSetState(_ptsWaiter.current(), d.vdate.v, updQts, d.vseq.v);
|
||||
|
||||
_lastUpdateTime = getms(true);
|
||||
|
@ -3305,10 +3305,10 @@ void MainWidget::gotDifference(const MTPupdates_Difference &diff) {
|
|||
_ptsWaiter.setRequesting(false);
|
||||
} break;
|
||||
case mtpc_updates_differenceSlice: {
|
||||
const auto &d(diff.c_updates_differenceSlice());
|
||||
auto &d = difference.c_updates_differenceSlice();
|
||||
feedDifference(d.vusers, d.vchats, d.vnew_messages, d.vother_updates);
|
||||
|
||||
const auto &s(d.vintermediate_state.c_updates_state());
|
||||
auto &s = d.vintermediate_state.c_updates_state();
|
||||
updSetState(s.vpts.v, s.vdate.v, s.vqts.v, s.vseq.v);
|
||||
|
||||
_ptsWaiter.setRequesting(false);
|
||||
|
@ -3317,11 +3317,15 @@ void MainWidget::gotDifference(const MTPupdates_Difference &diff) {
|
|||
getDifference();
|
||||
} break;
|
||||
case mtpc_updates_difference: {
|
||||
const auto &d(diff.c_updates_difference());
|
||||
auto &d = difference.c_updates_difference();
|
||||
feedDifference(d.vusers, d.vchats, d.vnew_messages, d.vother_updates);
|
||||
|
||||
gotState(d.vstate);
|
||||
} break;
|
||||
case mtpc_updates_differenceTooLong: {
|
||||
auto &d = difference.c_updates_differenceTooLong();
|
||||
LOG(("API Error: updates.differenceTooLong is not supported by Telegram Desktop!"));
|
||||
} break;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -3444,7 +3448,7 @@ void MainWidget::onGetDifferenceTimeByPts() {
|
|||
wait = wait ? qMin(wait, i.value() - now) : (i.value() - now);
|
||||
++i;
|
||||
} else {
|
||||
getChannelDifference(i.key(), GetChannelDifferenceFromPtsGap);
|
||||
getChannelDifference(i.key(), ChannelDifferenceRequest::PtsGapOrShortPoll);
|
||||
i = _channelGetDifferenceTimeByPts.erase(i);
|
||||
}
|
||||
}
|
||||
|
@ -3473,7 +3477,7 @@ void MainWidget::onGetDifferenceTimeAfterFail() {
|
|||
wait = wait ? qMin(wait, i.value() - now) : (i.value() - now);
|
||||
++i;
|
||||
} else {
|
||||
getChannelDifference(i.key(), GetChannelDifferenceFromFail);
|
||||
getChannelDifference(i.key(), ChannelDifferenceRequest::AfterFail);
|
||||
i = _channelGetDifferenceTimeAfterFail.erase(i);
|
||||
}
|
||||
}
|
||||
|
@ -3498,26 +3502,34 @@ void MainWidget::getDifference() {
|
|||
_getDifferenceTimeAfterFail = 0;
|
||||
|
||||
_ptsWaiter.setRequesting(true);
|
||||
MTP::send(MTPupdates_GetDifference(MTP_int(_ptsWaiter.current()), MTP_int(updDate), MTP_int(updQts)), rpcDone(&MainWidget::gotDifference), rpcFail(&MainWidget::failDifference));
|
||||
|
||||
MTPupdates_GetDifference::Flags flags = 0;
|
||||
MTP::send(MTPupdates_GetDifference(MTP_flags(flags), MTP_int(_ptsWaiter.current()), MTPint(), MTP_int(updDate), MTP_int(updQts)), rpcDone(&MainWidget::gotDifference), rpcFail(&MainWidget::failDifference));
|
||||
}
|
||||
|
||||
void MainWidget::getChannelDifference(ChannelData *channel, GetChannelDifferenceFrom from) {
|
||||
void MainWidget::getChannelDifference(ChannelData *channel, ChannelDifferenceRequest from) {
|
||||
if (this != App::main() || !channel) return;
|
||||
|
||||
if (from != GetChannelDifferenceFromPtsGap) {
|
||||
if (from != ChannelDifferenceRequest::PtsGapOrShortPoll) {
|
||||
_channelGetDifferenceTimeByPts.remove(channel);
|
||||
}
|
||||
|
||||
if (!channel->ptsInited() || channel->ptsRequesting()) return;
|
||||
|
||||
if (from != GetChannelDifferenceFromFail) {
|
||||
if (from != ChannelDifferenceRequest::AfterFail) {
|
||||
_channelGetDifferenceTimeAfterFail.remove(channel);
|
||||
}
|
||||
|
||||
channel->ptsSetRequesting(true);
|
||||
|
||||
auto filter = MTP_channelMessagesFilterEmpty();
|
||||
MTP::send(MTPupdates_GetChannelDifference(channel->inputChannel, filter, MTP_int(channel->pts()), MTP_int(MTPChannelGetDifferenceLimit)), rpcDone(&MainWidget::gotChannelDifference, channel), rpcFail(&MainWidget::failChannelDifference, channel));
|
||||
MTPupdates_GetChannelDifference::Flags flags = MTPupdates_GetChannelDifference::Flag::f_force;
|
||||
if (from != ChannelDifferenceRequest::PtsGapOrShortPoll) {
|
||||
if (!channel->ptsWaitingForSkipped()) {
|
||||
flags = 0; // No force flag when requesting for short poll.
|
||||
}
|
||||
}
|
||||
MTP::send(MTPupdates_GetChannelDifference(MTP_flags(flags), channel->inputChannel, filter, MTP_int(channel->pts()), MTP_int(MTPChannelGetDifferenceLimit)), rpcDone(&MainWidget::gotChannelDifference, channel), rpcFail(&MainWidget::failChannelDifference, channel));
|
||||
}
|
||||
|
||||
void MainWidget::mtpPing() {
|
||||
|
@ -4897,6 +4909,29 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
|||
}
|
||||
} break;
|
||||
|
||||
case mtpc_updateChannelWebPage: {
|
||||
auto &d = update.c_updateChannelWebPage();
|
||||
auto channel = App::channelLoaded(d.vchannel_id.v);
|
||||
|
||||
if (channel && !_handlingChannelDifference) {
|
||||
if (channel->ptsRequesting()) { // skip global updates while getting channel difference
|
||||
return;
|
||||
} else if (!channel->ptsUpdated(d.vpts.v, d.vpts_count.v, update)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// update before applying skipped
|
||||
App::feedWebPage(d.vwebpage);
|
||||
_history->updatePreview();
|
||||
webPagesOrGamesUpdate();
|
||||
|
||||
if (channel && !_handlingChannelDifference) {
|
||||
channel->ptsApplySkippedUpdates();
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_updateDeleteChannelMessages: {
|
||||
auto &d = update.c_updateDeleteChannelMessages();
|
||||
auto channel = App::channelLoaded(d.vchannel_id.v);
|
||||
|
|
|
@ -535,12 +535,12 @@ private:
|
|||
|
||||
SingleTimer _updateMutedTimer;
|
||||
|
||||
enum GetChannelDifferenceFrom {
|
||||
GetChannelDifferenceFromUnknown,
|
||||
GetChannelDifferenceFromPtsGap,
|
||||
GetChannelDifferenceFromFail,
|
||||
enum class ChannelDifferenceRequest {
|
||||
Unknown,
|
||||
PtsGapOrShortPoll,
|
||||
AfterFail,
|
||||
};
|
||||
void getChannelDifference(ChannelData *channel, GetChannelDifferenceFrom from = GetChannelDifferenceFromUnknown);
|
||||
void getChannelDifference(ChannelData *channel, ChannelDifferenceRequest from = ChannelDifferenceRequest::Unknown);
|
||||
void gotDifference(const MTPupdates_Difference &diff);
|
||||
bool failDifference(const RPCError &e);
|
||||
void feedDifference(const MTPVector<MTPUser> &users, const MTPVector<MTPChat> &chats, const MTPVector<MTPMessage> &msgs, const MTPVector<MTPUpdate> &other);
|
||||
|
|
|
@ -300,7 +300,7 @@ inputReportReasonViolence#1e22c78d = ReportReason;
|
|||
inputReportReasonPornography#2e59d922 = ReportReason;
|
||||
inputReportReasonOther#e1746d0a text:string = ReportReason;
|
||||
|
||||
userFull#5932fc03 flags:# blocked:flags.0?true user:User about:flags.1?string link:contacts.Link profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo = UserFull;
|
||||
userFull#f220f3f flags:# blocked:flags.0?true user:User about:flags.1?string link:contacts.Link profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo common_chats_count:int = UserFull;
|
||||
|
||||
contact#f911c994 user_id:int mutual:Bool = Contact;
|
||||
|
||||
|
@ -328,6 +328,7 @@ messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<C
|
|||
messages.channelMessages#99262e37 flags:# pts:int count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
|
||||
messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
|
||||
messages.chatsSlice#78f69146 count:int chats:Vector<Chat> users:Vector<User> = messages.Chats;
|
||||
|
||||
messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
|
||||
|
||||
|
@ -398,12 +399,14 @@ updateReadFeaturedStickers#571d2742 = Update;
|
|||
updateRecentStickers#9a422c20 = Update;
|
||||
updateConfig#a229dd06 = Update;
|
||||
updatePtsChanged#3354678f = Update;
|
||||
updateChannelWebPage#40771900 channel_id:int webpage:WebPage pts:int pts_count:int = Update;
|
||||
|
||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||
|
||||
updates.differenceEmpty#5d75a138 date:int seq:int = updates.Difference;
|
||||
updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> state:updates.State = updates.Difference;
|
||||
updates.differenceSlice#a8fb1981 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> intermediate_state:updates.State = updates.Difference;
|
||||
updates.differenceTooLong#4afe8f6d pts:int = updates.Difference;
|
||||
|
||||
updatesTooLong#e317af7e = Updates;
|
||||
updateShortMessage#914fbf11 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int user_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int entities:flags.7?Vector<MessageEntity> = Updates;
|
||||
|
@ -480,7 +483,6 @@ sendMessageUploadDocumentAction#aa0cd9e4 progress:int = SendMessageAction;
|
|||
sendMessageGeoLocationAction#176f8ba1 = SendMessageAction;
|
||||
sendMessageChooseContactAction#628cbc6f = SendMessageAction;
|
||||
sendMessageGamePlayAction#dd6a8f48 = SendMessageAction;
|
||||
sendMessageGameStopAction#15c2c99a = SendMessageAction;
|
||||
|
||||
contacts.found#1aa1f784 results:Vector<Peer> chats:Vector<Chat> users:Vector<User> = contacts.Found;
|
||||
|
||||
|
@ -535,7 +537,8 @@ contactLinkContact#d502c2d0 = ContactLink;
|
|||
|
||||
webPageEmpty#eb1477e8 id:long = WebPage;
|
||||
webPagePending#c586da1c id:long date:int = WebPage;
|
||||
webPage#ca820ed7 flags:# id:long url:string display_url:string type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document = WebPage;
|
||||
webPage#5f07b4bc flags:# id:long url:string display_url:string hash:int type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document cached_page:flags.10?Page = WebPage;
|
||||
webPageNotModified#85849473 = WebPage;
|
||||
|
||||
authorization#7bf2e6f6 hash:long flags:int device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
|
||||
|
||||
|
@ -667,7 +670,7 @@ botInlineMessageMediaContact#35edb4d4 flags:# phone_number:string first_name:str
|
|||
botInlineResult#9bebaeb9 flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb_url:flags.4?string content_url:flags.5?string content_type:flags.5?string w:flags.6?int h:flags.6?int duration:flags.7?int send_message:BotInlineMessage = BotInlineResult;
|
||||
botInlineMediaResult#17db940b flags:# id:string type:string photo:flags.0?Photo document:flags.1?Document title:flags.2?string description:flags.3?string send_message:BotInlineMessage = BotInlineResult;
|
||||
|
||||
messages.botResults#256709a6 flags:# gallery:flags.0?true query_id:long next_offset:flags.1?string switch_pm:flags.2?InlineBotSwitchPM results:Vector<BotInlineResult> = messages.BotResults;
|
||||
messages.botResults#ccd3563d flags:# gallery:flags.0?true query_id:long next_offset:flags.1?string switch_pm:flags.2?InlineBotSwitchPM results:Vector<BotInlineResult> cache_time:int = messages.BotResults;
|
||||
|
||||
exportedMessageLink#1f486803 link:string = ExportedMessageLink;
|
||||
|
||||
|
@ -682,7 +685,7 @@ auth.sentCodeTypeSms#c000bba2 length:int = auth.SentCodeType;
|
|||
auth.sentCodeTypeCall#5353e5a7 length:int = auth.SentCodeType;
|
||||
auth.sentCodeTypeFlashCall#ab03c6d9 pattern:string = auth.SentCodeType;
|
||||
|
||||
messages.botCallbackAnswer#b10df1fb flags:# alert:flags.1?true has_url:flags.3?true message:flags.0?string url:flags.2?string = messages.BotCallbackAnswer;
|
||||
messages.botCallbackAnswer#36585ea4 flags:# alert:flags.1?true has_url:flags.3?true message:flags.0?string url:flags.2?string cache_time:int = messages.BotCallbackAnswer;
|
||||
|
||||
messages.messageEditData#26b5dde6 flags:# caption:flags.0?true = messages.MessageEditData;
|
||||
|
||||
|
@ -736,6 +739,42 @@ highScore#58fffcd0 pos:int user_id:int score:int = HighScore;
|
|||
|
||||
messages.highScores#9a3bfd99 scores:Vector<HighScore> users:Vector<User> = messages.HighScores;
|
||||
|
||||
textEmpty#dc3d824f = RichText;
|
||||
textPlain#744694e0 text:string = RichText;
|
||||
textBold#6724abc4 text:RichText = RichText;
|
||||
textItalic#d912a59c text:RichText = RichText;
|
||||
textUnderline#c12622c4 text:RichText = RichText;
|
||||
textStrike#9bf8bb95 text:RichText = RichText;
|
||||
textFixed#6c3f19b9 text:RichText = RichText;
|
||||
textUrl#3c2884c1 text:RichText url:string webpage_id:long = RichText;
|
||||
textEmail#de5a0dd6 text:RichText email:string = RichText;
|
||||
textConcat#7e6260d7 texts:Vector<RichText> = RichText;
|
||||
|
||||
pageBlockTitle#70abc3fd text:RichText = PageBlock;
|
||||
pageBlockSubtitle#8ffa9a1f text:RichText = PageBlock;
|
||||
pageBlockAuthorDate#3d5b64f2 author:string published_date:int = PageBlock;
|
||||
pageBlockHeader#bfd064ec text:RichText = PageBlock;
|
||||
pageBlockSubheader#f12bb6e1 text:RichText = PageBlock;
|
||||
pageBlockParagraph#467a0766 text:RichText = PageBlock;
|
||||
pageBlockPreformatted#c070d93e text:RichText language:string = PageBlock;
|
||||
pageBlockFooter#48870999 text:RichText = PageBlock;
|
||||
pageBlockDivider#db20b188 = PageBlock;
|
||||
pageBlockList#3a58c7f4 ordered:Bool items:Vector<RichText> = PageBlock;
|
||||
pageBlockBlockquote#263d7c26 text:RichText caption:RichText = PageBlock;
|
||||
pageBlockPullquote#4f4456d3 text:RichText caption:RichText = PageBlock;
|
||||
pageBlockPhoto#e9c69982 photo_id:long caption:RichText = PageBlock;
|
||||
pageBlockVideo#d9d71866 flags:# autoplay:flags.1?true loop:flags.2?true video_id:long caption:RichText = PageBlock;
|
||||
pageBlockCover#39f23300 cover:PageBlock = PageBlock;
|
||||
pageBlockEmbed#36b0816 url:string w:int h:int caption:RichText = PageBlock;
|
||||
pageBlockEmbedPost#7ff81db7 flags:# author:string date:int caption:RichText url:string webpage_id:long text:flags.1?RichText medias:flags.2?Vector<EmbedPostMedia> author_photo_id:flags.3?long = PageBlock;
|
||||
pageBlockSlideshow#130c8963 items:Vector<PageBlock> caption:RichText = PageBlock;
|
||||
|
||||
embedPostPhoto#e31ee77 photo_id:long = EmbedPostMedia;
|
||||
embedPostVideo#a07f2d66 video_id:long = EmbedPostMedia;
|
||||
|
||||
pagePart#8dee6c44 blocks:Vector<PageBlock> photos:Vector<Photo> videos:Vector<Document> = Page;
|
||||
pageFull#d7a19d69 blocks:Vector<PageBlock> photos:Vector<Photo> videos:Vector<Document> = Page;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
|
@ -867,7 +906,7 @@ messages.getMessageEditData#fda68d36 peer:InputPeer id:int = messages.MessageEdi
|
|||
messages.editMessage#ce91e4ca flags:# no_webpage:flags.1?true peer:InputPeer id:int message:flags.11?string reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
|
||||
messages.editInlineBotMessage#130c2c85 flags:# no_webpage:flags.1?true id:InputBotInlineMessageID message:flags.11?string reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Bool;
|
||||
messages.getBotCallbackAnswer#810a9fec flags:# game:flags.1?true peer:InputPeer msg_id:int data:flags.0?bytes = messages.BotCallbackAnswer;
|
||||
messages.setBotCallbackAnswer#c927d44b flags:# alert:flags.1?true query_id:long message:flags.0?string url:flags.2?string = Bool;
|
||||
messages.setBotCallbackAnswer#d58f130a flags:# alert:flags.1?true query_id:long message:flags.0?string url:flags.2?string cache_time:int = Bool;
|
||||
messages.getPeerDialogs#2d9776b9 peers:Vector<InputPeer> = messages.PeerDialogs;
|
||||
messages.saveDraft#bc39e14b flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int peer:InputPeer message:string entities:flags.3?Vector<MessageEntity> = Bool;
|
||||
messages.getAllDrafts#6a3f8d65 = Updates;
|
||||
|
@ -883,10 +922,13 @@ messages.setGameScore#8ef8ecc0 flags:# edit_message:flags.0?true peer:InputPeer
|
|||
messages.setInlineGameScore#15ad9f64 flags:# edit_message:flags.0?true id:InputBotInlineMessageID user_id:InputUser score:int = Bool;
|
||||
messages.getGameHighScores#e822649d peer:InputPeer id:int user_id:InputUser = messages.HighScores;
|
||||
messages.getInlineGameHighScores#f635e1b id:InputBotInlineMessageID user_id:InputUser = messages.HighScores;
|
||||
messages.getCommonChats#d0a48c4 user_id:InputUser max_id:int limit:int = messages.Chats;
|
||||
messages.getAllChats#eba80ff0 except_ids:Vector<int> = messages.Chats;
|
||||
messages.getWebPage#61203e2 id:long hash:int = WebPage;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#a041495 pts:int date:int qts:int = updates.Difference;
|
||||
updates.getChannelDifference#bb32d7c0 channel:InputChannel filter:ChannelMessagesFilter pts:int limit:int = updates.ChannelDifference;
|
||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||
updates.getChannelDifference#3173d78 flags:# force:flags.0?true channel:InputChannel filter:ChannelMessagesFilter pts:int limit:int = updates.ChannelDifference;
|
||||
|
||||
photos.updateProfilePhoto#f0bb5152 id:InputPhoto = UserProfilePhoto;
|
||||
photos.uploadProfilePhoto#4f32c098 file:InputFile = photos.Photo;
|
||||
|
@ -905,6 +947,7 @@ help.getInviteText#4d392343 = help.InviteText;
|
|||
help.getSupport#9cdf08cd = help.Support;
|
||||
help.getAppChangelog#b921197a = help.AppChangelog;
|
||||
help.getTermsOfService#350170f3 = help.TermsOfService;
|
||||
help.setBotUpdatesStatus#ec22cfcd pending_updates_count:int message:string = Bool;
|
||||
|
||||
channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
|
||||
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
|
||||
|
@ -934,4 +977,4 @@ channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
|
|||
channels.updatePinnedMessage#a72ded52 flags:# silent:flags.0?true channel:InputChannel id:int = Updates;
|
||||
channels.getAdminedPublicChannels#8d8d82d7 = messages.Chats;
|
||||
|
||||
// LAYER 57
|
||||
// LAYER 59
|
||||
|
|
|
@ -2062,6 +2062,7 @@ void _serialize_userFull(MTPStringLogger &to, int32 stage, int32 lev, Types &typ
|
|||
case 5: to.add(" profile_photo: "); ++stages.back(); if (flag & MTPDuserFull::Flag::f_profile_photo) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
case 6: to.add(" notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 7: to.add(" bot_info: "); ++stages.back(); if (flag & MTPDuserFull::Flag::f_bot_info) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
|
||||
case 8: to.add(" common_chats_count: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
@ -2294,6 +2295,21 @@ void _serialize_messages_chats(MTPStringLogger &to, int32 stage, int32 lev, Type
|
|||
}
|
||||
}
|
||||
|
||||
void _serialize_messages_chatsSlice(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messages_chatsSlice");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" count: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" chats: "); ++stages.back(); types.push_back(00); 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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_messages_chatFull(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
|
@ -3110,6 +3126,22 @@ void _serialize_updatePtsChanged(MTPStringLogger &to, int32 stage, int32 lev, Ty
|
|||
to.add("{ updatePtsChanged }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
}
|
||||
|
||||
void _serialize_updateChannelWebPage(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ updateChannelWebPage");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" channel_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" webpage: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" pts_count: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_updates_state(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
|
@ -3177,6 +3209,19 @@ void _serialize_updates_differenceSlice(MTPStringLogger &to, int32 stage, int32
|
|||
}
|
||||
}
|
||||
|
||||
void _serialize_updates_differenceTooLong(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ updates_differenceTooLong");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_updatesTooLong(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
to.add("{ updatesTooLong }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
}
|
||||
|
@ -3900,10 +3945,6 @@ void _serialize_sendMessageGamePlayAction(MTPStringLogger &to, int32 stage, int3
|
|||
to.add("{ sendMessageGamePlayAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
}
|
||||
|
||||
void _serialize_sendMessageGameStopAction(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
to.add("{ sendMessageGameStopAction }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
}
|
||||
|
||||
void _serialize_contacts_found(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
|
@ -4270,22 +4311,28 @@ void _serialize_webPage(MTPStringLogger &to, int32 stage, int32 lev, Types &type
|
|||
case 1: to.add(" id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" url: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" display_url: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" type: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_type) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||
case 5: to.add(" site_name: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_site_name) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
|
||||
case 6: to.add(" title: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_title) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
case 7: to.add(" description: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_description) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
|
||||
case 8: to.add(" photo: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_photo) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
|
||||
case 9: to.add(" embed_url: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_embed_url) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
|
||||
case 10: to.add(" embed_type: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_embed_type) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
|
||||
case 11: to.add(" embed_width: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_embed_width) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
|
||||
case 12: to.add(" embed_height: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_embed_height) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
|
||||
case 13: to.add(" duration: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_duration) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
|
||||
case 14: to.add(" author: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_author) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 8 IN FIELD flags ]"); } break;
|
||||
case 15: to.add(" document: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_document) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break;
|
||||
case 4: to.add(" hash: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" type: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_type) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||
case 6: to.add(" site_name: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_site_name) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
|
||||
case 7: to.add(" title: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_title) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
case 8: to.add(" description: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_description) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
|
||||
case 9: to.add(" photo: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_photo) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
|
||||
case 10: to.add(" embed_url: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_embed_url) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
|
||||
case 11: to.add(" embed_type: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_embed_type) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
|
||||
case 12: to.add(" embed_width: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_embed_width) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
|
||||
case 13: to.add(" embed_height: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_embed_height) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
|
||||
case 14: to.add(" duration: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_duration) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
|
||||
case 15: to.add(" author: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_author) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 8 IN FIELD flags ]"); } break;
|
||||
case 16: to.add(" document: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_document) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break;
|
||||
case 17: to.add(" cached_page: "); ++stages.back(); if (flag & MTPDwebPage::Flag::f_cached_page) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 10 IN FIELD flags ]"); } break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_webPageNotModified(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
to.add("{ webPageNotModified }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
}
|
||||
|
||||
void _serialize_authorization(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
|
@ -5647,6 +5694,7 @@ void _serialize_messages_botResults(MTPStringLogger &to, int32 stage, int32 lev,
|
|||
case 3: to.add(" next_offset: "); ++stages.back(); if (flag & MTPDmessages_botResults::Flag::f_next_offset) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
|
||||
case 4: to.add(" switch_pm: "); ++stages.back(); if (flag & MTPDmessages_botResults::Flag::f_switch_pm) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
case 5: to.add(" results: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 6: to.add(" cache_time: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
@ -5762,6 +5810,7 @@ void _serialize_messages_botCallbackAnswer(MTPStringLogger &to, int32 stage, int
|
|||
case 2: to.add(" has_url: "); ++stages.back(); if (flag & MTPDmessages_botCallbackAnswer::Flag::f_has_url) { to.add("YES [ BY BIT 3 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
|
||||
case 3: to.add(" message: "); ++stages.back(); if (flag & MTPDmessages_botCallbackAnswer::Flag::f_message) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||
case 4: to.add(" url: "); ++stages.back(); if (flag & MTPDmessages_botCallbackAnswer::Flag::f_url) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
case 5: to.add(" cache_time: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
@ -6137,6 +6186,437 @@ void _serialize_messages_highScores(MTPStringLogger &to, int32 stage, int32 lev,
|
|||
}
|
||||
}
|
||||
|
||||
void _serialize_textEmpty(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
to.add("{ textEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
}
|
||||
|
||||
void _serialize_textPlain(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ textPlain");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_textBold(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ textBold");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_textItalic(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ textItalic");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_textUnderline(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ textUnderline");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_textStrike(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ textStrike");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_textFixed(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ textFixed");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_textUrl(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ textUrl");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" url: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" webpage_id: "); ++stages.back(); types.push_back(mtpc_long+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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_textEmail(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ textEmail");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" email: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_textConcat(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ textConcat");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" texts: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockTitle(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockTitle");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockSubtitle(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockSubtitle");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockAuthorDate(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockAuthorDate");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" author: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" published_date: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockHeader(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockHeader");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockSubheader(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockSubheader");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockParagraph(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockParagraph");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockPreformatted(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockPreformatted");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" language: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockFooter(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockFooter");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockDivider(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
to.add("{ pageBlockDivider }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
}
|
||||
|
||||
void _serialize_pageBlockList(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockList");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" ordered: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" items: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockBlockquote(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockBlockquote");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" caption: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockPullquote(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockPullquote");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" caption: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockPhoto(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockPhoto");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" photo_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" caption: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockVideo(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
MTPDpageBlockVideo::Flags flag(iflag);
|
||||
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockVideo");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" autoplay: "); ++stages.back(); if (flag & MTPDpageBlockVideo::Flag::f_autoplay) { to.add("YES [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
|
||||
case 2: to.add(" loop: "); ++stages.back(); if (flag & MTPDpageBlockVideo::Flag::f_loop) { to.add("YES [ BY BIT 2 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
case 3: to.add(" video_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" caption: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockCover(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockCover");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" cover: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockEmbed(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockEmbed");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" url: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" w: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" h: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" caption: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockEmbedPost(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
MTPDpageBlockEmbedPost::Flags flag(iflag);
|
||||
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockEmbedPost");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" author: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" caption: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" url: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" webpage_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 6: to.add(" text: "); ++stages.back(); if (flag & MTPDpageBlockEmbedPost::Flag::f_text) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
|
||||
case 7: to.add(" medias: "); ++stages.back(); if (flag & MTPDpageBlockEmbedPost::Flag::f_medias) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
case 8: to.add(" author_photo_id: "); ++stages.back(); if (flag & MTPDpageBlockEmbedPost::Flag::f_author_photo_id) { types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageBlockSlideshow(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageBlockSlideshow");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" items: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" caption: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_embedPostPhoto(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ embedPostPhoto");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" photo_id: "); ++stages.back(); types.push_back(mtpc_long+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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_embedPostVideo(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ embedPostVideo");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" video_id: "); ++stages.back(); types.push_back(mtpc_long+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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pagePart(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pagePart");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" blocks: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" photos: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" videos: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_pageFull(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ pageFull");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" blocks: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" photos: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" videos: "); ++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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_req_pq(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
|
@ -6747,6 +7227,7 @@ void _serialize_messages_setBotCallbackAnswer(MTPStringLogger &to, int32 stage,
|
|||
case 2: to.add(" query_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" message: "); ++stages.back(); if (flag & MTPmessages_setBotCallbackAnswer::Flag::f_message) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||
case 4: to.add(" url: "); ++stages.back(); if (flag & MTPmessages_setBotCallbackAnswer::Flag::f_url) { types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
case 5: to.add(" cache_time: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
@ -6881,6 +7362,20 @@ void _serialize_help_saveAppLog(MTPStringLogger &to, int32 stage, int32 lev, Typ
|
|||
}
|
||||
}
|
||||
|
||||
void _serialize_help_setBotUpdatesStatus(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ help_setBotUpdatesStatus");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" pending_updates_count: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_channels_readHistory(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
|
@ -8175,6 +8670,34 @@ void _serialize_messages_getChats(MTPStringLogger &to, int32 stage, int32 lev, T
|
|||
}
|
||||
}
|
||||
|
||||
void _serialize_messages_getCommonChats(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messages_getCommonChats");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" user_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_messages_getAllChats(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messages_getAllChats");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" except_ids: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_int+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;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_channels_getChannels(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
|
@ -8637,11 +9160,27 @@ void _serialize_messages_getInlineGameHighScores(MTPStringLogger &to, int32 stag
|
|||
}
|
||||
}
|
||||
|
||||
void _serialize_messages_getWebPage(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messages_getWebPage");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" hash: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_updates_getState(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
to.add("{ updates_getState }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
}
|
||||
|
||||
void _serialize_updates_getDifference(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
MTPupdates_getDifference::Flags flag(iflag);
|
||||
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
|
@ -8649,14 +9188,18 @@ void _serialize_updates_getDifference(MTPStringLogger &to, int32 stage, int32 le
|
|||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" qts: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" pts_total_limit: "); ++stages.back(); if (flag & MTPupdates_getDifference::Flag::f_pts_total_limit) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||
case 3: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" qts: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void _serialize_updates_getChannelDifference(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {
|
||||
MTPupdates_getChannelDifference::Flags flag(iflag);
|
||||
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
|
@ -8664,10 +9207,12 @@ void _serialize_updates_getChannelDifference(MTPStringLogger &to, int32 stage, i
|
|||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" channel: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" filter: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int+0); 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+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" force: "); ++stages.back(); if (flag & MTPupdates_getChannelDifference::Flag::f_force) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||
case 2: to.add(" channel: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" filter: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
}
|
||||
|
@ -9031,6 +9576,7 @@ namespace {
|
|||
_serializers.insert(mtpc_messages_messagesSlice, _serialize_messages_messagesSlice);
|
||||
_serializers.insert(mtpc_messages_channelMessages, _serialize_messages_channelMessages);
|
||||
_serializers.insert(mtpc_messages_chats, _serialize_messages_chats);
|
||||
_serializers.insert(mtpc_messages_chatsSlice, _serialize_messages_chatsSlice);
|
||||
_serializers.insert(mtpc_messages_chatFull, _serialize_messages_chatFull);
|
||||
_serializers.insert(mtpc_messages_affectedHistory, _serialize_messages_affectedHistory);
|
||||
_serializers.insert(mtpc_inputMessagesFilterEmpty, _serialize_inputMessagesFilterEmpty);
|
||||
|
@ -9097,10 +9643,12 @@ namespace {
|
|||
_serializers.insert(mtpc_updateRecentStickers, _serialize_updateRecentStickers);
|
||||
_serializers.insert(mtpc_updateConfig, _serialize_updateConfig);
|
||||
_serializers.insert(mtpc_updatePtsChanged, _serialize_updatePtsChanged);
|
||||
_serializers.insert(mtpc_updateChannelWebPage, _serialize_updateChannelWebPage);
|
||||
_serializers.insert(mtpc_updates_state, _serialize_updates_state);
|
||||
_serializers.insert(mtpc_updates_differenceEmpty, _serialize_updates_differenceEmpty);
|
||||
_serializers.insert(mtpc_updates_difference, _serialize_updates_difference);
|
||||
_serializers.insert(mtpc_updates_differenceSlice, _serialize_updates_differenceSlice);
|
||||
_serializers.insert(mtpc_updates_differenceTooLong, _serialize_updates_differenceTooLong);
|
||||
_serializers.insert(mtpc_updatesTooLong, _serialize_updatesTooLong);
|
||||
_serializers.insert(mtpc_updateShortMessage, _serialize_updateShortMessage);
|
||||
_serializers.insert(mtpc_updateShortChatMessage, _serialize_updateShortChatMessage);
|
||||
|
@ -9156,7 +9704,6 @@ namespace {
|
|||
_serializers.insert(mtpc_sendMessageGeoLocationAction, _serialize_sendMessageGeoLocationAction);
|
||||
_serializers.insert(mtpc_sendMessageChooseContactAction, _serialize_sendMessageChooseContactAction);
|
||||
_serializers.insert(mtpc_sendMessageGamePlayAction, _serialize_sendMessageGamePlayAction);
|
||||
_serializers.insert(mtpc_sendMessageGameStopAction, _serialize_sendMessageGameStopAction);
|
||||
_serializers.insert(mtpc_contacts_found, _serialize_contacts_found);
|
||||
_serializers.insert(mtpc_inputPrivacyKeyStatusTimestamp, _serialize_inputPrivacyKeyStatusTimestamp);
|
||||
_serializers.insert(mtpc_inputPrivacyKeyChatInvite, _serialize_inputPrivacyKeyChatInvite);
|
||||
|
@ -9197,6 +9744,7 @@ namespace {
|
|||
_serializers.insert(mtpc_webPageEmpty, _serialize_webPageEmpty);
|
||||
_serializers.insert(mtpc_webPagePending, _serialize_webPagePending);
|
||||
_serializers.insert(mtpc_webPage, _serialize_webPage);
|
||||
_serializers.insert(mtpc_webPageNotModified, _serialize_webPageNotModified);
|
||||
_serializers.insert(mtpc_authorization, _serialize_authorization);
|
||||
_serializers.insert(mtpc_account_authorizations, _serialize_account_authorizations);
|
||||
_serializers.insert(mtpc_account_noPassword, _serialize_account_noPassword);
|
||||
|
@ -9333,6 +9881,38 @@ namespace {
|
|||
_serializers.insert(mtpc_inputGameShortName, _serialize_inputGameShortName);
|
||||
_serializers.insert(mtpc_highScore, _serialize_highScore);
|
||||
_serializers.insert(mtpc_messages_highScores, _serialize_messages_highScores);
|
||||
_serializers.insert(mtpc_textEmpty, _serialize_textEmpty);
|
||||
_serializers.insert(mtpc_textPlain, _serialize_textPlain);
|
||||
_serializers.insert(mtpc_textBold, _serialize_textBold);
|
||||
_serializers.insert(mtpc_textItalic, _serialize_textItalic);
|
||||
_serializers.insert(mtpc_textUnderline, _serialize_textUnderline);
|
||||
_serializers.insert(mtpc_textStrike, _serialize_textStrike);
|
||||
_serializers.insert(mtpc_textFixed, _serialize_textFixed);
|
||||
_serializers.insert(mtpc_textUrl, _serialize_textUrl);
|
||||
_serializers.insert(mtpc_textEmail, _serialize_textEmail);
|
||||
_serializers.insert(mtpc_textConcat, _serialize_textConcat);
|
||||
_serializers.insert(mtpc_pageBlockTitle, _serialize_pageBlockTitle);
|
||||
_serializers.insert(mtpc_pageBlockSubtitle, _serialize_pageBlockSubtitle);
|
||||
_serializers.insert(mtpc_pageBlockAuthorDate, _serialize_pageBlockAuthorDate);
|
||||
_serializers.insert(mtpc_pageBlockHeader, _serialize_pageBlockHeader);
|
||||
_serializers.insert(mtpc_pageBlockSubheader, _serialize_pageBlockSubheader);
|
||||
_serializers.insert(mtpc_pageBlockParagraph, _serialize_pageBlockParagraph);
|
||||
_serializers.insert(mtpc_pageBlockPreformatted, _serialize_pageBlockPreformatted);
|
||||
_serializers.insert(mtpc_pageBlockFooter, _serialize_pageBlockFooter);
|
||||
_serializers.insert(mtpc_pageBlockDivider, _serialize_pageBlockDivider);
|
||||
_serializers.insert(mtpc_pageBlockList, _serialize_pageBlockList);
|
||||
_serializers.insert(mtpc_pageBlockBlockquote, _serialize_pageBlockBlockquote);
|
||||
_serializers.insert(mtpc_pageBlockPullquote, _serialize_pageBlockPullquote);
|
||||
_serializers.insert(mtpc_pageBlockPhoto, _serialize_pageBlockPhoto);
|
||||
_serializers.insert(mtpc_pageBlockVideo, _serialize_pageBlockVideo);
|
||||
_serializers.insert(mtpc_pageBlockCover, _serialize_pageBlockCover);
|
||||
_serializers.insert(mtpc_pageBlockEmbed, _serialize_pageBlockEmbed);
|
||||
_serializers.insert(mtpc_pageBlockEmbedPost, _serialize_pageBlockEmbedPost);
|
||||
_serializers.insert(mtpc_pageBlockSlideshow, _serialize_pageBlockSlideshow);
|
||||
_serializers.insert(mtpc_embedPostPhoto, _serialize_embedPostPhoto);
|
||||
_serializers.insert(mtpc_embedPostVideo, _serialize_embedPostVideo);
|
||||
_serializers.insert(mtpc_pagePart, _serialize_pagePart);
|
||||
_serializers.insert(mtpc_pageFull, _serialize_pageFull);
|
||||
|
||||
_serializers.insert(mtpc_req_pq, _serialize_req_pq);
|
||||
_serializers.insert(mtpc_req_DH_params, _serialize_req_DH_params);
|
||||
|
@ -9387,6 +9967,7 @@ namespace {
|
|||
_serializers.insert(mtpc_upload_saveFilePart, _serialize_upload_saveFilePart);
|
||||
_serializers.insert(mtpc_upload_saveBigFilePart, _serialize_upload_saveBigFilePart);
|
||||
_serializers.insert(mtpc_help_saveAppLog, _serialize_help_saveAppLog);
|
||||
_serializers.insert(mtpc_help_setBotUpdatesStatus, _serialize_help_setBotUpdatesStatus);
|
||||
_serializers.insert(mtpc_channels_readHistory, _serialize_channels_readHistory);
|
||||
_serializers.insert(mtpc_channels_reportSpam, _serialize_channels_reportSpam);
|
||||
_serializers.insert(mtpc_channels_editAbout, _serialize_channels_editAbout);
|
||||
|
@ -9478,6 +10059,8 @@ namespace {
|
|||
_serializers.insert(mtpc_channels_updatePinnedMessage, _serialize_channels_updatePinnedMessage);
|
||||
_serializers.insert(mtpc_messages_getPeerSettings, _serialize_messages_getPeerSettings);
|
||||
_serializers.insert(mtpc_messages_getChats, _serialize_messages_getChats);
|
||||
_serializers.insert(mtpc_messages_getCommonChats, _serialize_messages_getCommonChats);
|
||||
_serializers.insert(mtpc_messages_getAllChats, _serialize_messages_getAllChats);
|
||||
_serializers.insert(mtpc_channels_getChannels, _serialize_channels_getChannels);
|
||||
_serializers.insert(mtpc_channels_getAdminedPublicChannels, _serialize_channels_getAdminedPublicChannels);
|
||||
_serializers.insert(mtpc_messages_getFullChat, _serialize_messages_getFullChat);
|
||||
|
@ -9511,6 +10094,7 @@ namespace {
|
|||
_serializers.insert(mtpc_messages_getAttachedStickers, _serialize_messages_getAttachedStickers);
|
||||
_serializers.insert(mtpc_messages_getGameHighScores, _serialize_messages_getGameHighScores);
|
||||
_serializers.insert(mtpc_messages_getInlineGameHighScores, _serialize_messages_getInlineGameHighScores);
|
||||
_serializers.insert(mtpc_messages_getWebPage, _serialize_messages_getWebPage);
|
||||
_serializers.insert(mtpc_updates_getState, _serialize_updates_getState);
|
||||
_serializers.insert(mtpc_updates_getDifference, _serialize_updates_getDifference);
|
||||
_serializers.insert(mtpc_updates_getChannelDifference, _serialize_updates_getChannelDifference);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -35,38 +35,39 @@ struct PeerUpdate {
|
|||
|
||||
enum class Flag {
|
||||
// Common flags
|
||||
NameChanged = 0x00000001U,
|
||||
UsernameChanged = 0x00000002U,
|
||||
PhotoChanged = 0x00000004U,
|
||||
AboutChanged = 0x00000008U,
|
||||
NotificationsEnabled = 0x00000010U,
|
||||
SharedMediaChanged = 0x00000020U,
|
||||
MigrationChanged = 0x00000040U,
|
||||
NameChanged = 0x00000001U,
|
||||
UsernameChanged = 0x00000002U,
|
||||
PhotoChanged = 0x00000004U,
|
||||
AboutChanged = 0x00000008U,
|
||||
NotificationsEnabled = 0x00000010U,
|
||||
SharedMediaChanged = 0x00000020U,
|
||||
MigrationChanged = 0x00000040U,
|
||||
|
||||
// For chats and channels
|
||||
InviteLinkChanged = 0x00000020U,
|
||||
MembersChanged = 0x00000040U,
|
||||
AdminsChanged = 0x00000080U,
|
||||
InviteLinkChanged = 0x00000020U,
|
||||
MembersChanged = 0x00000040U,
|
||||
AdminsChanged = 0x00000080U,
|
||||
|
||||
// For users
|
||||
UserCanShareContact = 0x00010000U,
|
||||
UserIsContact = 0x00020000U,
|
||||
UserPhoneChanged = 0x00040000U,
|
||||
UserIsBlocked = 0x00080000U,
|
||||
BotCommandsChanged = 0x00100000U,
|
||||
UserOnlineChanged = 0x00200000U,
|
||||
BotCanAddToGroups = 0x00400000U,
|
||||
UserCanShareContact = 0x00010000U,
|
||||
UserIsContact = 0x00020000U,
|
||||
UserPhoneChanged = 0x00040000U,
|
||||
UserIsBlocked = 0x00080000U,
|
||||
BotCommandsChanged = 0x00100000U,
|
||||
UserOnlineChanged = 0x00200000U,
|
||||
BotCanAddToGroups = 0x00400000U,
|
||||
UserCommonChatsChanged = 0x00800000U,
|
||||
|
||||
// For chats
|
||||
ChatCanEdit = 0x00010000U,
|
||||
ChatCanEdit = 0x00010000U,
|
||||
|
||||
// For channels
|
||||
ChannelAmIn = 0x00010000U,
|
||||
ChannelAmEditor = 0x00020000U,
|
||||
ChannelCanEditPhoto = 0x00040000U,
|
||||
ChannelCanAddMembers = 0x00080000U,
|
||||
ChannelCanViewAdmins = 0x00100000U,
|
||||
ChannelCanViewMembers = 0x00200000U,
|
||||
ChannelAmIn = 0x00010000U,
|
||||
ChannelAmEditor = 0x00020000U,
|
||||
ChannelCanEditPhoto = 0x00040000U,
|
||||
ChannelCanAddMembers = 0x00080000U,
|
||||
ChannelCanViewAdmins = 0x00100000U,
|
||||
ChannelCanViewMembers = 0x00200000U,
|
||||
};
|
||||
Q_DECLARE_FLAGS(Flags, Flag);
|
||||
Flags flags = 0;
|
||||
|
|
|
@ -19,7 +19,7 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
|||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_actions_widget.h"
|
||||
#include "profile/profile_block_actions.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "styles/style_boxes.h"
|
145
Telegram/SourceFiles/profile/profile_block_channel_members.cpp
Normal file
145
Telegram/SourceFiles/profile/profile_block_channel_members.cpp
Normal file
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_block_channel_members.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "boxes/members_box.h"
|
||||
#include "observer_peer.h"
|
||||
#include "lang.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
using UpdateFlag = Notify::PeerUpdate::Flag;
|
||||
|
||||
ChannelMembersWidget::ChannelMembersWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_participants_section)) {
|
||||
auto observeEvents = UpdateFlag::ChannelCanViewAdmins
|
||||
| UpdateFlag::ChannelCanViewMembers
|
||||
| UpdateFlag::AdminsChanged
|
||||
| UpdateFlag::MembersChanged;
|
||||
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) {
|
||||
notifyPeerUpdated(update);
|
||||
}));
|
||||
|
||||
refreshButtons();
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
||||
if (update.peer != peer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (update.flags & (UpdateFlag::ChannelCanViewAdmins | UpdateFlag::AdminsChanged)) {
|
||||
refreshAdmins();
|
||||
}
|
||||
if (update.flags & (UpdateFlag::ChannelCanViewMembers | UpdateFlag::MembersChanged)) {
|
||||
refreshMembers();
|
||||
}
|
||||
refreshVisibility();
|
||||
|
||||
contentSizeUpdated();
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::addButton(const QString &text, ChildWidget<Ui::LeftOutlineButton> *button, const char *slot) {
|
||||
if (text.isEmpty()) {
|
||||
button->destroy();
|
||||
} else if (*button) {
|
||||
(*button)->setText(text);
|
||||
} else {
|
||||
(*button) = new Ui::LeftOutlineButton(this, text, st::defaultLeftOutlineButton);
|
||||
(*button)->show();
|
||||
connect(*button, SIGNAL(clicked()), this, slot);
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::refreshButtons() {
|
||||
refreshAdmins();
|
||||
refreshMembers();
|
||||
|
||||
refreshVisibility();
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::refreshAdmins() {
|
||||
auto getAdminsText = [this]() -> QString {
|
||||
if (auto channel = peer()->asChannel()) {
|
||||
if (!channel->isMegagroup() && channel->canViewAdmins()) {
|
||||
int adminsCount = qMax(channel->adminsCount(), 1);
|
||||
return lng_channel_admins_link(lt_count, adminsCount);
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
};
|
||||
addButton(getAdminsText(), &_admins, SLOT(onAdmins()));
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::refreshMembers() {
|
||||
auto getMembersText = [this]() -> QString {
|
||||
if (auto channel = peer()->asChannel()) {
|
||||
if (!channel->isMegagroup() && channel->canViewMembers()) {
|
||||
int membersCount = qMax(channel->membersCount(), 1);
|
||||
return lng_channel_members_link(lt_count, membersCount);
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
};
|
||||
addButton(getMembersText(), &_members, SLOT(onMembers()));
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::refreshVisibility() {
|
||||
setVisible(_admins || _members);
|
||||
}
|
||||
|
||||
int ChannelMembersWidget::resizeGetHeight(int newWidth) {
|
||||
int newHeight = contentTop();
|
||||
|
||||
auto resizeButton = [this, &newHeight, newWidth](ChildWidget<Ui::LeftOutlineButton> &button) {
|
||||
if (!button) {
|
||||
return;
|
||||
}
|
||||
|
||||
int left = defaultOutlineButtonLeft();
|
||||
int availableWidth = newWidth - left - st::profileBlockMarginRight;
|
||||
accumulate_min(availableWidth, st::profileBlockOneLineWidthMax);
|
||||
button->resizeToWidth(availableWidth);
|
||||
button->moveToLeft(left, newHeight);
|
||||
newHeight += button->height();
|
||||
};
|
||||
|
||||
resizeButton(_admins);
|
||||
resizeButton(_members);
|
||||
|
||||
return newHeight;
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::onAdmins() {
|
||||
if (auto channel = peer()->asChannel()) {
|
||||
Ui::showLayer(new MembersBox(channel, MembersFilter::Admins));
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::onMembers() {
|
||||
if (auto channel = peer()->asChannel()) {
|
||||
Ui::showLayer(new MembersBox(channel, MembersFilter::Recent));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Profile
|
65
Telegram/SourceFiles/profile/profile_block_channel_members.h
Normal file
65
Telegram/SourceFiles/profile/profile_block_channel_members.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "profile/profile_block_widget.h"
|
||||
|
||||
namespace Ui {
|
||||
class LeftOutlineButton;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Notify {
|
||||
struct PeerUpdate;
|
||||
} // namespace Notify
|
||||
|
||||
namespace Profile {
|
||||
|
||||
class ChannelMembersWidget : public BlockWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChannelMembersWidget(QWidget *parent, PeerData *peer);
|
||||
|
||||
protected:
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
private slots:
|
||||
void onAdmins();
|
||||
void onMembers();
|
||||
|
||||
private:
|
||||
// Observed notifications.
|
||||
void notifyPeerUpdated(const Notify::PeerUpdate &update);
|
||||
|
||||
void refreshButtons();
|
||||
void refreshAdmins();
|
||||
void refreshMembers();
|
||||
void refreshVisibility();
|
||||
|
||||
void addButton(const QString &text, ChildWidget<Ui::LeftOutlineButton> *button, const char *slot);
|
||||
|
||||
ChildWidget<Ui::LeftOutlineButton> _admins = { nullptr };
|
||||
ChildWidget<Ui::LeftOutlineButton> _members = { nullptr };
|
||||
|
||||
};
|
||||
|
||||
} // namespace Profile
|
175
Telegram/SourceFiles/profile/profile_block_common_groups.cpp
Normal file
175
Telegram/SourceFiles/profile/profile_block_common_groups.cpp
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_block_common_groups.h"
|
||||
|
||||
#include "profile/profile_section_memento.h"
|
||||
#include "styles/style_widgets.h"
|
||||
#include "observer_peer.h"
|
||||
#include "apiwrap.h"
|
||||
#include "lang.h"
|
||||
|
||||
namespace Profile {
|
||||
namespace {
|
||||
|
||||
constexpr int kCommonGroupsPerPage = 20;
|
||||
|
||||
} // namespace
|
||||
|
||||
CommonGroupsWidget::CommonGroupsWidget(QWidget *parent, PeerData *peer)
|
||||
: PeerListWidget(parent, peer, lang(lng_profile_common_groups_section)) {
|
||||
refreshVisibility();
|
||||
|
||||
auto observeEvents = Notify::PeerUpdate::Flag::MembersChanged;
|
||||
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) {
|
||||
notifyPeerUpdated(update);
|
||||
}));
|
||||
|
||||
setSelectedCallback([this](PeerData *selectedPeer) {
|
||||
Ui::showPeerHistory(selectedPeer, ShowAtUnreadMsgId, Ui::ShowWay::Forward);
|
||||
});
|
||||
setPreloadMoreCallback([this] {
|
||||
preloadMore();
|
||||
});
|
||||
}
|
||||
|
||||
void CommonGroupsWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
||||
for_const (auto item, items()) {
|
||||
if (item->peer == update.peer) {
|
||||
updateStatusText(item);
|
||||
this->update();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CommonGroupsWidget::resizeGetHeight(int newWidth) {
|
||||
auto result = PeerListWidget::resizeGetHeight(newWidth);
|
||||
return _height.animating() ? _height.current() : result;
|
||||
}
|
||||
|
||||
void CommonGroupsWidget::paintContents(Painter &p) {
|
||||
_height.animating(getms());
|
||||
return PeerListWidget::paintContents(p);
|
||||
}
|
||||
|
||||
void CommonGroupsWidget::saveState(SectionMemento *memento) const {
|
||||
if (auto count = itemsCount()) {
|
||||
QList<PeerData*> groups;
|
||||
groups.reserve(count);
|
||||
for_const (auto item, items()) {
|
||||
groups.push_back(item->peer);
|
||||
}
|
||||
memento->setCommonGroups(groups);
|
||||
}
|
||||
}
|
||||
|
||||
void CommonGroupsWidget::restoreState(const SectionMemento *memento) {
|
||||
CommonGroupsEvent event;
|
||||
event.groups = memento->getCommonGroups();
|
||||
if (!event.groups.empty()) {
|
||||
onShowCommonGroups(event);
|
||||
}
|
||||
}
|
||||
|
||||
void CommonGroupsWidget::onShowCommonGroups(const CommonGroupsEvent &event) {
|
||||
for_const (auto group, event.groups) {
|
||||
addItem(computeItem(group));
|
||||
_preloadGroupId = group->bareId();
|
||||
}
|
||||
refreshVisibility();
|
||||
if (event.initialHeight >= 0) {
|
||||
_height.start([this] { contentSizeUpdated(); }, event.initialHeight, resizeGetHeight(width()), st::widgetSlideDuration);
|
||||
}
|
||||
contentSizeUpdated();
|
||||
update();
|
||||
}
|
||||
|
||||
void CommonGroupsWidget::preloadMore() {
|
||||
if (_preloadRequestId || !_preloadGroupId) {
|
||||
return;
|
||||
}
|
||||
auto user = peer()->asUser();
|
||||
t_assert(user != nullptr);
|
||||
auto request = MTPmessages_GetCommonChats(user->inputUser, MTP_int(_preloadGroupId), MTP_int(kCommonGroupsPerPage));
|
||||
_preloadRequestId = MTP::send(request, ::rpcDone(base::lambda_guarded(this, [this](const MTPmessages_Chats &result) {
|
||||
_preloadRequestId = 0;
|
||||
_preloadGroupId = 0;
|
||||
|
||||
if (auto chats = Api::getChatsFromMessagesChats(result)) {
|
||||
auto &list = chats->c_vector().v;
|
||||
if (!list.empty()) {
|
||||
reserveItemsForSize(itemsCount() + list.size());
|
||||
for_const (auto &chatData, list) {
|
||||
if (auto chat = App::feedChat(chatData)) {
|
||||
addItem(computeItem(chat));
|
||||
_preloadGroupId = chat->bareId();
|
||||
}
|
||||
}
|
||||
contentSizeUpdated();
|
||||
}
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
||||
void CommonGroupsWidget::updateStatusText(Item *item) {
|
||||
auto group = item->peer;
|
||||
if (auto chat = group->asChat()) {
|
||||
auto count = qMax(chat->count, chat->participants.size());
|
||||
item->statusText = count ? lng_chat_status_members(lt_count, count) : lang(lng_group_status);
|
||||
} else if (auto megagroup = group->asMegagroup()) {
|
||||
auto count = megagroup->membersCount();
|
||||
item->statusText = (count > 0) ? lng_chat_status_members(lt_count, count) : lang(lng_group_status);
|
||||
|
||||
// Request members count.
|
||||
if (!megagroup->wasFullUpdated()) App::api()->requestFullPeer(megagroup);
|
||||
} else if (auto channel = group->asChannel()) {
|
||||
auto count = channel->membersCount();
|
||||
item->statusText = (count > 0) ? lng_chat_status_members(lt_count, count) : lang(lng_channel_status);
|
||||
|
||||
// Request members count.
|
||||
if (!channel->wasFullUpdated()) App::api()->requestFullPeer(channel);
|
||||
} else {
|
||||
t_assert(!"Users should not get to CommonGroupsWidget::updateStatusText()");
|
||||
}
|
||||
}
|
||||
|
||||
CommonGroupsWidget::Item *CommonGroupsWidget::computeItem(PeerData *group) {
|
||||
// Skip groups that migrated to supergroups.
|
||||
if (group->migrateTo()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto it = _dataMap.constFind(group);
|
||||
if (it == _dataMap.cend()) {
|
||||
it = _dataMap.insert(group, new Item(group));
|
||||
updateStatusText(it.value());
|
||||
}
|
||||
return it.value();
|
||||
}
|
||||
|
||||
CommonGroupsWidget::~CommonGroupsWidget() {
|
||||
for (auto item : base::take(_dataMap)) {
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Profile
|
75
Telegram/SourceFiles/profile/profile_block_common_groups.h
Normal file
75
Telegram/SourceFiles/profile/profile_block_common_groups.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "profile/profile_block_peer_list.h"
|
||||
|
||||
namespace Notify {
|
||||
struct PeerUpdate;
|
||||
} // namespace Notify
|
||||
|
||||
namespace Profile {
|
||||
|
||||
struct CommonGroupsEvent {
|
||||
QList<PeerData*> groups;
|
||||
|
||||
// If initialHeight >= 0 the common groups widget will
|
||||
// slide down starting from height() == initialHeight.
|
||||
// Otherwise it will just show instantly.
|
||||
int initialHeight = -1;
|
||||
};
|
||||
|
||||
class CommonGroupsWidget : public PeerListWidget {
|
||||
public:
|
||||
CommonGroupsWidget(QWidget *parent, PeerData *peer);
|
||||
|
||||
void setShowCommonGroupsObservable(base::Observable<CommonGroupsEvent> *observable) {
|
||||
subscribe(observable, [this](const CommonGroupsEvent &event) { onShowCommonGroups(event); });
|
||||
}
|
||||
|
||||
void saveState(SectionMemento *memento) const override;
|
||||
void restoreState(const SectionMemento *memento) override;
|
||||
|
||||
~CommonGroupsWidget();
|
||||
|
||||
protected:
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
void paintContents(Painter &p) override;
|
||||
|
||||
private:
|
||||
// Observed notifications.
|
||||
void notifyPeerUpdated(const Notify::PeerUpdate &update);
|
||||
|
||||
void updateStatusText(Item *item);
|
||||
void onShowCommonGroups(const CommonGroupsEvent &event);
|
||||
void preloadMore();
|
||||
|
||||
Item *computeItem(PeerData *group);
|
||||
QMap<PeerData*, Item*> _dataMap;
|
||||
|
||||
IntAnimation _height;
|
||||
|
||||
int32 _preloadGroupId = 0;
|
||||
mtpRequestId _preloadRequestId = 0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Profile
|
429
Telegram/SourceFiles/profile/profile_block_group_members.cpp
Normal file
429
Telegram/SourceFiles/profile/profile_block_group_members.cpp
Normal file
|
@ -0,0 +1,429 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_block_group_members.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "apiwrap.h"
|
||||
#include "observer_peer.h"
|
||||
#include "lang.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
using UpdateFlag = Notify::PeerUpdate::Flag;
|
||||
|
||||
GroupMembersWidget::GroupMembersWidget(QWidget *parent, PeerData *peer, TitleVisibility titleVisibility)
|
||||
: PeerListWidget(parent
|
||||
, peer
|
||||
, (titleVisibility == TitleVisibility::Visible) ? lang(lng_profile_participants_section) : QString()
|
||||
, lang(lng_profile_kick)) {
|
||||
_updateOnlineTimer.setSingleShot(true);
|
||||
connect(&_updateOnlineTimer, SIGNAL(timeout()), this, SLOT(onUpdateOnlineDisplay()));
|
||||
|
||||
auto observeEvents = UpdateFlag::AdminsChanged
|
||||
| UpdateFlag::MembersChanged
|
||||
| UpdateFlag::UserOnlineChanged;
|
||||
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) {
|
||||
notifyPeerUpdated(update);
|
||||
}));
|
||||
|
||||
setRemovedCallback([this, peer](PeerData *selectedPeer) {
|
||||
Ui::showLayer(new KickMemberBox(peer, selectedPeer->asUser()));
|
||||
});
|
||||
setSelectedCallback([this](PeerData *selectedPeer) {
|
||||
Ui::showPeerProfile(selectedPeer);
|
||||
});
|
||||
setUpdateItemCallback([this](Item *item) {
|
||||
updateItemStatusText(item);
|
||||
});
|
||||
setPreloadMoreCallback([this] {
|
||||
preloadMore();
|
||||
});
|
||||
|
||||
refreshMembers();
|
||||
}
|
||||
|
||||
void GroupMembersWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
||||
if (update.peer != peer()) {
|
||||
if (update.flags & UpdateFlag::UserOnlineChanged) {
|
||||
if (auto user = update.peer->asUser()) {
|
||||
refreshUserOnline(user);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (update.flags & UpdateFlag::MembersChanged) {
|
||||
refreshMembers();
|
||||
contentSizeUpdated();
|
||||
} else if (update.flags & UpdateFlag::AdminsChanged) {
|
||||
if (auto chat = peer()->asChat()) {
|
||||
for_const (auto item, items()) {
|
||||
setItemFlags(getMember(item), chat);
|
||||
}
|
||||
} else if (auto megagroup = peer()->asMegagroup()) {
|
||||
for_const (auto item, items()) {
|
||||
setItemFlags(getMember(item), megagroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
this->update();
|
||||
}
|
||||
|
||||
void GroupMembersWidget::refreshUserOnline(UserData *user) {
|
||||
auto it = _membersByUser.find(user);
|
||||
if (it == _membersByUser.cend()) return;
|
||||
|
||||
_now = unixtime();
|
||||
|
||||
auto member = getMember(it.value());
|
||||
member->statusHasOnlineColor = !user->botInfo && App::onlineColorUse(user->onlineTill, _now);
|
||||
member->onlineTill = user->onlineTill;
|
||||
member->onlineForSort = user->isSelf() ? INT_MAX : App::onlineForSort(user, _now);
|
||||
member->statusText = QString();
|
||||
|
||||
sortMembers();
|
||||
update();
|
||||
}
|
||||
|
||||
void GroupMembersWidget::preloadMore() {
|
||||
if (auto megagroup = peer()->asMegagroup()) {
|
||||
auto megagroupInfo = megagroup->mgInfo;
|
||||
if (!megagroupInfo->lastParticipants.isEmpty() && megagroupInfo->lastParticipants.size() < megagroup->membersCount()) {
|
||||
App::api()->requestLastParticipants(megagroup, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int GroupMembersWidget::resizeGetHeight(int newWidth) {
|
||||
if (_limitReachedInfo) {
|
||||
int limitReachedInfoWidth = newWidth - getListLeft();
|
||||
accumulate_min(limitReachedInfoWidth, st::profileBlockWideWidthMax);
|
||||
|
||||
_limitReachedInfo->resizeToWidth(limitReachedInfoWidth);
|
||||
_limitReachedInfo->moveToLeft(getListLeft(), contentTop());
|
||||
}
|
||||
return PeerListWidget::resizeGetHeight(newWidth);
|
||||
}
|
||||
|
||||
void GroupMembersWidget::paintContents(Painter &p) {
|
||||
int left = getListLeft();
|
||||
int top = getListTop();
|
||||
int memberRowWidth = width() - left;
|
||||
accumulate_min(memberRowWidth, st::profileBlockWideWidthMax);
|
||||
if (_limitReachedInfo) {
|
||||
int infoTop = contentTop();
|
||||
int infoHeight = top - infoTop - st::profileLimitReachedSkip;
|
||||
paintOutlinedRect(p, left, infoTop, memberRowWidth, infoHeight);
|
||||
}
|
||||
|
||||
_now = unixtime();
|
||||
PeerListWidget::paintContents(p);
|
||||
}
|
||||
|
||||
void GroupMembersWidget::updateItemStatusText(Item *item) {
|
||||
auto member = getMember(item);
|
||||
auto user = member->user();
|
||||
if (member->statusText.isEmpty() || (member->onlineTextTill <= _now)) {
|
||||
if (user->botInfo) {
|
||||
bool seesAllMessages = (user->botInfo->readsAllHistory || member->hasAdminStar);
|
||||
member->statusText = lang(seesAllMessages ? lng_status_bot_reads_all : lng_status_bot_not_reads_all);
|
||||
member->onlineTextTill = _now + 86400;
|
||||
} else {
|
||||
member->statusHasOnlineColor = App::onlineColorUse(member->onlineTill, _now);
|
||||
member->statusText = App::onlineText(member->onlineTill, _now);
|
||||
member->onlineTextTill = _now + App::onlineWillChangeIn(member->onlineTill, _now);
|
||||
}
|
||||
}
|
||||
if (_updateOnlineAt <= _now || _updateOnlineAt > member->onlineTextTill) {
|
||||
_updateOnlineAt = member->onlineTextTill;
|
||||
_updateOnlineTimer.start((_updateOnlineAt - _now + 1) * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
int GroupMembersWidget::getListTop() const {
|
||||
int result = contentTop();
|
||||
if (_limitReachedInfo) {
|
||||
result += _limitReachedInfo->height();
|
||||
result += st::profileLimitReachedSkip;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void GroupMembersWidget::refreshMembers() {
|
||||
_now = unixtime();
|
||||
if (auto chat = peer()->asChat()) {
|
||||
checkSelfAdmin(chat);
|
||||
if (chat->noParticipantInfo()) {
|
||||
App::api()->requestFullPeer(chat);
|
||||
}
|
||||
fillChatMembers(chat);
|
||||
refreshLimitReached();
|
||||
} else if (auto megagroup = peer()->asMegagroup()) {
|
||||
checkSelfAdmin(megagroup);
|
||||
auto megagroupInfo = megagroup->mgInfo;
|
||||
if (megagroupInfo->lastParticipants.isEmpty() || megagroup->lastParticipantsCountOutdated()) {
|
||||
App::api()->requestLastParticipants(megagroup);
|
||||
}
|
||||
fillMegagroupMembers(megagroup);
|
||||
}
|
||||
sortMembers();
|
||||
|
||||
refreshVisibility();
|
||||
}
|
||||
|
||||
void GroupMembersWidget::refreshLimitReached() {
|
||||
auto chat = peer()->asChat();
|
||||
if (!chat) return;
|
||||
|
||||
bool limitReachedShown = (itemsCount() >= Global::ChatSizeMax()) && chat->amCreator() && !emptyTitle();
|
||||
if (limitReachedShown && !_limitReachedInfo) {
|
||||
_limitReachedInfo.create(this, st::profileLimitReachedLabel, st::profileLimitReachedStyle);
|
||||
QString title = textRichPrepare(lng_profile_migrate_reached(lt_count, Global::ChatSizeMax()));
|
||||
QString body = textRichPrepare(lang(lng_profile_migrate_body));
|
||||
QString link = textRichPrepare(lang(lng_profile_migrate_learn_more));
|
||||
QString text = qsl("%1%2%3\n%4 [a href=\"https://telegram.org/blog/supergroups5k\"]%5[/a]").arg(textcmdStartSemibold()).arg(title).arg(textcmdStopSemibold()).arg(body).arg(link);
|
||||
_limitReachedInfo->setRichText(text);
|
||||
_limitReachedInfo->setClickHandlerHook([this](const ClickHandlerPtr &handler, Qt::MouseButton button) {
|
||||
Ui::showLayer(new ConvertToSupergroupBox(peer()->asChat()));
|
||||
return false;
|
||||
});
|
||||
} else if (!limitReachedShown && _limitReachedInfo) {
|
||||
_limitReachedInfo.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void GroupMembersWidget::checkSelfAdmin(ChatData *chat) {
|
||||
if (chat->participants.isEmpty()) return;
|
||||
|
||||
auto self = App::self();
|
||||
if (chat->amAdmin() && !chat->admins.contains(self)) {
|
||||
chat->admins.insert(self);
|
||||
} else if (!chat->amAdmin() && chat->admins.contains(self)) {
|
||||
chat->admins.remove(self);
|
||||
}
|
||||
}
|
||||
|
||||
void GroupMembersWidget::checkSelfAdmin(ChannelData *megagroup) {
|
||||
if (megagroup->mgInfo->lastParticipants.isEmpty()) return;
|
||||
|
||||
bool amAdmin = (megagroup->amCreator() || megagroup->amEditor());
|
||||
auto self = App::self();
|
||||
if (amAdmin && !megagroup->mgInfo->lastAdmins.contains(self)) {
|
||||
megagroup->mgInfo->lastAdmins.insert(self);
|
||||
} else if (!amAdmin && megagroup->mgInfo->lastAdmins.contains(self)) {
|
||||
megagroup->mgInfo->lastAdmins.remove(self);
|
||||
}
|
||||
}
|
||||
|
||||
void GroupMembersWidget::sortMembers() {
|
||||
if (!_sortByOnline || !itemsCount()) return;
|
||||
|
||||
sortItems([this](Item *a, Item *b) {
|
||||
return getMember(a)->onlineForSort > getMember(b)->onlineForSort;
|
||||
});
|
||||
|
||||
updateOnlineCount();
|
||||
}
|
||||
|
||||
void GroupMembersWidget::updateOnlineCount() {
|
||||
bool onlyMe = true;
|
||||
int newOnlineCount = 0;
|
||||
for_const (auto item, items()) {
|
||||
auto member = getMember(item);
|
||||
auto user = member->user();
|
||||
auto isOnline = !user->botInfo && App::onlineColorUse(member->onlineTill, _now);
|
||||
if (member->statusHasOnlineColor != isOnline) {
|
||||
member->statusHasOnlineColor = isOnline;
|
||||
member->statusText = QString();
|
||||
}
|
||||
if (member->statusHasOnlineColor) {
|
||||
++newOnlineCount;
|
||||
if (!user->isSelf()) {
|
||||
onlyMe = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newOnlineCount == 1 && onlyMe) {
|
||||
newOnlineCount = 0;
|
||||
}
|
||||
if (_onlineCount != newOnlineCount) {
|
||||
_onlineCount = newOnlineCount;
|
||||
emit onlineCountUpdated(_onlineCount);
|
||||
}
|
||||
}
|
||||
|
||||
GroupMembersWidget::Member *GroupMembersWidget::addUser(ChatData *chat, UserData *user) {
|
||||
auto member = computeMember(user);
|
||||
setItemFlags(member, chat);
|
||||
addItem(member);
|
||||
return member;
|
||||
}
|
||||
|
||||
void GroupMembersWidget::fillChatMembers(ChatData *chat) {
|
||||
if (chat->participants.isEmpty()) return;
|
||||
|
||||
clearItems();
|
||||
if (!chat->amIn()) return;
|
||||
|
||||
_sortByOnline = true;
|
||||
|
||||
reserveItemsForSize(chat->participants.size());
|
||||
addUser(chat, App::self())->onlineForSort = INT_MAX; // Put me on the first place.
|
||||
for (auto i = chat->participants.cbegin(), e = chat->participants.cend(); i != e; ++i) {
|
||||
auto user = i.key();
|
||||
if (!user->isSelf()) {
|
||||
addUser(chat, user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GroupMembersWidget::setItemFlags(Item *item, ChatData *chat) {
|
||||
auto user = getMember(item)->user();
|
||||
auto isCreator = (peerFromUser(chat->creator) == item->peer->id);
|
||||
auto isAdmin = chat->admins.contains(user);
|
||||
item->hasAdminStar = isCreator || isAdmin;
|
||||
if (item->peer->id == peerFromUser(MTP::authedId())) {
|
||||
item->hasRemoveLink = false;
|
||||
} else if (chat->amCreator() || (chat->amAdmin() && !item->hasAdminStar)) {
|
||||
item->hasRemoveLink = true;
|
||||
} else {
|
||||
item->hasRemoveLink = chat->invitedByMe.contains(user);
|
||||
}
|
||||
}
|
||||
|
||||
GroupMembersWidget::Member *GroupMembersWidget::addUser(ChannelData *megagroup, UserData *user) {
|
||||
auto member = computeMember(user);
|
||||
setItemFlags(member, megagroup);
|
||||
addItem(member);
|
||||
return member;
|
||||
}
|
||||
|
||||
void GroupMembersWidget::fillMegagroupMembers(ChannelData *megagroup) {
|
||||
t_assert(megagroup->mgInfo != nullptr);
|
||||
if (megagroup->mgInfo->lastParticipants.isEmpty()) return;
|
||||
|
||||
if (!megagroup->canViewMembers()) {
|
||||
clearItems();
|
||||
return;
|
||||
}
|
||||
|
||||
_sortByOnline = (megagroup->membersCount() > 0 && megagroup->membersCount() <= Global::ChatSizeMax());
|
||||
|
||||
auto &membersList = megagroup->mgInfo->lastParticipants;
|
||||
if (_sortByOnline) {
|
||||
clearItems();
|
||||
reserveItemsForSize(membersList.size());
|
||||
if (megagroup->amIn()) {
|
||||
addUser(megagroup, App::self())->onlineForSort = INT_MAX;
|
||||
}
|
||||
} else if (membersList.size() >= itemsCount()) {
|
||||
if (addUsersToEnd(megagroup)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!_sortByOnline) {
|
||||
clearItems();
|
||||
reserveItemsForSize(membersList.size());
|
||||
}
|
||||
for_const (auto user, membersList) {
|
||||
if (!_sortByOnline || !user->isSelf()) {
|
||||
addUser(megagroup, user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GroupMembersWidget::addUsersToEnd(ChannelData *megagroup) {
|
||||
auto &membersList = megagroup->mgInfo->lastParticipants;
|
||||
auto &itemsList = items();
|
||||
for (int i = 0, count = itemsList.size(); i < count; ++i) {
|
||||
if (itemsList[i]->peer != membersList.at(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
reserveItemsForSize(membersList.size());
|
||||
for (int i = itemsCount(), count = membersList.size(); i < count; ++i) {
|
||||
addUser(megagroup, membersList.at(i));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GroupMembersWidget::setItemFlags(Item *item, ChannelData *megagroup) {
|
||||
auto amCreatorOrAdmin = (peerToUser(item->peer->id) == MTP::authedId()) && (megagroup->amCreator() || megagroup->amEditor());
|
||||
auto isAdmin = megagroup->mgInfo->lastAdmins.contains(getMember(item)->user());
|
||||
item->hasAdminStar = amCreatorOrAdmin || isAdmin;
|
||||
if (item->peer->isSelf()) {
|
||||
item->hasRemoveLink = false;
|
||||
} else if (megagroup->amCreator() || (megagroup->amEditor() && !item->hasAdminStar)) {
|
||||
item->hasRemoveLink = true;
|
||||
} else {
|
||||
item->hasRemoveLink = false;
|
||||
}
|
||||
}
|
||||
|
||||
GroupMembersWidget::Member *GroupMembersWidget::computeMember(UserData *user) {
|
||||
auto it = _membersByUser.constFind(user);
|
||||
if (it == _membersByUser.cend()) {
|
||||
auto member = new Member(user);
|
||||
it = _membersByUser.insert(user, member);
|
||||
member->statusHasOnlineColor = !user->botInfo && App::onlineColorUse(user->onlineTill, _now);
|
||||
member->onlineTill = user->onlineTill;
|
||||
member->onlineForSort = App::onlineForSort(user, _now);
|
||||
}
|
||||
return it.value();
|
||||
}
|
||||
|
||||
void GroupMembersWidget::onUpdateOnlineDisplay() {
|
||||
if (_sortByOnline) {
|
||||
_now = unixtime();
|
||||
|
||||
bool changed = false;
|
||||
for_const (auto item, items()) {
|
||||
if (!item->statusHasOnlineColor) {
|
||||
if (!item->peer->isSelf()) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto member = getMember(item);
|
||||
bool isOnline = !member->user()->botInfo && App::onlineColorUse(member->onlineTill, _now);
|
||||
if (!isOnline) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
updateOnlineCount();
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
GroupMembersWidget::~GroupMembersWidget() {
|
||||
auto members = base::take(_membersByUser);
|
||||
for_const (auto member, members) {
|
||||
delete member;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Profile
|
|
@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "profile/profile_block_widget.h"
|
||||
#include "profile/profile_block_peer_list.h"
|
||||
|
||||
namespace Ui {
|
||||
class FlatLabel;
|
||||
|
@ -33,7 +33,7 @@ struct PeerUpdate;
|
|||
|
||||
namespace Profile {
|
||||
|
||||
class MembersWidget : public BlockWidget {
|
||||
class GroupMembersWidget : public PeerListWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -41,14 +41,13 @@ public:
|
|||
Visible,
|
||||
Hidden,
|
||||
};
|
||||
MembersWidget(QWidget *parent, PeerData *peer, TitleVisibility titleVisibility = TitleVisibility::Visible);
|
||||
GroupMembersWidget(QWidget *parent, PeerData *peer, TitleVisibility titleVisibility = TitleVisibility::Visible);
|
||||
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
int onlineCount() const {
|
||||
return _onlineCount;
|
||||
}
|
||||
|
||||
~MembersWidget();
|
||||
~GroupMembersWidget();
|
||||
|
||||
protected:
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
|
@ -56,18 +55,6 @@ protected:
|
|||
|
||||
void paintContents(Painter &p) override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void enterEvent(QEvent *e) override;
|
||||
void enterFromChildEvent(QEvent *e, QWidget *child) override {
|
||||
enterEvent(e);
|
||||
}
|
||||
void leaveEvent(QEvent *e) override;
|
||||
void leaveToChildEvent(QEvent *e, QWidget *child) override {
|
||||
leaveEvent(e);
|
||||
}
|
||||
|
||||
signals:
|
||||
void onlineCountUpdated(int onlineCount);
|
||||
|
||||
|
@ -78,8 +65,6 @@ private:
|
|||
// Observed notifications.
|
||||
void notifyPeerUpdated(const Notify::PeerUpdate &update);
|
||||
|
||||
void preloadUserPhotos();
|
||||
|
||||
void refreshMembers();
|
||||
void fillChatMembers(ChatData *chat);
|
||||
void fillMegagroupMembers(ChannelData *megagroup);
|
||||
|
@ -89,91 +74,46 @@ private:
|
|||
void checkSelfAdmin(ChannelData *megagroup);
|
||||
void refreshLimitReached();
|
||||
|
||||
void preloadMore();
|
||||
|
||||
bool limitReachedHook(const ClickHandlerPtr &handler, Qt::MouseButton button);
|
||||
|
||||
void refreshVisibility();
|
||||
void updateSelection();
|
||||
void setSelected(int selected, bool selectedKick);
|
||||
void repaintSelectedRow();
|
||||
void refreshUserOnline(UserData *user);
|
||||
|
||||
int getListLeft() const;
|
||||
int getListTop() const;
|
||||
int getListTop() const override;
|
||||
|
||||
struct Member {
|
||||
Member(UserData *user) : user(user) {
|
||||
struct Member : public Item {
|
||||
explicit Member(UserData *user) : Item(user) {
|
||||
}
|
||||
UserData *user() const {
|
||||
return static_cast<UserData*>(peer);
|
||||
}
|
||||
UserData *user;
|
||||
Text name;
|
||||
QString onlineText;
|
||||
TimeId onlineTextTill = 0;
|
||||
TimeId onlineTill = 0;
|
||||
TimeId onlineForSort = 0;
|
||||
bool online = false;
|
||||
bool isAdmin = false;
|
||||
bool canBeKicked = false;
|
||||
};
|
||||
Member *getMember(UserData *user);
|
||||
void paintMember(Painter &p, int x, int y, Member *member, bool selected, bool selectedKick);
|
||||
void paintOutlinedRect(Painter &p, int x, int y, int w, int h) const;
|
||||
void setMemberFlags(Member *member, ChatData *chat);
|
||||
Member *getMember(Item *item) {
|
||||
return static_cast<Member*>(item);
|
||||
}
|
||||
|
||||
void updateItemStatusText(Item *item);
|
||||
Member *computeMember(UserData *user);
|
||||
Member *addUser(ChatData *chat, UserData *user);
|
||||
void setMemberFlags(Member *member, ChannelData *megagroup);
|
||||
Member *addUser(ChannelData *megagroup, UserData *user);
|
||||
void setItemFlags(Item *item, ChatData *chat);
|
||||
void setItemFlags(Item *item, ChannelData *megagroup);
|
||||
bool addUsersToEnd(ChannelData *megagroup);
|
||||
|
||||
ChildWidget<Ui::FlatLabel> _limitReachedInfo = { nullptr };
|
||||
|
||||
QList<Member*> _list;
|
||||
QMap<UserData*, Member*> _membersByUser;
|
||||
bool _sortByOnline = false;
|
||||
TimeId _now = 0;
|
||||
|
||||
int _visibleTop = 0;
|
||||
int _visibleBottom = 0;
|
||||
|
||||
int _selected = -1;
|
||||
int _pressed = -1;
|
||||
bool _selectedKick = false;
|
||||
bool _pressedKick = false;
|
||||
QPoint _mousePosition;
|
||||
|
||||
int _onlineCount = 0;
|
||||
TimeId _updateOnlineAt = 0;
|
||||
QTimer _updateOnlineTimer;
|
||||
|
||||
int _removeWidth = 0;
|
||||
|
||||
};
|
||||
|
||||
class ChannelMembersWidget : public BlockWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChannelMembersWidget(QWidget *parent, PeerData *peer);
|
||||
|
||||
protected:
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
private slots:
|
||||
void onAdmins();
|
||||
void onMembers();
|
||||
|
||||
private:
|
||||
// Observed notifications.
|
||||
void notifyPeerUpdated(const Notify::PeerUpdate &update);
|
||||
|
||||
void refreshButtons();
|
||||
void refreshAdmins();
|
||||
void refreshMembers();
|
||||
void refreshVisibility();
|
||||
|
||||
void addButton(const QString &text, ChildWidget<Ui::LeftOutlineButton> *button, const char *slot);
|
||||
|
||||
ChildWidget<Ui::LeftOutlineButton> _admins = { nullptr };
|
||||
ChildWidget<Ui::LeftOutlineButton> _members = { nullptr };
|
||||
|
||||
};
|
||||
|
||||
} // namespace Profile
|
|
@ -19,28 +19,56 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
|||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_info_widget.h"
|
||||
#include "profile/profile_block_info.h"
|
||||
|
||||
#include "profile/profile_block_common_groups.h"
|
||||
#include "profile/profile_section_memento.h"
|
||||
#include "styles/style_profile.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/effects/widget_slide_wrap.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "observer_peer.h"
|
||||
#include "apiwrap.h"
|
||||
#include "lang.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
constexpr int kCommonGroupsLimit = 20;
|
||||
|
||||
using UpdateFlag = Notify::PeerUpdate::Flag;
|
||||
|
||||
InfoWidget::InfoWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_info_section)) {
|
||||
auto observeEvents = UpdateFlag::AboutChanged
|
||||
| UpdateFlag::UsernameChanged
|
||||
| UpdateFlag::UserPhoneChanged
|
||||
| UpdateFlag::UserCanShareContact;
|
||||
| UpdateFlag::UserCanShareContact
|
||||
| UpdateFlag::UserCommonChatsChanged;
|
||||
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) {
|
||||
notifyPeerUpdated(update);
|
||||
}));
|
||||
|
||||
refreshLabels();
|
||||
if (_commonGroups && _commonGroups->isHidden()) {
|
||||
_commonGroups->show();
|
||||
refreshVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
void InfoWidget::showFinished() {
|
||||
_showFinished = true;
|
||||
if (_commonGroups && _commonGroups->isHidden() && getCommonGroupsCount() > 0) {
|
||||
_commonGroups->show();
|
||||
refreshVisibility();
|
||||
_height.start([this] { contentSizeUpdated(); }, isHidden() ? 0 : height(), resizeGetHeight(width()), st::widgetSlideDuration);
|
||||
contentSizeUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
void InfoWidget::restoreState(const SectionMemento *memento) {
|
||||
if (!memento->getCommonGroups().isEmpty()) {
|
||||
onForceHideCommonGroups();
|
||||
}
|
||||
}
|
||||
|
||||
void InfoWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
||||
|
@ -58,13 +86,17 @@ void InfoWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
|||
if (update.flags & (UpdateFlag::UserPhoneChanged | UpdateFlag::UserCanShareContact)) {
|
||||
refreshMobileNumber();
|
||||
}
|
||||
if (update.flags & UpdateFlag::UserCommonChatsChanged) {
|
||||
refreshCommonGroups();
|
||||
}
|
||||
refreshVisibility();
|
||||
|
||||
contentSizeUpdated();
|
||||
}
|
||||
|
||||
int InfoWidget::resizeGetHeight(int newWidth) {
|
||||
int newHeight = contentTop();
|
||||
int initialHeight = contentTop();
|
||||
int newHeight = initialHeight;
|
||||
|
||||
int marginLeft = st::profileBlockTextPart.margin.left();
|
||||
int marginRight = st::profileBlockTextPart.margin.right();
|
||||
|
@ -109,8 +141,18 @@ int InfoWidget::resizeGetHeight(int newWidth) {
|
|||
moveLabeledText(_mobileNumberLabel, _mobileNumber, nullptr);
|
||||
moveLabeledText(_usernameLabel, _username, nullptr);
|
||||
|
||||
if (_commonGroups && !_commonGroups->isHidden()) {
|
||||
int left = defaultOutlineButtonLeft();
|
||||
int availableWidth = newWidth - left - st::profileBlockMarginRight;
|
||||
accumulate_min(availableWidth, st::profileBlockOneLineWidthMax);
|
||||
|
||||
_commonGroups->resizeToWidth(availableWidth);
|
||||
_commonGroups->moveToLeft(left, newHeight);
|
||||
newHeight += _commonGroups->height();
|
||||
}
|
||||
|
||||
newHeight += st::profileBlockMarginBottom;
|
||||
return newHeight;
|
||||
return _height.animating() ? _height.current() : newHeight;
|
||||
}
|
||||
|
||||
void InfoWidget::leaveEvent(QEvent *e) {
|
||||
|
@ -123,12 +165,13 @@ void InfoWidget::refreshLabels() {
|
|||
refreshMobileNumber();
|
||||
refreshUsername();
|
||||
refreshChannelLink();
|
||||
refreshCommonGroups();
|
||||
|
||||
refreshVisibility();
|
||||
}
|
||||
|
||||
void InfoWidget::refreshVisibility() {
|
||||
setVisible(_about || _mobileNumber || _username || _channelLink);
|
||||
setVisible(_about || _mobileNumber || _username || _channelLink || (_commonGroups && !_commonGroups->isHidden()));
|
||||
}
|
||||
|
||||
void InfoWidget::refreshAbout() {
|
||||
|
@ -198,6 +241,84 @@ void InfoWidget::refreshChannelLink() {
|
|||
}
|
||||
}
|
||||
|
||||
int InfoWidget::getCommonGroupsCount() const {
|
||||
if (auto user = peer()->asUser()) {
|
||||
return user->commonChatsCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InfoWidget::refreshCommonGroups() {
|
||||
if (auto count = (_forceHiddenCommonGroups ? 0 : getCommonGroupsCount())) {
|
||||
auto text = lng_profile_common_groups(lt_count, count);
|
||||
if (_commonGroups) {
|
||||
_commonGroups->setText(text);
|
||||
} else {
|
||||
_commonGroups.create(this, text, st::defaultLeftOutlineButton);
|
||||
_commonGroups->setClickedCallback([this] { onShowCommonGroups(); });
|
||||
_commonGroups->hide();
|
||||
if (_showFinished) {
|
||||
_height.start([this] { contentSizeUpdated(); }, isHidden() ? 0 : height(), resizeGetHeight(width()), st::widgetSlideDuration);
|
||||
contentSizeUpdated();
|
||||
}
|
||||
}
|
||||
} else if (_commonGroups) {
|
||||
_commonGroups.destroyDelayed();
|
||||
}
|
||||
}
|
||||
|
||||
void InfoWidget::setShowCommonGroupsObservable(base::Observable<CommonGroupsEvent> *observable) {
|
||||
_showCommonGroupsObservable = observable;
|
||||
subscribe(_showCommonGroupsObservable, [this](const CommonGroupsEvent &event) {
|
||||
onForceHideCommonGroups();
|
||||
});
|
||||
}
|
||||
|
||||
void InfoWidget::onForceHideCommonGroups() {
|
||||
if (_forceHiddenCommonGroups) {
|
||||
return;
|
||||
}
|
||||
_forceHiddenCommonGroups = true;
|
||||
_commonGroups.destroyDelayed();
|
||||
refreshVisibility();
|
||||
contentSizeUpdated();
|
||||
}
|
||||
|
||||
void InfoWidget::onShowCommonGroups() {
|
||||
auto count = getCommonGroupsCount();
|
||||
if (count <= 0) {
|
||||
refreshCommonGroups();
|
||||
return;
|
||||
}
|
||||
if (_getCommonGroupsRequestId) {
|
||||
return;
|
||||
}
|
||||
auto user = peer()->asUser();
|
||||
t_assert(user != nullptr);
|
||||
auto request = MTPmessages_GetCommonChats(user->inputUser, MTP_int(0), MTP_int(kCommonGroupsLimit));
|
||||
_getCommonGroupsRequestId = MTP::send(request, ::rpcDone(base::lambda_guarded(this, [this](const MTPmessages_Chats &result) {
|
||||
_getCommonGroupsRequestId = 0;
|
||||
|
||||
CommonGroupsEvent event;
|
||||
if (auto chats = Api::getChatsFromMessagesChats(result)) {
|
||||
auto &list = chats->c_vector().v;
|
||||
event.groups.reserve(list.size());
|
||||
for_const (auto &chatData, list) {
|
||||
if (auto chat = App::feedChat(chatData)) {
|
||||
event.groups.push_back(chat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto oldHeight = height();
|
||||
onForceHideCommonGroups();
|
||||
if (!event.groups.empty() && _showCommonGroupsObservable) {
|
||||
event.initialHeight = oldHeight - (isHidden() ? 0 : height());
|
||||
_showCommonGroupsObservable->notify(event, true);
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
||||
void InfoWidget::setLabeledText(ChildWidget<Ui::FlatLabel> *labelWidget, const QString &label,
|
||||
ChildWidget<Ui::FlatLabel> *textWidget, const TextWithEntities &textWithEntities, const QString ©Text) {
|
||||
if (labelWidget) labelWidget->destroy();
|
|
@ -30,12 +30,23 @@ namespace Notify {
|
|||
struct PeerUpdate;
|
||||
} // namespace Notify
|
||||
|
||||
namespace Ui {
|
||||
class LeftOutlineButton;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Profile {
|
||||
|
||||
class InfoWidget : public BlockWidget {
|
||||
struct CommonGroupsEvent;
|
||||
class InfoWidget : public BlockWidget, public RPCSender {
|
||||
public:
|
||||
InfoWidget(QWidget *parent, PeerData *peer);
|
||||
|
||||
void setShowCommonGroupsObservable(base::Observable<CommonGroupsEvent> *observable);
|
||||
|
||||
void showFinished() override;
|
||||
|
||||
void restoreState(const SectionMemento *memento) override;
|
||||
|
||||
protected:
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
@ -51,8 +62,13 @@ private:
|
|||
void refreshMobileNumber();
|
||||
void refreshUsername();
|
||||
void refreshChannelLink();
|
||||
void refreshCommonGroups();
|
||||
void refreshVisibility();
|
||||
|
||||
int getCommonGroupsCount() const;
|
||||
void onForceHideCommonGroups();
|
||||
void onShowCommonGroups();
|
||||
|
||||
// labelWidget may be nullptr.
|
||||
void setLabeledText(ChildWidget<Ui::FlatLabel> *labelWidget, const QString &label,
|
||||
ChildWidget<Ui::FlatLabel> *textWidget, const TextWithEntities &textWithEntities, const QString ©Text);
|
||||
|
@ -65,6 +81,15 @@ private:
|
|||
ChildWidget<Ui::FlatLabel> _mobileNumber = { nullptr };
|
||||
ChildWidget<Ui::FlatLabel> _usernameLabel = { nullptr };
|
||||
ChildWidget<Ui::FlatLabel> _username = { nullptr };
|
||||
ChildWidget<Ui::LeftOutlineButton> _commonGroups = { nullptr };
|
||||
|
||||
IntAnimation _height;
|
||||
bool _showFinished = false;
|
||||
|
||||
bool _forceHiddenCommonGroups = false;
|
||||
mtpRequestId _getCommonGroupsRequestId = 0;
|
||||
|
||||
base::Observable<CommonGroupsEvent> *_showCommonGroupsObservable = nullptr;
|
||||
|
||||
};
|
||||
|
|
@ -19,7 +19,7 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
|||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_invite_link_widget.h"
|
||||
#include "profile/profile_block_invite_link.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "ui/widgets/labels.h"
|
241
Telegram/SourceFiles/profile/profile_block_peer_list.cpp
Normal file
241
Telegram/SourceFiles/profile/profile_block_peer_list.cpp
Normal file
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_block_peer_list.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
PeerListWidget::PeerListWidget(QWidget *parent, PeerData *peer, const QString &title, const QString &removeText)
|
||||
: BlockWidget(parent, peer, title)
|
||||
, _removeText(removeText)
|
||||
, _removeWidth(st::normalFont->width(_removeText)) {
|
||||
setMouseTracking(true);
|
||||
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
|
||||
}
|
||||
|
||||
int PeerListWidget::resizeGetHeight(int newWidth) {
|
||||
auto newHeight = getListTop();
|
||||
|
||||
newHeight += _items.size() * st::profileMemberHeight;
|
||||
|
||||
return newHeight + st::profileBlockMarginBottom;
|
||||
}
|
||||
|
||||
void PeerListWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
_visibleTop = visibleTop;
|
||||
_visibleBottom = visibleBottom;
|
||||
|
||||
if (_preloadMoreCallback) {
|
||||
if (_visibleTop + PreloadHeightsCount * (_visibleBottom - _visibleTop) > height()) {
|
||||
_preloadMoreCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PeerListWidget::paintContents(Painter &p) {
|
||||
int left = getListLeft();
|
||||
int top = getListTop();
|
||||
int memberRowWidth = width() - left;
|
||||
accumulate_min(memberRowWidth, st::profileBlockWideWidthMax);
|
||||
|
||||
int from = floorclamp(_visibleTop - top, st::profileMemberHeight, 0, _items.size());
|
||||
int to = ceilclamp(_visibleBottom - top, st::profileMemberHeight, 0, _items.size());
|
||||
for (int i = from; i < to; ++i) {
|
||||
int y = top + i * st::profileMemberHeight;
|
||||
bool selected = (i == _selected);
|
||||
bool selectedRemove = selected && _selectedRemove;
|
||||
if (_pressed >= 0) {
|
||||
if (_pressed != _selected) {
|
||||
selected = selectedRemove = false;
|
||||
} else if (!_pressedRemove) {
|
||||
_selectedRemove = false;
|
||||
}
|
||||
}
|
||||
paintItem(p, left, y, _items[i], selected, selectedRemove);
|
||||
}
|
||||
}
|
||||
|
||||
void PeerListWidget::paintItem(Painter &p, int x, int y, Item *item, bool selected, bool selectedKick) {
|
||||
if (_updateItemCallback) {
|
||||
_updateItemCallback(item);
|
||||
}
|
||||
|
||||
int memberRowWidth = width() - x;
|
||||
if (selected) {
|
||||
accumulate_min(memberRowWidth, st::profileBlockWideWidthMax);
|
||||
paintOutlinedRect(p, x, y, memberRowWidth, st::profileMemberHeight);
|
||||
}
|
||||
int skip = st::profileMemberPhotoPosition.x();
|
||||
|
||||
item->peer->paintUserpicLeft(p, st::profileMemberPhotoSize, x + st::profileMemberPhotoPosition.x(), y + st::profileMemberPhotoPosition.y(), width());
|
||||
|
||||
if (item->name.isEmpty()) {
|
||||
item->name.setText(st::semiboldFont, App::peerName(item->peer), _textNameOptions);
|
||||
}
|
||||
int nameLeft = x + st::profileMemberNamePosition.x();
|
||||
int nameTop = y + st::profileMemberNamePosition.y();
|
||||
int nameWidth = memberRowWidth - st::profileMemberNamePosition.x() - skip;
|
||||
if (item->hasRemoveLink && selected) {
|
||||
p.setFont(selectedKick ? st::normalFont->underline() : st::normalFont);
|
||||
p.setPen(st::windowActiveTextFg);
|
||||
p.drawTextLeft(nameLeft + nameWidth - _removeWidth, nameTop, width(), _removeText, _removeWidth);
|
||||
nameWidth -= _removeWidth + skip;
|
||||
}
|
||||
if (item->hasAdminStar) {
|
||||
nameWidth -= st::profileMemberAdminIcon.width();
|
||||
int iconLeft = nameLeft + qMin(nameWidth, item->name.maxWidth());
|
||||
st::profileMemberAdminIcon.paint(p, QPoint(iconLeft, nameTop), width());
|
||||
}
|
||||
p.setPen(st::profileMemberNameFg);
|
||||
item->name.drawLeftElided(p, nameLeft, nameTop, nameWidth, width());
|
||||
|
||||
if (item->statusHasOnlineColor) {
|
||||
p.setPen(st::profileMemberStatusFgActive);
|
||||
} else {
|
||||
p.setPen(selected ? st::profileMemberStatusFgOver : st::profileMemberStatusFg);
|
||||
}
|
||||
p.setFont(st::normalFont);
|
||||
p.drawTextLeft(x + st::profileMemberStatusPosition.x(), y + st::profileMemberStatusPosition.y(), width(), item->statusText);
|
||||
}
|
||||
|
||||
void PeerListWidget::paintOutlinedRect(Painter &p, int x, int y, int w, int h) const {
|
||||
int outlineWidth = st::defaultLeftOutlineButton.outlineWidth;
|
||||
p.fillRect(rtlrect(x, y, outlineWidth, h, width()), st::defaultLeftOutlineButton.outlineFgOver);
|
||||
p.fillRect(rtlrect(x + outlineWidth, y, w - outlineWidth, h, width()), st::defaultLeftOutlineButton.textBgOver);
|
||||
}
|
||||
|
||||
void PeerListWidget::mouseMoveEvent(QMouseEvent *e) {
|
||||
_mousePosition = e->globalPos();
|
||||
updateSelection();
|
||||
}
|
||||
|
||||
void PeerListWidget::mousePressEvent(QMouseEvent *e) {
|
||||
_mousePosition = e->globalPos();
|
||||
updateSelection();
|
||||
|
||||
_pressed = _selected;
|
||||
_pressedRemove = _selectedRemove;
|
||||
}
|
||||
|
||||
void PeerListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||
_mousePosition = e->globalPos();
|
||||
updateSelection();
|
||||
|
||||
auto pressed = _pressed;
|
||||
auto pressedRemove = _pressedRemove;
|
||||
_pressed = -1;
|
||||
_pressedRemove = false;
|
||||
if (pressed >= 0 && pressed < _items.size() && pressed == _selected && pressedRemove == _selectedRemove) {
|
||||
if (auto &callback = (pressedRemove ? _removedCallback : _selectedCallback)) {
|
||||
callback(_items[pressed]->peer);
|
||||
}
|
||||
}
|
||||
setCursor(_selectedRemove ? style::cur_pointer : style::cur_default);
|
||||
repaintSelectedRow();
|
||||
}
|
||||
|
||||
void PeerListWidget::enterEvent(QEvent *e) {
|
||||
_mousePosition = QCursor::pos();
|
||||
updateSelection();
|
||||
}
|
||||
|
||||
void PeerListWidget::leaveEvent(QEvent *e) {
|
||||
_mousePosition = QPoint(-1, -1);
|
||||
updateSelection();
|
||||
}
|
||||
|
||||
void PeerListWidget::updateSelection() {
|
||||
int selected = -1;
|
||||
bool selectedKick = false;
|
||||
|
||||
auto mouse = mapFromGlobal(_mousePosition);
|
||||
if (rtl()) mouse.setX(width() - mouse.x());
|
||||
int left = getListLeft();
|
||||
int top = getListTop();
|
||||
int memberRowWidth = width() - left;
|
||||
accumulate_min(memberRowWidth, st::profileBlockWideWidthMax);
|
||||
if (mouse.x() >= left && mouse.x() < left + memberRowWidth && mouse.y() >= top) {
|
||||
selected = (mouse.y() - top) / st::profileMemberHeight;
|
||||
if (selected >= _items.size()) {
|
||||
selected = -1;
|
||||
} else if (_items[selected]->hasRemoveLink) {
|
||||
int skip = st::profileMemberPhotoPosition.x();
|
||||
int nameLeft = left + st::profileMemberNamePosition.x();
|
||||
int nameTop = top + _selected * st::profileMemberHeight + st::profileMemberNamePosition.y();
|
||||
int nameWidth = memberRowWidth - st::profileMemberNamePosition.x() - skip;
|
||||
if (mouse.x() >= nameLeft + nameWidth - _removeWidth && mouse.x() < nameLeft + nameWidth) {
|
||||
if (mouse.y() >= nameTop && mouse.y() < nameTop + st::normalFont->height) {
|
||||
selectedKick = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setSelected(selected, selectedKick);
|
||||
}
|
||||
|
||||
void PeerListWidget::setSelected(int selected, bool selectedRemove) {
|
||||
if (_selected == selected && _selectedRemove == selectedRemove) {
|
||||
return;
|
||||
}
|
||||
|
||||
repaintSelectedRow();
|
||||
if (_selectedRemove != selectedRemove) {
|
||||
_selectedRemove = selectedRemove;
|
||||
if (_pressed < 0) {
|
||||
setCursor(_selectedRemove ? style::cur_pointer : style::cur_default);
|
||||
}
|
||||
}
|
||||
if (_selected != selected) {
|
||||
_selected = selected;
|
||||
repaintSelectedRow();
|
||||
}
|
||||
}
|
||||
|
||||
void PeerListWidget::repaintSelectedRow() {
|
||||
if (_selected >= 0) {
|
||||
int left = getListLeft();
|
||||
rtlupdate(left, getListTop() + _selected * st::profileMemberHeight, width() - left, st::profileMemberHeight);
|
||||
}
|
||||
}
|
||||
|
||||
int PeerListWidget::getListLeft() const {
|
||||
return st::profileBlockTitlePosition.x() - st::profileMemberPaddingLeft;
|
||||
}
|
||||
|
||||
void PeerListWidget::preloadPhotos() {
|
||||
int top = getListTop();
|
||||
int preloadFor = (_visibleBottom - _visibleTop) * PreloadHeightsCount;
|
||||
int from = floorclamp(_visibleTop - top, st::profileMemberHeight, 0, _items.size());
|
||||
int to = ceilclamp(_visibleBottom + preloadFor - top, st::profileMemberHeight, 0, _items.size());
|
||||
for (int i = from; i < to; ++i) {
|
||||
_items[i]->peer->loadUserpic();
|
||||
}
|
||||
}
|
||||
|
||||
void PeerListWidget::refreshVisibility() {
|
||||
setVisible(!_items.isEmpty());
|
||||
}
|
||||
|
||||
} // namespace Profile
|
139
Telegram/SourceFiles/profile/profile_block_peer_list.h
Normal file
139
Telegram/SourceFiles/profile/profile_block_peer_list.h
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "profile/profile_block_widget.h"
|
||||
|
||||
namespace Notify {
|
||||
struct PeerUpdate;
|
||||
} // namespace Notify
|
||||
|
||||
namespace Profile {
|
||||
|
||||
class PeerListWidget : public BlockWidget {
|
||||
public:
|
||||
PeerListWidget(QWidget *parent, PeerData *peer, const QString &title, const QString &removeText = QString());
|
||||
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
|
||||
struct Item {
|
||||
explicit Item(PeerData *peer) : peer(peer) {
|
||||
}
|
||||
PeerData * const peer;
|
||||
Text name;
|
||||
QString statusText;
|
||||
bool statusHasOnlineColor = false;
|
||||
bool hasAdminStar = false;
|
||||
bool hasRemoveLink = false;
|
||||
};
|
||||
virtual int getListTop() const {
|
||||
return contentTop();
|
||||
}
|
||||
|
||||
int getListLeft() const;
|
||||
|
||||
const QList<Item*> &items() const {
|
||||
return _items;
|
||||
}
|
||||
int itemsCount() const {
|
||||
return _items.size();
|
||||
}
|
||||
|
||||
// Does not take ownership of item.
|
||||
void addItem(Item *item) {
|
||||
if (!item) return;
|
||||
_items.push_back(item);
|
||||
}
|
||||
void clearItems() {
|
||||
_items.clear();
|
||||
}
|
||||
void reserveItemsForSize(int size) {
|
||||
_items.reserve(size);
|
||||
}
|
||||
template <typename Predicate>
|
||||
void sortItems(Predicate predicate) {
|
||||
qSort(_items.begin(), _items.end(), std_::move(predicate));
|
||||
}
|
||||
|
||||
void setPreloadMoreCallback(base::lambda<void()> &&callback) {
|
||||
_preloadMoreCallback = std_::move(callback);
|
||||
}
|
||||
void setSelectedCallback(base::lambda<void(PeerData*)> &&callback) {
|
||||
_selectedCallback = std_::move(callback);
|
||||
}
|
||||
void setRemovedCallback(base::lambda<void(PeerData*)> &&callback) {
|
||||
_removedCallback = std_::move(callback);
|
||||
}
|
||||
void setUpdateItemCallback(base::lambda<void(Item*)> &&callback) {
|
||||
_updateItemCallback = std_::move(callback);
|
||||
}
|
||||
|
||||
protected:
|
||||
void paintOutlinedRect(Painter &p, int x, int y, int w, int h) const;
|
||||
void refreshVisibility();
|
||||
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
void paintContents(Painter &p) override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void enterEvent(QEvent *e) override;
|
||||
void enterFromChildEvent(QEvent *e, QWidget *child) override {
|
||||
enterEvent(e);
|
||||
}
|
||||
void leaveEvent(QEvent *e) override;
|
||||
void leaveToChildEvent(QEvent *e, QWidget *child) override {
|
||||
leaveEvent(e);
|
||||
}
|
||||
|
||||
private:
|
||||
void updateSelection();
|
||||
void setSelected(int selected, bool selectedRemove);
|
||||
void repaintSelectedRow();
|
||||
void preloadPhotos();
|
||||
|
||||
void paintItem(Painter &p, int x, int y, Item *item, bool selected, bool selectedRemove);
|
||||
|
||||
base::lambda<void()> _preloadMoreCallback;
|
||||
base::lambda<void(PeerData*)> _selectedCallback;
|
||||
base::lambda<void(PeerData*)> _removedCallback;
|
||||
base::lambda<void(Item*)> _updateItemCallback;
|
||||
|
||||
QList<Item*> _items;
|
||||
|
||||
int _visibleTop = 0;
|
||||
int _visibleBottom = 0;
|
||||
|
||||
int _selected = -1;
|
||||
int _pressed = -1;
|
||||
bool _selectedRemove = false;
|
||||
bool _pressedRemove = false;
|
||||
QPoint _mousePosition;
|
||||
|
||||
QString _removeText;
|
||||
int _removeWidth = 0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Profile
|
|
@ -19,7 +19,7 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
|||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_settings_widget.h"
|
||||
#include "profile/profile_block_settings.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "ui/widgets/buttons.h"
|
|
@ -19,7 +19,7 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
|||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_shared_media_widget.h"
|
||||
#include "profile/profile_block_shared_media.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "observer_peer.h"
|
|
@ -24,12 +24,22 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
|
||||
namespace Profile {
|
||||
|
||||
class SectionMemento;
|
||||
|
||||
class BlockWidget : public TWidget, protected base::Subscriber {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BlockWidget(QWidget *parent, PeerData *peer, const QString &title);
|
||||
|
||||
virtual void showFinished() {
|
||||
}
|
||||
|
||||
virtual void saveState(SectionMemento *memento) const {
|
||||
}
|
||||
virtual void restoreState(const SectionMemento *memento) {
|
||||
}
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
virtual void paintContents(Painter &p) {
|
||||
|
@ -42,6 +52,7 @@ protected:
|
|||
int resizeGetHeight(int newWidth) override = 0;
|
||||
|
||||
void contentSizeUpdated() {
|
||||
auto oldHeight = height();
|
||||
resizeToWidth(width());
|
||||
emit heightUpdated();
|
||||
}
|
||||
|
|
|
@ -24,12 +24,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "styles/style_profile.h"
|
||||
#include "styles/style_window.h"
|
||||
#include "profile/profile_cover.h"
|
||||
#include "profile/profile_info_widget.h"
|
||||
#include "profile/profile_settings_widget.h"
|
||||
#include "profile/profile_invite_link_widget.h"
|
||||
#include "profile/profile_shared_media_widget.h"
|
||||
#include "profile/profile_actions_widget.h"
|
||||
#include "profile/profile_members_widget.h"
|
||||
#include "profile/profile_block_common_groups.h"
|
||||
#include "profile/profile_block_info.h"
|
||||
#include "profile/profile_block_settings.h"
|
||||
#include "profile/profile_block_invite_link.h"
|
||||
#include "profile/profile_block_shared_media.h"
|
||||
#include "profile/profile_block_actions.h"
|
||||
#include "profile/profile_block_channel_members.h"
|
||||
#include "profile/profile_block_group_members.h"
|
||||
#include "apiwrap.h"
|
||||
|
||||
namespace Profile {
|
||||
|
@ -48,7 +50,16 @@ void InnerWidget::createBlocks() {
|
|||
auto channel = _peer->asChannel();
|
||||
auto megagroup = _peer->isMegagroup() ? channel : nullptr;
|
||||
if (user || channel || megagroup) {
|
||||
_blocks.push_back({ new InfoWidget(this, _peer), BlockSide::Right });
|
||||
auto widget = new InfoWidget(this, _peer);
|
||||
widget->setShowCommonGroupsObservable(&_showCommonGroupsObservable);
|
||||
_blocks.push_back({ widget, BlockSide::Right });
|
||||
}
|
||||
if (user) {
|
||||
_commonGroupsWidget = new CommonGroupsWidget(this, _peer);
|
||||
_commonGroupsWidget->setShowCommonGroupsObservable(&_showCommonGroupsObservable);
|
||||
_blocks.push_back({ _commonGroupsWidget, BlockSide::Right });
|
||||
} else {
|
||||
_commonGroupsWidget = nullptr;
|
||||
}
|
||||
_blocks.push_back({ new SettingsWidget(this, _peer), BlockSide::Right });
|
||||
if (chat || channel || megagroup) {
|
||||
|
@ -60,7 +71,7 @@ void InnerWidget::createBlocks() {
|
|||
}
|
||||
_blocks.push_back({ new ActionsWidget(this, _peer), BlockSide::Right });
|
||||
if (chat || megagroup) {
|
||||
auto membersWidget = new MembersWidget(this, _peer);
|
||||
auto membersWidget = new GroupMembersWidget(this, _peer);
|
||||
connect(membersWidget, SIGNAL(onlineCountUpdated(int)), _cover, SLOT(onOnlineCountUpdated(int)));
|
||||
_cover->onOnlineCountUpdated(membersWidget->onlineCount());
|
||||
_blocks.push_back({ membersWidget, BlockSide::Left });
|
||||
|
@ -89,8 +100,23 @@ bool InnerWidget::shareContactButtonShown() const {
|
|||
return _cover->shareContactButtonShown();
|
||||
}
|
||||
|
||||
void InnerWidget::saveState(SectionMemento *memento) const {
|
||||
for_const (auto &blockData, _blocks) {
|
||||
blockData.block->saveState(memento);
|
||||
}
|
||||
}
|
||||
|
||||
void InnerWidget::restoreState(const SectionMemento *memento) {
|
||||
for_const (auto &blockData, _blocks) {
|
||||
blockData.block->restoreState(memento);
|
||||
}
|
||||
}
|
||||
|
||||
void InnerWidget::showFinished() {
|
||||
_cover->showFinished();
|
||||
for_const (auto &blockData, _blocks) {
|
||||
blockData.block->showFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void InnerWidget::decreaseAdditionalHeight(int removeHeight) {
|
||||
|
@ -182,6 +208,8 @@ void InnerWidget::refreshBlocksPositions() {
|
|||
continue;
|
||||
}
|
||||
blockData.block->moveToLeft(left, top);
|
||||
blockData.block->setVisibleTopBottom(_visibleTop - top, _visibleBottom - top);
|
||||
|
||||
top += blockData.block->height();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -20,10 +20,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "profile/profile_block_common_groups.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
class CoverWidget;
|
||||
class BlockWidget;
|
||||
struct CommonGroupsEvent;
|
||||
class SectionMemento;
|
||||
|
||||
class InnerWidget final : public TWidget {
|
||||
Q_OBJECT
|
||||
|
@ -48,6 +52,9 @@ public:
|
|||
// It should show it only if it is hidden in the cover.
|
||||
bool shareContactButtonShown() const;
|
||||
|
||||
void saveState(SectionMemento *memento) const;
|
||||
void restoreState(const SectionMemento *memento);
|
||||
|
||||
void showFinished();
|
||||
|
||||
signals:
|
||||
|
@ -110,7 +117,12 @@ private:
|
|||
};
|
||||
QList<Block> _blocks;
|
||||
|
||||
// We need to save this pointer for getting common groups list for section memento.
|
||||
CommonGroupsWidget *_commonGroupsWidget = nullptr;
|
||||
|
||||
Mode _mode = Mode::OneColumn;
|
||||
|
||||
base::Observable<CommonGroupsEvent> _showCommonGroupsObservable;
|
||||
};
|
||||
|
||||
} // namespace Profile
|
||||
|
|
|
@ -1,713 +0,0 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_members_widget.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "mtproto/file_download.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "boxes/contactsbox.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "apiwrap.h"
|
||||
#include "mainwidget.h"
|
||||
#include "observer_peer.h"
|
||||
#include "lang.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
using UpdateFlag = Notify::PeerUpdate::Flag;
|
||||
|
||||
MembersWidget::MembersWidget(QWidget *parent, PeerData *peer, TitleVisibility titleVisibility)
|
||||
: BlockWidget(parent, peer, (titleVisibility == TitleVisibility::Visible) ? lang(lng_profile_participants_section) : QString()) {
|
||||
setMouseTracking(true);
|
||||
|
||||
_removeWidth = st::normalFont->width(lang(lng_profile_kick));
|
||||
|
||||
_updateOnlineTimer.setSingleShot(true);
|
||||
connect(&_updateOnlineTimer, SIGNAL(timeout()), this, SLOT(onUpdateOnlineDisplay()));
|
||||
|
||||
auto observeEvents = UpdateFlag::AdminsChanged
|
||||
| UpdateFlag::MembersChanged
|
||||
| UpdateFlag::UserOnlineChanged;
|
||||
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) {
|
||||
notifyPeerUpdated(update);
|
||||
}));
|
||||
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
|
||||
|
||||
refreshMembers();
|
||||
}
|
||||
|
||||
void MembersWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
||||
if (update.peer != peer()) {
|
||||
if (update.flags & UpdateFlag::UserOnlineChanged) {
|
||||
if (auto user = update.peer->asUser()) {
|
||||
refreshUserOnline(user);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (update.flags & UpdateFlag::MembersChanged) {
|
||||
refreshMembers();
|
||||
contentSizeUpdated();
|
||||
} else if (update.flags & UpdateFlag::AdminsChanged) {
|
||||
if (auto chat = peer()->asChat()) {
|
||||
for_const (auto member, _list) {
|
||||
setMemberFlags(member, chat);
|
||||
}
|
||||
} else if (auto megagroup = peer()->asMegagroup()) {
|
||||
for_const (auto member, _list) {
|
||||
setMemberFlags(member, megagroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
this->update();
|
||||
}
|
||||
|
||||
void MembersWidget::refreshUserOnline(UserData *user) {
|
||||
auto it = _membersByUser.find(user);
|
||||
if (it == _membersByUser.cend()) return;
|
||||
|
||||
_now = unixtime();
|
||||
|
||||
auto member = it.value();
|
||||
member->online = !user->botInfo && App::onlineColorUse(user->onlineTill, _now);
|
||||
member->onlineTill = user->onlineTill;
|
||||
member->onlineForSort = user->isSelf() ? INT_MAX : App::onlineForSort(user, _now);
|
||||
member->onlineText = QString();
|
||||
|
||||
sortMembers();
|
||||
update();
|
||||
}
|
||||
|
||||
void MembersWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
_visibleTop = visibleTop;
|
||||
_visibleBottom = visibleBottom;
|
||||
|
||||
if (auto megagroup = peer()->asMegagroup()) {
|
||||
auto megagroupInfo = megagroup->mgInfo;
|
||||
if (!megagroupInfo->lastParticipants.isEmpty() && megagroupInfo->lastParticipants.size() < megagroup->membersCount()) {
|
||||
if (_visibleTop + PreloadHeightsCount * (_visibleBottom - _visibleTop) > height()) {
|
||||
App::api()->requestLastParticipants(megagroup, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
preloadUserPhotos();
|
||||
}
|
||||
|
||||
int MembersWidget::resizeGetHeight(int newWidth) {
|
||||
int newHeight = contentTop();
|
||||
|
||||
if (_limitReachedInfo) {
|
||||
int limitReachedInfoWidth = newWidth - getListLeft();
|
||||
accumulate_min(limitReachedInfoWidth, st::profileBlockWideWidthMax);
|
||||
|
||||
_limitReachedInfo->resizeToWidth(limitReachedInfoWidth);
|
||||
_limitReachedInfo->moveToLeft(getListLeft(), contentTop());
|
||||
newHeight = getListTop();
|
||||
}
|
||||
|
||||
newHeight += _list.size() * st::profileMemberHeight;
|
||||
|
||||
return newHeight;
|
||||
}
|
||||
|
||||
void MembersWidget::paintContents(Painter &p) {
|
||||
int left = getListLeft();
|
||||
int top = getListTop();
|
||||
int memberRowWidth = width() - left;
|
||||
accumulate_min(memberRowWidth, st::profileBlockWideWidthMax);
|
||||
if (_limitReachedInfo) {
|
||||
int infoTop = contentTop();
|
||||
int infoHeight = top - infoTop - st::profileLimitReachedSkip;
|
||||
paintOutlinedRect(p, left, infoTop, memberRowWidth, infoHeight);
|
||||
}
|
||||
|
||||
_now = unixtime();
|
||||
int from = floorclamp(_visibleTop - top, st::profileMemberHeight, 0, _list.size());
|
||||
int to = ceilclamp(_visibleBottom - top, st::profileMemberHeight, 0, _list.size());
|
||||
for (int i = from; i < to; ++i) {
|
||||
int y = top + i * st::profileMemberHeight;
|
||||
bool selected = (i == _selected);
|
||||
bool selectedKick = selected && _selectedKick;
|
||||
if (_pressed >= 0) {
|
||||
if (_pressed != _selected) {
|
||||
selected = selectedKick = false;
|
||||
} else if (!_pressedKick) {
|
||||
_selectedKick = false;
|
||||
}
|
||||
}
|
||||
paintMember(p, left, y, _list.at(i), selected, selectedKick);
|
||||
}
|
||||
}
|
||||
|
||||
void MembersWidget::paintOutlinedRect(Painter &p, int x, int y, int w, int h) const {
|
||||
int outlineWidth = st::defaultLeftOutlineButton.outlineWidth;
|
||||
p.fillRect(rtlrect(x, y, outlineWidth, h, width()), st::defaultLeftOutlineButton.outlineFgOver);
|
||||
p.fillRect(rtlrect(x + outlineWidth, y, w - outlineWidth, h, width()), st::defaultLeftOutlineButton.textBgOver);
|
||||
}
|
||||
|
||||
void MembersWidget::mouseMoveEvent(QMouseEvent *e) {
|
||||
_mousePosition = e->globalPos();
|
||||
updateSelection();
|
||||
}
|
||||
|
||||
void MembersWidget::mousePressEvent(QMouseEvent *e) {
|
||||
_mousePosition = e->globalPos();
|
||||
updateSelection();
|
||||
|
||||
_pressed = _selected;
|
||||
_pressedKick = _selectedKick;
|
||||
}
|
||||
|
||||
void MembersWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||
_mousePosition = e->globalPos();
|
||||
updateSelection();
|
||||
|
||||
auto pressed = _pressed;
|
||||
auto pressedKick = _pressedKick;
|
||||
_pressed = -1;
|
||||
_pressedKick = false;
|
||||
if (pressed >= 0 && pressed < _list.size() && pressed == _selected && pressedKick == _selectedKick) {
|
||||
auto member = _list.at(pressed);
|
||||
if (pressedKick) {
|
||||
Ui::showLayer(new KickMemberBox(peer(), member->user));
|
||||
} else {
|
||||
Ui::showPeerProfile(member->user);
|
||||
}
|
||||
}
|
||||
setCursor(_selectedKick ? style::cur_pointer : style::cur_default);
|
||||
repaintSelectedRow();
|
||||
}
|
||||
|
||||
void MembersWidget::enterEvent(QEvent *e) {
|
||||
_mousePosition = QCursor::pos();
|
||||
updateSelection();
|
||||
}
|
||||
|
||||
void MembersWidget::leaveEvent(QEvent *e) {
|
||||
_mousePosition = QPoint(-1, -1);
|
||||
updateSelection();
|
||||
}
|
||||
|
||||
void MembersWidget::updateSelection() {
|
||||
int selected = -1;
|
||||
bool selectedKick = false;
|
||||
|
||||
auto mouse = mapFromGlobal(_mousePosition);
|
||||
if (rtl()) mouse.setX(width() - mouse.x());
|
||||
int left = getListLeft();
|
||||
int top = getListTop();
|
||||
int memberRowWidth = width() - left;
|
||||
accumulate_min(memberRowWidth, st::profileBlockWideWidthMax);
|
||||
if (mouse.x() >= left && mouse.x() < left + memberRowWidth && mouse.y() >= top) {
|
||||
selected = (mouse.y() - top) / st::profileMemberHeight;
|
||||
if (selected >= _list.size()) {
|
||||
selected = -1;
|
||||
} else if (_list.at(selected)->canBeKicked) {
|
||||
int skip = st::profileMemberPhotoPosition.x();
|
||||
int nameLeft = left + st::profileMemberNamePosition.x();
|
||||
int nameTop = top + _selected * st::profileMemberHeight + st::profileMemberNamePosition.y();
|
||||
int nameWidth = memberRowWidth - st::profileMemberNamePosition.x() - skip;
|
||||
if (mouse.x() >= nameLeft + nameWidth - _removeWidth && mouse.x() < nameLeft + nameWidth) {
|
||||
if (mouse.y() >= nameTop && mouse.y() < nameTop + st::normalFont->height) {
|
||||
selectedKick = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setSelected(selected, selectedKick);
|
||||
}
|
||||
|
||||
void MembersWidget::setSelected(int selected, bool selectedKick) {
|
||||
if (_selected == selected && _selectedKick == selectedKick) {
|
||||
return;
|
||||
}
|
||||
|
||||
repaintSelectedRow();
|
||||
if (_selectedKick != selectedKick) {
|
||||
_selectedKick = selectedKick;
|
||||
if (_pressed < 0) {
|
||||
setCursor(_selectedKick ? style::cur_pointer : style::cur_default);
|
||||
}
|
||||
}
|
||||
if (_selected != selected) {
|
||||
_selected = selected;
|
||||
repaintSelectedRow();
|
||||
}
|
||||
}
|
||||
|
||||
void MembersWidget::repaintSelectedRow() {
|
||||
if (_selected >= 0) {
|
||||
int left = getListLeft();
|
||||
rtlupdate(left, getListTop() + _selected * st::profileMemberHeight, width() - left, st::profileMemberHeight);
|
||||
}
|
||||
}
|
||||
|
||||
int MembersWidget::getListLeft() const {
|
||||
return st::profileBlockTitlePosition.x() - st::profileMemberPaddingLeft;
|
||||
}
|
||||
|
||||
int MembersWidget::getListTop() const {
|
||||
int result = contentTop();
|
||||
if (_limitReachedInfo) {
|
||||
result += _limitReachedInfo->height();
|
||||
result += st::profileLimitReachedSkip;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void MembersWidget::refreshMembers() {
|
||||
_now = unixtime();
|
||||
if (auto chat = peer()->asChat()) {
|
||||
checkSelfAdmin(chat);
|
||||
if (chat->noParticipantInfo()) {
|
||||
App::api()->requestFullPeer(chat);
|
||||
}
|
||||
fillChatMembers(chat);
|
||||
refreshLimitReached();
|
||||
} else if (auto megagroup = peer()->asMegagroup()) {
|
||||
checkSelfAdmin(megagroup);
|
||||
auto megagroupInfo = megagroup->mgInfo;
|
||||
if (megagroupInfo->lastParticipants.isEmpty() || megagroup->lastParticipantsCountOutdated()) {
|
||||
App::api()->requestLastParticipants(megagroup);
|
||||
}
|
||||
fillMegagroupMembers(megagroup);
|
||||
}
|
||||
sortMembers();
|
||||
|
||||
refreshVisibility();
|
||||
}
|
||||
|
||||
void MembersWidget::refreshLimitReached() {
|
||||
auto chat = peer()->asChat();
|
||||
if (!chat) return;
|
||||
|
||||
bool limitReachedShown = (_list.size() >= Global::ChatSizeMax()) && chat->amCreator() && !emptyTitle();
|
||||
if (limitReachedShown && !_limitReachedInfo) {
|
||||
_limitReachedInfo.create(this, st::profileLimitReachedLabel, st::profileLimitReachedStyle);
|
||||
QString title = textRichPrepare(lng_profile_migrate_reached(lt_count, Global::ChatSizeMax()));
|
||||
QString body = textRichPrepare(lang(lng_profile_migrate_body));
|
||||
QString link = textRichPrepare(lang(lng_profile_migrate_learn_more));
|
||||
QString text = qsl("%1%2%3\n%4 [a href=\"https://telegram.org/blog/supergroups5k\"]%5[/a]").arg(textcmdStartSemibold()).arg(title).arg(textcmdStopSemibold()).arg(body).arg(link);
|
||||
_limitReachedInfo->setRichText(text);
|
||||
_limitReachedInfo->setClickHandlerHook([this](const ClickHandlerPtr &handler, Qt::MouseButton button) {
|
||||
Ui::showLayer(new ConvertToSupergroupBox(peer()->asChat()));
|
||||
return false;
|
||||
});
|
||||
} else if (!limitReachedShown && _limitReachedInfo) {
|
||||
_limitReachedInfo.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void MembersWidget::checkSelfAdmin(ChatData *chat) {
|
||||
if (chat->participants.isEmpty()) return;
|
||||
|
||||
auto self = App::self();
|
||||
if (chat->amAdmin() && !chat->admins.contains(self)) {
|
||||
chat->admins.insert(self);
|
||||
} else if (!chat->amAdmin() && chat->admins.contains(self)) {
|
||||
chat->admins.remove(self);
|
||||
}
|
||||
}
|
||||
|
||||
void MembersWidget::checkSelfAdmin(ChannelData *megagroup) {
|
||||
if (megagroup->mgInfo->lastParticipants.isEmpty()) return;
|
||||
|
||||
bool amAdmin = (megagroup->amCreator() || megagroup->amEditor());
|
||||
auto self = App::self();
|
||||
if (amAdmin && !megagroup->mgInfo->lastAdmins.contains(self)) {
|
||||
megagroup->mgInfo->lastAdmins.insert(self);
|
||||
} else if (!amAdmin && megagroup->mgInfo->lastAdmins.contains(self)) {
|
||||
megagroup->mgInfo->lastAdmins.remove(self);
|
||||
}
|
||||
}
|
||||
|
||||
void MembersWidget::preloadUserPhotos() {
|
||||
int top = getListTop();
|
||||
int preloadFor = (_visibleBottom - _visibleTop) * PreloadHeightsCount;
|
||||
int from = floorclamp(_visibleTop - top, st::profileMemberHeight, 0, _list.size());
|
||||
int to = ceilclamp(_visibleBottom + preloadFor - top, st::profileMemberHeight, 0, _list.size());
|
||||
for (int i = from; i < to; ++i) {
|
||||
_list.at(i)->user->loadUserpic();
|
||||
}
|
||||
}
|
||||
|
||||
void MembersWidget::refreshVisibility() {
|
||||
setVisible(!_list.isEmpty());
|
||||
}
|
||||
|
||||
void MembersWidget::sortMembers() {
|
||||
if (!_sortByOnline || _list.isEmpty()) return;
|
||||
|
||||
qSort(_list.begin(), _list.end(), [](Member *a, Member *b) -> bool {
|
||||
return a->onlineForSort > b->onlineForSort;
|
||||
});
|
||||
|
||||
updateOnlineCount();
|
||||
}
|
||||
|
||||
void MembersWidget::updateOnlineCount() {
|
||||
bool onlyMe = true;
|
||||
int newOnlineCount = 0;
|
||||
for_const (auto member, _list) {
|
||||
bool isOnline = !member->user->botInfo && App::onlineColorUse(member->onlineTill, _now);
|
||||
if (member->online != isOnline) {
|
||||
member->online = isOnline;
|
||||
member->onlineText = QString();
|
||||
}
|
||||
if (member->online) {
|
||||
++newOnlineCount;
|
||||
if (!member->user->isSelf()) {
|
||||
onlyMe = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newOnlineCount == 1 && onlyMe) {
|
||||
newOnlineCount = 0;
|
||||
}
|
||||
if (_onlineCount != newOnlineCount) {
|
||||
_onlineCount = newOnlineCount;
|
||||
emit onlineCountUpdated(_onlineCount);
|
||||
}
|
||||
}
|
||||
|
||||
MembersWidget::Member *MembersWidget::addUser(ChatData *chat, UserData *user) {
|
||||
auto member = getMember(user);
|
||||
setMemberFlags(member, chat);
|
||||
_list.push_back(member);
|
||||
return member;
|
||||
}
|
||||
|
||||
void MembersWidget::fillChatMembers(ChatData *chat) {
|
||||
if (chat->participants.isEmpty()) return;
|
||||
|
||||
_list.clear();
|
||||
if (!chat->amIn()) return;
|
||||
|
||||
_sortByOnline = true;
|
||||
|
||||
_list.reserve(chat->participants.size());
|
||||
addUser(chat, App::self())->onlineForSort = INT_MAX; // Put me on the first place.
|
||||
for (auto i = chat->participants.cbegin(), e = chat->participants.cend(); i != e; ++i) {
|
||||
auto user = i.key();
|
||||
if (!user->isSelf()) {
|
||||
addUser(chat, user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MembersWidget::setMemberFlags(Member *member, ChatData *chat) {
|
||||
auto isCreator = (chat->creator == peerToUser(member->user->id));
|
||||
auto isAdmin = chat->admins.contains(member->user);
|
||||
member->isAdmin = isCreator || isAdmin;
|
||||
if (member->user->id == peerFromUser(MTP::authedId())) {
|
||||
member->canBeKicked = false;
|
||||
} else if (chat->amCreator() || (chat->amAdmin() && !member->isAdmin)) {
|
||||
member->canBeKicked = true;
|
||||
} else {
|
||||
member->canBeKicked = chat->invitedByMe.contains(member->user);
|
||||
}
|
||||
}
|
||||
|
||||
MembersWidget::Member *MembersWidget::addUser(ChannelData *megagroup, UserData *user) {
|
||||
auto member = getMember(user);
|
||||
setMemberFlags(member, megagroup);
|
||||
_list.push_back(member);
|
||||
return member;
|
||||
}
|
||||
|
||||
void MembersWidget::fillMegagroupMembers(ChannelData *megagroup) {
|
||||
t_assert(megagroup->mgInfo != nullptr);
|
||||
if (megagroup->mgInfo->lastParticipants.isEmpty()) return;
|
||||
|
||||
if (!megagroup->canViewMembers()) {
|
||||
_list.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
_sortByOnline = (megagroup->membersCount() > 0 && megagroup->membersCount() <= Global::ChatSizeMax());
|
||||
|
||||
auto &membersList = megagroup->mgInfo->lastParticipants;
|
||||
if (_sortByOnline) {
|
||||
_list.clear();
|
||||
_list.reserve(membersList.size());
|
||||
if (megagroup->amIn()) {
|
||||
addUser(megagroup, App::self())->onlineForSort = INT_MAX;
|
||||
}
|
||||
} else if (membersList.size() >= _list.size()) {
|
||||
if (addUsersToEnd(megagroup)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!_sortByOnline) {
|
||||
_list.clear();
|
||||
_list.reserve(membersList.size());
|
||||
}
|
||||
for_const (auto user, membersList) {
|
||||
if (!_sortByOnline || !user->isSelf()) {
|
||||
addUser(megagroup, user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MembersWidget::addUsersToEnd(ChannelData *megagroup) {
|
||||
auto &membersList = megagroup->mgInfo->lastParticipants;
|
||||
for (int i = 0, count = _list.size(); i < count; ++i) {
|
||||
if (_list.at(i)->user != membersList.at(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
_list.reserve(membersList.size());
|
||||
for (int i = _list.size(), count = membersList.size(); i < count; ++i) {
|
||||
addUser(megagroup, membersList.at(i));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MembersWidget::setMemberFlags(Member *member, ChannelData *megagroup) {
|
||||
auto amCreatorOrAdmin = (peerToUser(member->user->id) == MTP::authedId()) && (megagroup->amCreator() || megagroup->amEditor());
|
||||
auto isAdmin = megagroup->mgInfo->lastAdmins.contains(member->user);
|
||||
member->isAdmin = amCreatorOrAdmin || isAdmin;
|
||||
if (member->user->isSelf()) {
|
||||
member->canBeKicked = false;
|
||||
} else if (megagroup->amCreator() || (megagroup->amEditor() && !member->isAdmin)) {
|
||||
member->canBeKicked = true;
|
||||
} else {
|
||||
member->canBeKicked = false;
|
||||
}
|
||||
}
|
||||
|
||||
MembersWidget::Member *MembersWidget::getMember(UserData *user) {
|
||||
auto it = _membersByUser.constFind(user);
|
||||
if (it == _membersByUser.cend()) {
|
||||
auto member = new Member(user);
|
||||
it = _membersByUser.insert(user, member);
|
||||
member->online = !user->botInfo && App::onlineColorUse(user->onlineTill, _now);
|
||||
member->onlineTill = user->onlineTill;
|
||||
member->onlineForSort = App::onlineForSort(user, _now);
|
||||
}
|
||||
return it.value();
|
||||
}
|
||||
|
||||
void MembersWidget::paintMember(Painter &p, int x, int y, Member *member, bool selected, bool selectedKick) {
|
||||
int memberRowWidth = width() - x;
|
||||
if (selected) {
|
||||
accumulate_min(memberRowWidth, st::profileBlockWideWidthMax);
|
||||
paintOutlinedRect(p, x, y, memberRowWidth, st::profileMemberHeight);
|
||||
}
|
||||
int skip = st::profileMemberPhotoPosition.x();
|
||||
|
||||
member->user->paintUserpicLeft(p, st::profileMemberPhotoSize, x + st::profileMemberPhotoPosition.x(), y + st::profileMemberPhotoPosition.y(), width());
|
||||
|
||||
if (member->name.isEmpty()) {
|
||||
member->name.setText(st::semiboldFont, App::peerName(member->user), _textNameOptions);
|
||||
}
|
||||
int nameLeft = x + st::profileMemberNamePosition.x();
|
||||
int nameTop = y + st::profileMemberNamePosition.y();
|
||||
int nameWidth = memberRowWidth - st::profileMemberNamePosition.x() - skip;
|
||||
if (member->canBeKicked && selected) {
|
||||
p.setFont(selectedKick ? st::normalFont->underline() : st::normalFont);
|
||||
p.setPen(st::windowActiveTextFg);
|
||||
p.drawTextLeft(nameLeft + nameWidth - _removeWidth, nameTop, width(), lang(lng_profile_kick), _removeWidth);
|
||||
nameWidth -= _removeWidth + skip;
|
||||
}
|
||||
if (member->isAdmin) {
|
||||
nameWidth -= st::profileMemberAdminIcon.width();
|
||||
int iconLeft = nameLeft + qMin(nameWidth, member->name.maxWidth());
|
||||
st::profileMemberAdminIcon.paint(p, QPoint(iconLeft, nameTop), width());
|
||||
}
|
||||
p.setPen(st::profileMemberNameFg);
|
||||
member->name.drawLeftElided(p, nameLeft, nameTop, nameWidth, width());
|
||||
|
||||
if (member->onlineText.isEmpty() || (member->onlineTextTill <= _now)) {
|
||||
if (member->user->botInfo) {
|
||||
bool seesAllMessages = (member->user->botInfo->readsAllHistory || member->isAdmin);
|
||||
member->onlineText = lang(seesAllMessages ? lng_status_bot_reads_all : lng_status_bot_not_reads_all);
|
||||
member->onlineTextTill = _now + 86400;
|
||||
} else {
|
||||
member->online = App::onlineColorUse(member->onlineTill, _now);
|
||||
member->onlineText = App::onlineText(member->onlineTill, _now);
|
||||
member->onlineTextTill = _now + App::onlineWillChangeIn(member->onlineTill, _now);
|
||||
}
|
||||
}
|
||||
if (_updateOnlineAt <= _now || _updateOnlineAt > member->onlineTextTill) {
|
||||
_updateOnlineAt = member->onlineTextTill;
|
||||
_updateOnlineTimer.start((_updateOnlineAt - _now + 1) * 1000);
|
||||
}
|
||||
|
||||
if (member->online) {
|
||||
p.setPen(st::profileMemberStatusFgActive);
|
||||
} else {
|
||||
p.setPen(selected ? st::profileMemberStatusFgOver : st::profileMemberStatusFg);
|
||||
}
|
||||
p.setFont(st::normalFont);
|
||||
p.drawTextLeft(x + st::profileMemberStatusPosition.x(), y + st::profileMemberStatusPosition.y(), width(), member->onlineText);
|
||||
}
|
||||
|
||||
void MembersWidget::onUpdateOnlineDisplay() {
|
||||
if (_sortByOnline) {
|
||||
_now = unixtime();
|
||||
|
||||
bool changed = false;
|
||||
for_const (auto member, _list) {
|
||||
if (!member->online) {
|
||||
if (!member->user->isSelf()) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool isOnline = !member->user->botInfo && App::onlineColorUse(member->onlineTill, _now);
|
||||
if (!isOnline) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
updateOnlineCount();
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
MembersWidget::~MembersWidget() {
|
||||
auto members = base::take(_membersByUser);
|
||||
for_const (auto member, members) {
|
||||
delete member;
|
||||
}
|
||||
}
|
||||
|
||||
ChannelMembersWidget::ChannelMembersWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_participants_section)) {
|
||||
auto observeEvents = UpdateFlag::ChannelCanViewAdmins
|
||||
| UpdateFlag::ChannelCanViewMembers
|
||||
| UpdateFlag::AdminsChanged
|
||||
| UpdateFlag::MembersChanged;
|
||||
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) {
|
||||
notifyPeerUpdated(update);
|
||||
}));
|
||||
|
||||
refreshButtons();
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
||||
if (update.peer != peer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (update.flags & (UpdateFlag::ChannelCanViewAdmins | UpdateFlag::AdminsChanged)) {
|
||||
refreshAdmins();
|
||||
}
|
||||
if (update.flags & (UpdateFlag::ChannelCanViewMembers | UpdateFlag::MembersChanged)) {
|
||||
refreshMembers();
|
||||
}
|
||||
refreshVisibility();
|
||||
|
||||
contentSizeUpdated();
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::addButton(const QString &text, ChildWidget<Ui::LeftOutlineButton> *button, const char *slot) {
|
||||
if (text.isEmpty()) {
|
||||
button->destroy();
|
||||
} else if (*button) {
|
||||
(*button)->setText(text);
|
||||
} else {
|
||||
(*button) = new Ui::LeftOutlineButton(this, text, st::defaultLeftOutlineButton);
|
||||
(*button)->show();
|
||||
connect(*button, SIGNAL(clicked()), this, slot);
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::refreshButtons() {
|
||||
refreshAdmins();
|
||||
refreshMembers();
|
||||
|
||||
refreshVisibility();
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::refreshAdmins() {
|
||||
auto getAdminsText = [this]() -> QString {
|
||||
if (auto channel = peer()->asChannel()) {
|
||||
if (!channel->isMegagroup() && channel->canViewAdmins()) {
|
||||
int adminsCount = qMax(channel->adminsCount(), 1);
|
||||
return lng_channel_admins_link(lt_count, adminsCount);
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
};
|
||||
addButton(getAdminsText(), &_admins, SLOT(onAdmins()));
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::refreshMembers() {
|
||||
auto getMembersText = [this]() -> QString {
|
||||
if (auto channel = peer()->asChannel()) {
|
||||
if (!channel->isMegagroup() && channel->canViewMembers()) {
|
||||
int membersCount = qMax(channel->membersCount(), 1);
|
||||
return lng_channel_members_link(lt_count, membersCount);
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
};
|
||||
addButton(getMembersText(), &_members, SLOT(onMembers()));
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::refreshVisibility() {
|
||||
setVisible(_admins || _members);
|
||||
}
|
||||
|
||||
int ChannelMembersWidget::resizeGetHeight(int newWidth) {
|
||||
int newHeight = contentTop();
|
||||
|
||||
auto resizeButton = [this, &newHeight, newWidth](ChildWidget<Ui::LeftOutlineButton> &button) {
|
||||
if (!button) {
|
||||
return;
|
||||
}
|
||||
|
||||
int left = defaultOutlineButtonLeft();
|
||||
int availableWidth = newWidth - left - st::profileBlockMarginRight;
|
||||
accumulate_min(availableWidth, st::profileBlockOneLineWidthMax);
|
||||
button->resizeToWidth(availableWidth);
|
||||
button->moveToLeft(left, newHeight);
|
||||
newHeight += button->height();
|
||||
};
|
||||
|
||||
resizeButton(_admins);
|
||||
resizeButton(_members);
|
||||
|
||||
return newHeight;
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::onAdmins() {
|
||||
if (auto channel = peer()->asChannel()) {
|
||||
Ui::showLayer(new MembersBox(channel, MembersFilter::Admins));
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelMembersWidget::onMembers() {
|
||||
if (auto channel = peer()->asChannel()) {
|
||||
Ui::showLayer(new MembersBox(channel, MembersFilter::Recent));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Profile
|
|
@ -27,8 +27,7 @@ namespace Profile {
|
|||
|
||||
Window::SectionWidget *SectionMemento::createWidget(QWidget *parent, const QRect &geometry) const {
|
||||
auto result = new Widget(parent, _peer);
|
||||
result->setGeometry(geometry);
|
||||
result->setInternalState(this);
|
||||
result->setInternalState(geometry, this);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,11 +33,26 @@ public:
|
|||
|
||||
Window::SectionWidget *createWidget(QWidget *parent, const QRect &geometry) const override;
|
||||
|
||||
private:
|
||||
friend class Widget;
|
||||
PeerData *getPeer() const {
|
||||
return _peer;
|
||||
}
|
||||
void setScrollTop(int scrollTop) {
|
||||
_scrollTop = scrollTop;
|
||||
}
|
||||
int getScrollTop() const {
|
||||
return _scrollTop;
|
||||
}
|
||||
void setCommonGroups(const QList<PeerData*> &groups) {
|
||||
_commonGroups = groups;
|
||||
}
|
||||
const QList<PeerData*> &getCommonGroups() const {
|
||||
return _commonGroups;
|
||||
}
|
||||
|
||||
private:
|
||||
PeerData *_peer;
|
||||
int _scrollTop = 0;
|
||||
QList<PeerData*> _commonGroups;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -74,28 +74,38 @@ void Widget::setInnerFocus() {
|
|||
|
||||
bool Widget::showInternal(const Window::SectionMemento *memento) {
|
||||
if (auto profileMemento = dynamic_cast<const SectionMemento*>(memento)) {
|
||||
if (profileMemento->_peer == peer()) {
|
||||
// Perhaps no need to do that?..
|
||||
_scroll->scrollToY(profileMemento->_scrollTop);
|
||||
|
||||
if (profileMemento->getPeer() == peer()) {
|
||||
restoreState(profileMemento);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Widget::setInternalState(const SectionMemento *memento) {
|
||||
void Widget::setInternalState(const QRect &geometry, const SectionMemento *memento) {
|
||||
setGeometry(geometry);
|
||||
myEnsureResized(this);
|
||||
_scroll->scrollToY(memento->_scrollTop);
|
||||
_fixedBarShadow->setMode(memento->_scrollTop > 0 ? Ui::ToggleableShadow::Mode::ShownFast : Ui::ToggleableShadow::Mode::HiddenFast);
|
||||
restoreState(memento);
|
||||
}
|
||||
|
||||
std_::unique_ptr<Window::SectionMemento> Widget::createMemento() const {
|
||||
auto result = std_::make_unique<SectionMemento>(peer());
|
||||
result->_scrollTop = _scroll->scrollTop();
|
||||
saveState(result.get());
|
||||
return std_::move(result);
|
||||
}
|
||||
|
||||
void Widget::saveState(SectionMemento *memento) const {
|
||||
memento->setScrollTop(_scroll->scrollTop());
|
||||
_inner->saveState(memento);
|
||||
}
|
||||
|
||||
void Widget::restoreState(const SectionMemento *memento) {
|
||||
_inner->restoreState(memento);
|
||||
auto scrollTop = memento->getScrollTop();
|
||||
_scroll->scrollToY(scrollTop);
|
||||
_fixedBarShadow->setMode((scrollTop > 0) ? Ui::ToggleableShadow::Mode::ShownFast : Ui::ToggleableShadow::Mode::HiddenFast);
|
||||
}
|
||||
|
||||
void Widget::resizeEvent(QResizeEvent *e) {
|
||||
if (!width() || !height()) {
|
||||
return;
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
bool showInternal(const Window::SectionMemento *memento) override;
|
||||
std_::unique_ptr<Window::SectionMemento> createMemento() const override;
|
||||
|
||||
void setInternalState(const SectionMemento *memento);
|
||||
void setInternalState(const QRect &geometry, const SectionMemento *memento);
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
@ -67,8 +67,8 @@ private slots:
|
|||
|
||||
private:
|
||||
void updateAdaptiveLayout();
|
||||
|
||||
friend class SectionMemento;
|
||||
void saveState(SectionMemento *memento) const;
|
||||
void restoreState(const SectionMemento *memento);
|
||||
|
||||
ChildWidget<Ui::ScrollArea> _scroll;
|
||||
ChildWidget<InnerWidget> _inner;
|
||||
|
|
|
@ -282,6 +282,13 @@ bool UserData::setAbout(const QString &newAbout) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void UserData::setCommonChatsCount(int count) {
|
||||
if (_commonChatsCount != count) {
|
||||
_commonChatsCount = count;
|
||||
Notify::peerUpdatedDelayed(this, UpdateFlag::UserCommonChatsChanged);
|
||||
}
|
||||
}
|
||||
|
||||
void UserData::setName(const QString &newFirstName, const QString &newLastName, const QString &newPhoneName, const QString &newUsername) {
|
||||
bool changeName = !newFirstName.isEmpty() || !newLastName.isEmpty();
|
||||
|
||||
|
|
|
@ -468,11 +468,17 @@ public:
|
|||
_restrictionReason = reason;
|
||||
}
|
||||
|
||||
int commonChatsCount() const {
|
||||
return _commonChatsCount;
|
||||
}
|
||||
void setCommonChatsCount(int count);
|
||||
|
||||
private:
|
||||
QString _restrictionReason;
|
||||
QString _about;
|
||||
QString _phone;
|
||||
BlockStatus _blockStatus = BlockStatus::Unknown;
|
||||
int _commonChatsCount = 0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -615,14 +621,6 @@ private:
|
|||
};
|
||||
|
||||
struct MegagroupInfo {
|
||||
MegagroupInfo()
|
||||
: botStatus(0)
|
||||
, pinnedMsgId(0)
|
||||
, joinedMessageFound(false)
|
||||
, lastParticipantsStatus(LastParticipantsUpToDate)
|
||||
, lastParticipantsCount(0)
|
||||
, migrateFromPtr(0) {
|
||||
}
|
||||
typedef QList<UserData*> LastParticipants;
|
||||
LastParticipants lastParticipants;
|
||||
typedef OrderedSet<UserData*> LastAdmins;
|
||||
|
@ -631,20 +629,20 @@ struct MegagroupInfo {
|
|||
MarkupSenders markupSenders;
|
||||
typedef OrderedSet<UserData*> Bots;
|
||||
Bots bots;
|
||||
int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
|
||||
|
||||
MsgId pinnedMsgId;
|
||||
bool joinedMessageFound;
|
||||
int botStatus = 0; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
|
||||
MsgId pinnedMsgId = 0;
|
||||
bool joinedMessageFound = false;
|
||||
|
||||
enum LastParticipantsStatus {
|
||||
LastParticipantsUpToDate = 0x00,
|
||||
LastParticipantsAdminsOutdated = 0x01,
|
||||
LastParticipantsCountOutdated = 0x02,
|
||||
};
|
||||
mutable int32 lastParticipantsStatus;
|
||||
int32 lastParticipantsCount;
|
||||
mutable int lastParticipantsStatus = LastParticipantsUpToDate;
|
||||
int lastParticipantsCount = 0;
|
||||
|
||||
ChatData *migrateFromPtr;
|
||||
ChatData *migrateFromPtr = nullptr;
|
||||
};
|
||||
|
||||
class ChannelData : public PeerData {
|
||||
|
@ -657,6 +655,9 @@ public:
|
|||
|
||||
void updateFull(bool force = false);
|
||||
void fullUpdated();
|
||||
bool wasFullUpdated() const {
|
||||
return (_lastFullUpdate != 0);
|
||||
}
|
||||
|
||||
uint64 access = 0;
|
||||
|
||||
|
@ -798,6 +799,12 @@ public:
|
|||
void ptsWaitingForShortPoll(int32 ms) { // < 0 - not waiting
|
||||
return _ptsWaiter.setWaitingForShortPoll(this, ms);
|
||||
}
|
||||
bool ptsWaitingForSkipped() const {
|
||||
return _ptsWaiter.waitingForSkipped();
|
||||
}
|
||||
bool ptsWaitingForShortPoll() const {
|
||||
return _ptsWaiter.waitingForShortPoll();
|
||||
}
|
||||
|
||||
QString restrictionReason() const override {
|
||||
return _restrictionReason;
|
||||
|
|
|
@ -24,7 +24,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "mainwindow.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "profile/profile_members_widget.h"
|
||||
#include "ui/effects/panel_animation.h"
|
||||
|
||||
namespace {
|
||||
|
|
|
@ -390,8 +390,24 @@
|
|||
'<(src_loc)/platform/platform_main_window.h',
|
||||
'<(src_loc)/platform/platform_notifications_manager.h',
|
||||
'<(src_loc)/platform/platform_window_title.h',
|
||||
'<(src_loc)/profile/profile_actions_widget.cpp',
|
||||
'<(src_loc)/profile/profile_actions_widget.h',
|
||||
'<(src_loc)/profile/profile_block_actions.cpp',
|
||||
'<(src_loc)/profile/profile_block_actions.h',
|
||||
'<(src_loc)/profile/profile_block_channel_members.cpp',
|
||||
'<(src_loc)/profile/profile_block_channel_members.h',
|
||||
'<(src_loc)/profile/profile_block_common_groups.cpp',
|
||||
'<(src_loc)/profile/profile_block_common_groups.h',
|
||||
'<(src_loc)/profile/profile_block_info.cpp',
|
||||
'<(src_loc)/profile/profile_block_info.h',
|
||||
'<(src_loc)/profile/profile_block_invite_link.cpp',
|
||||
'<(src_loc)/profile/profile_block_invite_link.h',
|
||||
'<(src_loc)/profile/profile_block_group_members.cpp',
|
||||
'<(src_loc)/profile/profile_block_group_members.h',
|
||||
'<(src_loc)/profile/profile_block_peer_list.cpp',
|
||||
'<(src_loc)/profile/profile_block_peer_list.h',
|
||||
'<(src_loc)/profile/profile_block_settings.cpp',
|
||||
'<(src_loc)/profile/profile_block_settings.h',
|
||||
'<(src_loc)/profile/profile_block_shared_media.cpp',
|
||||
'<(src_loc)/profile/profile_block_shared_media.h',
|
||||
'<(src_loc)/profile/profile_block_widget.cpp',
|
||||
'<(src_loc)/profile/profile_block_widget.h',
|
||||
'<(src_loc)/profile/profile_cover_drop_area.cpp',
|
||||
|
@ -400,20 +416,10 @@
|
|||
'<(src_loc)/profile/profile_cover.h',
|
||||
'<(src_loc)/profile/profile_fixed_bar.cpp',
|
||||
'<(src_loc)/profile/profile_fixed_bar.h',
|
||||
'<(src_loc)/profile/profile_info_widget.cpp',
|
||||
'<(src_loc)/profile/profile_info_widget.h',
|
||||
'<(src_loc)/profile/profile_inner_widget.cpp',
|
||||
'<(src_loc)/profile/profile_inner_widget.h',
|
||||
'<(src_loc)/profile/profile_invite_link_widget.cpp',
|
||||
'<(src_loc)/profile/profile_invite_link_widget.h',
|
||||
'<(src_loc)/profile/profile_members_widget.cpp',
|
||||
'<(src_loc)/profile/profile_members_widget.h',
|
||||
'<(src_loc)/profile/profile_section_memento.cpp',
|
||||
'<(src_loc)/profile/profile_section_memento.h',
|
||||
'<(src_loc)/profile/profile_settings_widget.cpp',
|
||||
'<(src_loc)/profile/profile_settings_widget.h',
|
||||
'<(src_loc)/profile/profile_shared_media_widget.cpp',
|
||||
'<(src_loc)/profile/profile_shared_media_widget.h',
|
||||
'<(src_loc)/profile/profile_userpic_button.cpp',
|
||||
'<(src_loc)/profile/profile_userpic_button.h',
|
||||
'<(src_loc)/profile/profile_widget.cpp',
|
||||
|
|
Loading…
Add table
Reference in a new issue