diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 776cd91c8..e87f976e3 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -326,6 +326,25 @@ namespace App { return lng_status_lastseen_date(lt_date, dOnline.date().toString(qsl("dd.MM.yy"))); } + namespace { + // we should get a full restriction in "{fulltype}: {reason}" format and we + // need to find a "-all" tag in {fulltype}, otherwise ignore this restriction + QString extractRestrictionReason(const QString &fullRestriction) { + int fullTypeEnd = fullRestriction.indexOf(':'); + if (fullTypeEnd <= 0) { + return QString(); + } + + // {fulltype} is in "{type}-{tag}-{tag}-{tag}" format + // if we find "all" tag we return the restriction string + QStringList typeTags = fullRestriction.mid(0, fullTypeEnd).split('-').mid(1); + if (typeTags.contains(qsl("all"))) { + return fullRestriction.midRef(fullTypeEnd + 1).trimmed().toString(); + } + return QString(); + } + } + bool onlineColorUse(UserData *user, int32 now) { if (isServiceUser(user->id) || user->botInfo) { return false; @@ -388,6 +407,11 @@ namespace App { data->input = MTP_inputPeerUser(d.vid, d.vaccess_hash); data->inputUser = MTP_inputUser(d.vid, d.vaccess_hash); } + if (d.is_restricted()) { + data->setRestrictionReason(extractRestrictionReason(qs(d.vrestriction_reason))); + } else { + data->setRestrictionReason(QString()); + } } if (d.is_deleted()) { data->setPhone(QString()); @@ -593,6 +617,11 @@ namespace App { if (cdata->version < d.vversion.v) { cdata->version = d.vversion.v; } + if (d.is_restricted()) { + cdata->setRestrictionReason(extractRestrictionReason(qs(d.vrestriction_reason))); + } else { + cdata->setRestrictionReason(QString()); + } } QString uname = d.has_username() ? textOneLine(qs(d.vusername)) : QString(); cdata->setName(qs(d.vtitle), uname); diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 09f71b91f..ba77a20a2 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -69,6 +69,9 @@ namespace Ui { inline void showChatsList() { showPeerHistory(PeerId(0), 0); } + inline void showChatsListAsync() { + showPeerHistoryAsync(PeerId(0), 0); + } bool hideWindowNoQuit(); diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index d31bdb383..8476a665c 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -7566,6 +7566,12 @@ void HistoryWidget::peerUpdated(PeerData *data) { QTimer::singleShot(ReloadChannelMembersTimeout, App::api(), SLOT(delayedRequestParticipantsCount())); return; } + QString restriction = _peer->restrictionReason(); + if (!restriction.isEmpty()) { + Ui::showChatsList(); + Ui::showLayer(new InformBox(restriction)); + return; + } bool resize = false; if (pinnedMsgVisibilityUpdated()) { resize = true; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index b1c5fcf60..8bfcb4886 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -2244,9 +2244,16 @@ void MainWidget::ctrlEnterSubmitUpdated() { void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool back) { if (PeerData *peer = App::peerLoaded(peerId)) { if (peer->migrateTo()) { - peerId = peer->migrateTo()->id; + peer = peer->migrateTo(); + peerId = peer->id; if (showAtMsgId > 0) showAtMsgId = -showAtMsgId; } + QString restriction = peer->restrictionReason(); + if (!restriction.isEmpty()) { + Ui::showChatsList(); + Ui::showLayer(new InformBox(restriction)); + return; + } } if (!back && (!peerId || (_stack.size() == 1 && _stack[0]->type() == HistoryStackItem && _stack[0]->peer->id == peerId))) { back = true; diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index d0f9ba705..304fb2974 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -214,6 +214,12 @@ class UserData; class ChatData; class ChannelData; class PeerData { +protected: + + PeerData(const PeerId &id); + PeerData(const PeerData &other) = delete; + PeerData &operator=(const PeerData &other) = delete; + public: virtual ~PeerData() { @@ -295,12 +301,14 @@ public: NotifySettingsPtr notify; - PeerData(const PeerData &other) = delete; - PeerData &operator=(const PeerData &other) = delete; + // if this string is not empty we must not allow to open the + // conversation and we must show this string instead + virtual QString restrictionReason() const { + return QString(); + } protected: - PeerData(const PeerId &id); ImagePtr _userpic; ImagePtr currentUserpic() const; }; @@ -368,14 +376,7 @@ class PhotoData; class UserData : public PeerData { public: - UserData(const PeerId &id) : PeerData(id) - , access(0) - , flags(0) - , onlineTill(0) - , contact(-1) - , blocked(UserBlockUnknown) - , photosCount(-1) - , botInfo(0) { + UserData(const PeerId &id) : PeerData(id) { setName(QString(), QString(), QString(), QString()); } void setPhoto(const MTPUserProfilePhoto &photo); @@ -388,9 +389,9 @@ public: void madeAction(); // pseudo-online - uint64 access; + uint64 access = 0; - MTPDuser::Flags flags; + MTPDuser::Flags flags = { 0 }; bool isVerified() const { return flags & MTPDuser::Flag::f_verified; } @@ -406,17 +407,28 @@ public: QString phone; QString nameOrPhone; Text phoneText; - int32 onlineTill; - int32 contact; // -1 - not contact, cant add (self, empty, deleted, foreign), 0 - not contact, can add (request), 1 - contact - UserBlockedStatus blocked; + int32 onlineTill = 0; + int32 contact = -1; // -1 - not contact, cant add (self, empty, deleted, foreign), 0 - not contact, can add (request), 1 - contact + UserBlockedStatus blocked = UserBlockUnknown; typedef QList Photos; Photos photos; - int32 photosCount; // -1 not loaded, 0 all loaded + int32 photosCount = -1; // -1 not loaded, 0 all loaded QString about; - BotInfo *botInfo; + BotInfo *botInfo = nullptr; + + QString restrictionReason() const override { + return _restrictionReason; + } + void setRestrictionReason(const QString &reason) { + _restrictionReason = reason; + } + +private: + QString _restrictionReason; + }; static UserData * const InlineBotLookingUpData = SharedMemoryLocation(); @@ -600,18 +612,8 @@ class ChannelData : public PeerData { public: ChannelData(const PeerId &id) : PeerData(id) - , access(0) , inputChannel(MTP_inputChannel(MTP_int(bareId()), MTP_long(0))) - , count(1) - , adminsCount(1) - , date(0) - , version(0) - , flags(0) - , flagsFull(0) - , mgInfo(nullptr) - , isForbidden(true) - , inviter(0) - , _lastFullUpdate(0) { + , mgInfo(nullptr) { setName(QString(), QString()); } void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId); @@ -620,18 +622,19 @@ public: void updateFull(bool force = false); void fullUpdated(); - uint64 access; + uint64 access = 0; MTPinputChannel inputChannel; QString username, about; - int32 count, adminsCount; - int32 date; - int32 version; - MTPDchannel::Flags flags; - MTPDchannelFull::Flags flagsFull; - MegagroupInfo *mgInfo; + int count = 1; + int adminsCount = 1; + int32 date = 0; + int version = 0; + MTPDchannel::Flags flags = { 0 }; + MTPDchannelFull::Flags flagsFull = { 0 }; + MegagroupInfo *mgInfo = nullptr; bool lastParticipantsCountOutdated() const { if (!mgInfo || !(mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsCountOutdated)) { return false; @@ -685,7 +688,7 @@ public: bool addsSignature() const { return flags & MTPDchannel::Flag::f_signatures; } - bool isForbidden; + bool isForbidden = true; bool isVerified() const { return flags & MTPDchannel::Flag::f_verified; } @@ -696,7 +699,7 @@ public: // ImagePtr photoFull; QString invitationUrl; - int32 inviter; // > 0 - user who invited me to channel, < 0 - not in channel + int32 inviter = 0; // > 0 - user who invited me to channel, < 0 - not in channel QDateTime inviteDate; void ptsInit(int32 pts) { @@ -732,12 +735,22 @@ public: return _ptsWaiter.setWaitingForShortPoll(this, ms); } + QString restrictionReason() const override { + return _restrictionReason; + } + void setRestrictionReason(const QString &reason) { + _restrictionReason = reason; + } + ~ChannelData(); private: PtsWaiter _ptsWaiter; - uint64 _lastFullUpdate; + uint64 _lastFullUpdate = 0; + + QString _restrictionReason; + }; inline UserData *PeerData::asUser() {