mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-04-01 23:00:58 +00:00
Unify legacy and megagroups information edit.
This commit is contained in:
parent
ff728e2fc1
commit
18c6be0d3b
@ -878,11 +878,13 @@ void ApiWrap::changeDialogUnreadMark(
|
|||||||
)).send();
|
)).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::requestFullPeer(PeerData *peer) {
|
void ApiWrap::requestFullPeer(not_null<PeerData*> peer) {
|
||||||
if (!peer || _fullPeerRequests.contains(peer)) return;
|
if (_fullPeerRequests.contains(peer)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto sendRequest = [this, peer] {
|
const auto requestId = [&] {
|
||||||
auto failHandler = [this, peer](const RPCError &error) {
|
const auto failHandler = [=](const RPCError &error) {
|
||||||
_fullPeerRequests.remove(peer);
|
_fullPeerRequests.remove(peer);
|
||||||
};
|
};
|
||||||
if (const auto user = peer->asUser()) {
|
if (const auto user = peer->asUser()) {
|
||||||
@ -897,32 +899,41 @@ void ApiWrap::requestFullPeer(PeerData *peer) {
|
|||||||
} else if (const auto chat = peer->asChat()) {
|
} else if (const auto chat = peer->asChat()) {
|
||||||
return request(MTPmessages_GetFullChat(
|
return request(MTPmessages_GetFullChat(
|
||||||
chat->inputChat
|
chat->inputChat
|
||||||
)).done([=](const MTPmessages_ChatFull &result, mtpRequestId requestId) {
|
)).done([=](
|
||||||
|
const MTPmessages_ChatFull &result,
|
||||||
|
mtpRequestId requestId) {
|
||||||
gotChatFull(peer, result, requestId);
|
gotChatFull(peer, result, requestId);
|
||||||
}).fail(failHandler).send();
|
}).fail(failHandler).send();
|
||||||
} else if (const auto channel = peer->asChannel()) {
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
return request(MTPchannels_GetFullChannel(
|
return request(MTPchannels_GetFullChannel(
|
||||||
channel->inputChannel
|
channel->inputChannel
|
||||||
)).done([=](const MTPmessages_ChatFull &result, mtpRequestId requestId) {
|
)).done([=](
|
||||||
|
const MTPmessages_ChatFull &result,
|
||||||
|
mtpRequestId requestId) {
|
||||||
gotChatFull(peer, result, requestId);
|
gotChatFull(peer, result, requestId);
|
||||||
}).fail(failHandler).send();
|
}).fail(failHandler).send();
|
||||||
}
|
}
|
||||||
return 0;
|
Unexpected("Peer type in requestFullPeer.");
|
||||||
};
|
}();
|
||||||
if (auto requestId = sendRequest()) {
|
|
||||||
_fullPeerRequests.insert(peer, requestId);
|
_fullPeerRequests.insert(peer, requestId);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result) {
|
void ApiWrap::processFullPeer(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
const MTPmessages_ChatFull &result) {
|
||||||
gotChatFull(peer, result, mtpRequestId(0));
|
gotChatFull(peer, result, mtpRequestId(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::processFullPeer(UserData *user, const MTPUserFull &result) {
|
void ApiWrap::processFullPeer(
|
||||||
|
not_null<UserData*> user,
|
||||||
|
const MTPUserFull &result) {
|
||||||
gotUserFull(user, result, mtpRequestId(0));
|
gotUserFull(user, result, mtpRequestId(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req) {
|
void ApiWrap::gotChatFull(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
const MTPmessages_ChatFull &result,
|
||||||
|
mtpRequestId req) {
|
||||||
auto &d = result.c_messages_chatFull();
|
auto &d = result.c_messages_chatFull();
|
||||||
auto &vc = d.vchats.v;
|
auto &vc = d.vchats.v;
|
||||||
auto badVersion = false;
|
auto badVersion = false;
|
||||||
@ -940,9 +951,10 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
|||||||
App::feedChats(d.vchats);
|
App::feedChats(d.vchats);
|
||||||
|
|
||||||
using UpdateFlag = Notify::PeerUpdate::Flag;
|
using UpdateFlag = Notify::PeerUpdate::Flag;
|
||||||
if (auto chat = peer->asChat()) {
|
if (const auto chat = peer->asChat()) {
|
||||||
if (d.vfull_chat.type() != mtpc_chatFull) {
|
if (d.vfull_chat.type() != mtpc_chatFull) {
|
||||||
LOG(("MTP Error: bad type in gotChatFull for chat: %1").arg(d.vfull_chat.type()));
|
LOG(("MTP Error: bad type in gotChatFull for chat: %1"
|
||||||
|
).arg(d.vfull_chat.type()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto &f = d.vfull_chat.c_chatFull();
|
auto &f = d.vfull_chat.c_chatFull();
|
||||||
@ -957,6 +969,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
chat->setFullFlags(f.vflags.v);
|
||||||
chat->setUserpicPhoto(f.has_chat_photo()
|
chat->setUserpicPhoto(f.has_chat_photo()
|
||||||
? f.vchat_photo
|
? f.vchat_photo
|
||||||
: MTPPhoto(MTP_photoEmpty(MTP_long(0))));
|
: MTPPhoto(MTP_photoEmpty(MTP_long(0))));
|
||||||
@ -971,10 +984,13 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
|||||||
}
|
}
|
||||||
chat->fullUpdated();
|
chat->fullUpdated();
|
||||||
|
|
||||||
notifySettingReceived(MTP_inputNotifyPeer(peer->input), f.vnotify_settings);
|
notifySettingReceived(
|
||||||
} else if (auto channel = peer->asChannel()) {
|
MTP_inputNotifyPeer(peer->input),
|
||||||
|
f.vnotify_settings);
|
||||||
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
if (d.vfull_chat.type() != mtpc_channelFull) {
|
if (d.vfull_chat.type() != mtpc_channelFull) {
|
||||||
LOG(("MTP Error: bad type in gotChatFull for channel: %1").arg(d.vfull_chat.type()));
|
LOG(("MTP Error: bad type in gotChatFull for channel: %1"
|
||||||
|
).arg(d.vfull_chat.type()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto &f = d.vfull_chat.c_channelFull();
|
auto &f = d.vfull_chat.c_channelFull();
|
||||||
@ -1084,8 +1100,11 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
|||||||
fullPeerUpdated().notify(peer);
|
fullPeerUpdated().notify(peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::gotUserFull(UserData *user, const MTPUserFull &result, mtpRequestId req) {
|
void ApiWrap::gotUserFull(
|
||||||
auto &d = result.c_userFull();
|
not_null<UserData*> user,
|
||||||
|
const MTPUserFull &result,
|
||||||
|
mtpRequestId req) {
|
||||||
|
const auto &d = result.c_userFull();
|
||||||
|
|
||||||
if (user == _session->user() && !_session->validateSelf(d.vuser)) {
|
if (user == _session->user() && !_session->validateSelf(d.vuser)) {
|
||||||
constexpr auto kRequestUserAgainTimeout = TimeMs(10000);
|
constexpr auto kRequestUserAgainTimeout = TimeMs(10000);
|
||||||
@ -1129,17 +1148,19 @@ void ApiWrap::gotUserFull(UserData *user, const MTPUserFull &result, mtpRequestI
|
|||||||
fullPeerUpdated().notify(user);
|
fullPeerUpdated().notify(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::requestPeer(PeerData *peer) {
|
void ApiWrap::requestPeer(not_null<PeerData*> peer) {
|
||||||
if (!peer || _fullPeerRequests.contains(peer) || _peerRequests.contains(peer)) return;
|
if (_fullPeerRequests.contains(peer) || _peerRequests.contains(peer)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto sendRequest = [this, peer] {
|
const auto requestId = [&] {
|
||||||
auto failHandler = [this, peer](const RPCError &error) {
|
const auto failHandler = [=](const RPCError &error) {
|
||||||
_peerRequests.remove(peer);
|
_peerRequests.remove(peer);
|
||||||
};
|
};
|
||||||
auto chatHandler = [this, peer](const MTPmessages_Chats &result) {
|
const auto chatHandler = [=](const MTPmessages_Chats &result) {
|
||||||
_peerRequests.remove(peer);
|
_peerRequests.remove(peer);
|
||||||
|
|
||||||
if (auto chats = Api::getChatsFromMessagesChats(result)) {
|
if (const auto chats = Api::getChatsFromMessagesChats(result)) {
|
||||||
auto &v = chats->v;
|
auto &v = chats->v;
|
||||||
bool badVersion = false;
|
bool badVersion = false;
|
||||||
if (const auto chat = peer->asChat()) {
|
if (const auto chat = peer->asChat()) {
|
||||||
@ -1151,12 +1172,12 @@ void ApiWrap::requestPeer(PeerData *peer) {
|
|||||||
&& (v[0].type() == mtpc_channel)
|
&& (v[0].type() == mtpc_channel)
|
||||||
&& (v[0].c_channel().vversion.v < channel->version);
|
&& (v[0].c_channel().vversion.v < channel->version);
|
||||||
}
|
}
|
||||||
auto chat = App::feedChats(*chats);
|
const auto chat = App::feedChats(*chats);
|
||||||
if (chat == peer) {
|
if (chat == peer) {
|
||||||
if (badVersion) {
|
if (badVersion) {
|
||||||
if (auto chat = peer->asChat()) {
|
if (const auto chat = peer->asChat()) {
|
||||||
chat->version = v[0].c_chat().vversion.v;
|
chat->version = v[0].c_chat().vversion.v;
|
||||||
} else if (auto channel = peer->asChannel()) {
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
channel->version = v[0].c_channel().vversion.v;
|
channel->version = v[0].c_channel().vversion.v;
|
||||||
}
|
}
|
||||||
requestPeer(peer);
|
requestPeer(peer);
|
||||||
@ -1164,21 +1185,25 @@ void ApiWrap::requestPeer(PeerData *peer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (auto user = peer->asUser()) {
|
if (const auto user = peer->asUser()) {
|
||||||
return request(MTPusers_GetUsers(MTP_vector<MTPInputUser>(1, user->inputUser))).done([this, user](const MTPVector<MTPUser> &result) {
|
return request(MTPusers_GetUsers(
|
||||||
|
MTP_vector<MTPInputUser>(1, user->inputUser)
|
||||||
|
)).done([=](const MTPVector<MTPUser> &result) {
|
||||||
_peerRequests.remove(user);
|
_peerRequests.remove(user);
|
||||||
App::feedUsers(result);
|
App::feedUsers(result);
|
||||||
}).fail(failHandler).send();
|
}).fail(failHandler).send();
|
||||||
} else if (auto chat = peer->asChat()) {
|
} else if (const auto chat = peer->asChat()) {
|
||||||
return request(MTPmessages_GetChats(MTP_vector<MTPint>(1, chat->inputChat))).done(chatHandler).fail(failHandler).send();
|
return request(MTPmessages_GetChats(
|
||||||
} else if (auto channel = peer->asChannel()) {
|
MTP_vector<MTPint>(1, chat->inputChat)
|
||||||
return request(MTPchannels_GetChannels(MTP_vector<MTPInputChannel>(1, channel->inputChannel))).done(chatHandler).fail(failHandler).send();
|
)).done(chatHandler).fail(failHandler).send();
|
||||||
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
|
return request(MTPchannels_GetChannels(
|
||||||
|
MTP_vector<MTPInputChannel>(1, channel->inputChannel)
|
||||||
|
)).done(chatHandler).fail(failHandler).send();
|
||||||
}
|
}
|
||||||
return 0;
|
Unexpected("Peer type in requestPeer.");
|
||||||
};
|
}();
|
||||||
if (auto requestId = sendRequest()) {
|
|
||||||
_peerRequests.insert(peer, requestId);
|
_peerRequests.insert(peer, requestId);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::markMediaRead(
|
void ApiWrap::markMediaRead(
|
||||||
@ -1629,7 +1654,7 @@ void ApiWrap::unblockParticipant(
|
|||||||
} else {
|
} else {
|
||||||
channel->updateFullForced();
|
channel->updateFullForced();
|
||||||
}
|
}
|
||||||
}).fail([this, kick](const RPCError &error) {
|
}).fail([=](const RPCError &error) {
|
||||||
_kickRequests.remove(kick);
|
_kickRequests.remove(kick);
|
||||||
}).send();
|
}).send();
|
||||||
|
|
||||||
|
@ -99,8 +99,8 @@ public:
|
|||||||
void changeDialogUnreadMark(not_null<History*> history, bool unread);
|
void changeDialogUnreadMark(not_null<History*> history, bool unread);
|
||||||
//void changeDialogUnreadMark(not_null<Data::Feed*> feed, bool unread); // #feed
|
//void changeDialogUnreadMark(not_null<Data::Feed*> feed, bool unread); // #feed
|
||||||
|
|
||||||
void requestFullPeer(PeerData *peer);
|
void requestFullPeer(not_null<PeerData*> peer);
|
||||||
void requestPeer(PeerData *peer);
|
void requestPeer(not_null<PeerData*> peer);
|
||||||
void requestPeers(const QList<PeerData*> &peers);
|
void requestPeers(const QList<PeerData*> &peers);
|
||||||
void requestLastParticipants(not_null<ChannelData*> channel);
|
void requestLastParticipants(not_null<ChannelData*> channel);
|
||||||
void requestBots(not_null<ChannelData*> channel);
|
void requestBots(not_null<ChannelData*> channel);
|
||||||
@ -138,8 +138,12 @@ public:
|
|||||||
void requestChannelMembersForAdd(
|
void requestChannelMembersForAdd(
|
||||||
not_null<ChannelData*> channel,
|
not_null<ChannelData*> channel,
|
||||||
Fn<void(const MTPchannels_ChannelParticipants&)> callback);
|
Fn<void(const MTPchannels_ChannelParticipants&)> callback);
|
||||||
void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result);
|
void processFullPeer(
|
||||||
void processFullPeer(UserData *user, const MTPUserFull &result);
|
not_null<PeerData*> peer,
|
||||||
|
const MTPmessages_ChatFull &result);
|
||||||
|
void processFullPeer(
|
||||||
|
not_null<UserData*> user,
|
||||||
|
const MTPUserFull &result);
|
||||||
|
|
||||||
void markMediaRead(const base::flat_set<not_null<HistoryItem*>> &items);
|
void markMediaRead(const base::flat_set<not_null<HistoryItem*>> &items);
|
||||||
void markMediaRead(not_null<HistoryItem*> item);
|
void markMediaRead(not_null<HistoryItem*> item);
|
||||||
@ -435,8 +439,14 @@ private:
|
|||||||
not_null<Data::Feed*> feed,
|
not_null<Data::Feed*> feed,
|
||||||
const MTPmessages_Dialogs &dialogs);
|
const MTPmessages_Dialogs &dialogs);
|
||||||
|
|
||||||
void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req);
|
void gotChatFull(
|
||||||
void gotUserFull(UserData *user, const MTPUserFull &result, mtpRequestId req);
|
not_null<PeerData*> peer,
|
||||||
|
const MTPmessages_ChatFull &result,
|
||||||
|
mtpRequestId req);
|
||||||
|
void gotUserFull(
|
||||||
|
not_null<UserData*> user,
|
||||||
|
const MTPUserFull &result,
|
||||||
|
mtpRequestId req);
|
||||||
void applyLastParticipantsList(
|
void applyLastParticipantsList(
|
||||||
not_null<ChannelData*> channel,
|
not_null<ChannelData*> channel,
|
||||||
int availableCount,
|
int availableCount,
|
||||||
|
@ -366,65 +366,6 @@ void MaxInviteBox::resizeEvent(QResizeEvent *e) {
|
|||||||
_invitationLink = myrtlrect(st::boxPadding.left(), st::boxPadding.top() + _textHeight + st::boxTextFont->height, width() - st::boxPadding.left() - st::boxPadding.right(), 2 * st::boxTextFont->height);
|
_invitationLink = myrtlrect(st::boxPadding.left(), st::boxPadding.top() + _textHeight + st::boxTextFont->height, width() - st::boxPadding.left() - st::boxPadding.right(), 2 * st::boxTextFont->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConvertToSupergroupBox::ConvertToSupergroupBox(QWidget*, ChatData *chat)
|
|
||||||
: _chat(chat)
|
|
||||||
, _text(100)
|
|
||||||
, _note(100) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConvertToSupergroupBox::prepare() {
|
|
||||||
QStringList text;
|
|
||||||
text.push_back(lang(lng_profile_convert_feature1));
|
|
||||||
text.push_back(lang(lng_profile_convert_feature2));
|
|
||||||
text.push_back(lang(lng_profile_convert_feature3));
|
|
||||||
text.push_back(lang(lng_profile_convert_feature4));
|
|
||||||
|
|
||||||
setTitle(langFactory(lng_profile_convert_title));
|
|
||||||
|
|
||||||
addButton(langFactory(lng_profile_convert_confirm), [this] { convertToSupergroup(); });
|
|
||||||
addButton(langFactory(lng_cancel), [this] { closeBox(); });
|
|
||||||
|
|
||||||
_text.setText(st::boxLabelStyle, text.join('\n'), _confirmBoxTextOptions);
|
|
||||||
_note.setText(st::boxLabelStyle, lng_profile_convert_warning(lt_bold_start, textcmdStartSemibold(), lt_bold_end, textcmdStopSemibold()), _confirmBoxTextOptions);
|
|
||||||
_textWidth = st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right();
|
|
||||||
_textHeight = _text.countHeight(_textWidth);
|
|
||||||
setDimensions(st::boxWideWidth, _textHeight + st::boxPadding.bottom() + _note.countHeight(_textWidth));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConvertToSupergroupBox::convertToSupergroup() {
|
|
||||||
MTP::send(MTPmessages_MigrateChat(_chat->inputChat), rpcDone(&ConvertToSupergroupBox::convertDone), rpcFail(&ConvertToSupergroupBox::convertFail));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConvertToSupergroupBox::convertDone(const MTPUpdates &updates) {
|
|
||||||
Ui::hideLayer();
|
|
||||||
ConvertToSupergroupDone(updates);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConvertToSupergroupBox::convertFail(const RPCError &error) {
|
|
||||||
if (MTP::isDefaultHandledError(error)) return false;
|
|
||||||
Ui::hideLayer();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConvertToSupergroupBox::keyPressEvent(QKeyEvent *e) {
|
|
||||||
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
|
|
||||||
convertToSupergroup();
|
|
||||||
} else {
|
|
||||||
BoxContent::keyPressEvent(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConvertToSupergroupBox::paintEvent(QPaintEvent *e) {
|
|
||||||
BoxContent::paintEvent(e);
|
|
||||||
|
|
||||||
Painter p(this);
|
|
||||||
|
|
||||||
// draw box title / text
|
|
||||||
p.setPen(st::boxTextFg);
|
|
||||||
_text.drawLeft(p, st::boxPadding.left(), 0, _textWidth, width());
|
|
||||||
_note.drawLeft(p, st::boxPadding.left(), _textHeight + st::boxPadding.bottom(), _textWidth, width());
|
|
||||||
}
|
|
||||||
|
|
||||||
PinMessageBox::PinMessageBox(
|
PinMessageBox::PinMessageBox(
|
||||||
QWidget*,
|
QWidget*,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
|
@ -119,27 +119,6 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConvertToSupergroupBox : public BoxContent, public RPCSender {
|
|
||||||
public:
|
|
||||||
ConvertToSupergroupBox(QWidget*, ChatData *chat);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void prepare() override;
|
|
||||||
|
|
||||||
void keyPressEvent(QKeyEvent *e) override;
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void convertToSupergroup();
|
|
||||||
void convertDone(const MTPUpdates &updates);
|
|
||||||
bool convertFail(const RPCError &error);
|
|
||||||
|
|
||||||
ChatData *_chat;
|
|
||||||
Text _text, _note;
|
|
||||||
int32 _textWidth, _textHeight;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class PinMessageBox : public BoxContent, public RPCSender {
|
class PinMessageBox : public BoxContent, public RPCSender {
|
||||||
public:
|
public:
|
||||||
PinMessageBox(QWidget*, not_null<PeerData*> peer, MsgId msgId);
|
PinMessageBox(QWidget*, not_null<PeerData*> peer, MsgId msgId);
|
||||||
|
@ -132,44 +132,6 @@ bool InviteSelectedUsers(
|
|||||||
// return mapFromGlobal(QCursor::pos()) - _st.rippleAreaPosition;
|
// return mapFromGlobal(QCursor::pos()) - _st.rippleAreaPosition;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
class EditChatAdminsBoxController::LabeledCheckbox : public Ui::RpWidget {
|
|
||||||
public:
|
|
||||||
LabeledCheckbox(
|
|
||||||
QWidget *parent,
|
|
||||||
const QString &text,
|
|
||||||
bool checked = false,
|
|
||||||
const style::Checkbox &st = st::defaultCheckbox,
|
|
||||||
const style::Check &checkSt = st::defaultCheck);
|
|
||||||
|
|
||||||
bool checked() const {
|
|
||||||
return _checkbox->checked();
|
|
||||||
}
|
|
||||||
rpl::producer<bool> checkedChanges() const {
|
|
||||||
return _checkbox->checkedChanges();
|
|
||||||
}
|
|
||||||
rpl::producer<bool> checkedValue() const {
|
|
||||||
return _checkbox->checkedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setLabelText(
|
|
||||||
bool checked,
|
|
||||||
const style::TextStyle &st,
|
|
||||||
const QString &text,
|
|
||||||
const TextParseOptions &options = _defaultOptions,
|
|
||||||
int minResizeWidth = QFIXED_MAX);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
object_ptr<Ui::Checkbox> _checkbox;
|
|
||||||
Text _labelUnchecked;
|
|
||||||
Text _labelChecked;
|
|
||||||
int _labelWidth = 0;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
void PeerListRowWithLink::setActionLink(const QString &action) {
|
void PeerListRowWithLink::setActionLink(const QString &action) {
|
||||||
_action = action;
|
_action = action;
|
||||||
refreshActionLink();
|
refreshActionLink();
|
||||||
@ -595,191 +557,6 @@ void AddParticipantsBoxController::Start(not_null<ChannelData*> channel) {
|
|||||||
Start(channel, {}, true);
|
Start(channel, {}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
EditChatAdminsBoxController::LabeledCheckbox::LabeledCheckbox(
|
|
||||||
QWidget *parent,
|
|
||||||
const QString &text,
|
|
||||||
bool checked,
|
|
||||||
const style::Checkbox &st,
|
|
||||||
const style::Check &checkSt)
|
|
||||||
: RpWidget(parent)
|
|
||||||
, _checkbox(this, text, checked, st, checkSt) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditChatAdminsBoxController::LabeledCheckbox::setLabelText(
|
|
||||||
bool checked,
|
|
||||||
const style::TextStyle &st,
|
|
||||||
const QString &text,
|
|
||||||
const TextParseOptions &options,
|
|
||||||
int minResizeWidth) {
|
|
||||||
auto &label = (checked ? _labelChecked : _labelUnchecked);
|
|
||||||
label = Text(st, text, options, minResizeWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
int EditChatAdminsBoxController::LabeledCheckbox::resizeGetHeight(int newWidth) {
|
|
||||||
_labelWidth = newWidth - st::contactsPadding.left() - st::contactsPadding.right();
|
|
||||||
_checkbox->resizeToNaturalWidth(_labelWidth);
|
|
||||||
_checkbox->moveToLeft(st::contactsPadding.left(), st::contactsAllAdminsTop);
|
|
||||||
auto labelHeight = qMax(
|
|
||||||
_labelChecked.countHeight(_labelWidth),
|
|
||||||
_labelUnchecked.countHeight(_labelWidth));
|
|
||||||
return st::contactsAboutTop + labelHeight + st::contactsAboutBottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditChatAdminsBoxController::LabeledCheckbox::paintEvent(QPaintEvent *e) {
|
|
||||||
Painter p(this);
|
|
||||||
auto infoTop = _checkbox->bottomNoMargins() + st::contactsAllAdminsTop - st::lineWidth;
|
|
||||||
|
|
||||||
auto infoRect = rtlrect(0, infoTop, width(), height() - infoTop - st::contactsPadding.bottom(), width());
|
|
||||||
p.fillRect(infoRect, st::contactsAboutBg);
|
|
||||||
auto dividerFillTop = rtlrect(0, infoRect.y(), width(), st::profileDividerTop.height(), width());
|
|
||||||
st::profileDividerTop.fill(p, dividerFillTop);
|
|
||||||
auto dividerFillBottom = rtlrect(0, infoRect.y() + infoRect.height() - st::profileDividerBottom.height(), width(), st::profileDividerBottom.height(), width());
|
|
||||||
st::profileDividerBottom.fill(p, dividerFillBottom);
|
|
||||||
|
|
||||||
p.setPen(st::contactsAboutFg);
|
|
||||||
(checked() ? _labelChecked : _labelUnchecked).draw(p, st::contactsPadding.left(), st::contactsAboutTop, _labelWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
EditChatAdminsBoxController::EditChatAdminsBoxController(not_null<ChatData*> chat)
|
|
||||||
: PeerListController()
|
|
||||||
, _chat(chat) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EditChatAdminsBoxController::allAreAdmins() const {
|
|
||||||
return _allAdmins->checked();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditChatAdminsBoxController::prepare() {
|
|
||||||
createAllAdminsCheckbox();
|
|
||||||
|
|
||||||
setSearchNoResultsText(lang(lng_blocked_list_not_found));
|
|
||||||
delegate()->peerListSetSearchMode(allAreAdmins() ? PeerListSearchMode::Disabled : PeerListSearchMode::Enabled);
|
|
||||||
delegate()->peerListSetTitle(langFactory(lng_channel_admins));
|
|
||||||
|
|
||||||
rebuildRows();
|
|
||||||
if (!delegate()->peerListFullRowsCount()) {
|
|
||||||
Auth().api().requestFullPeer(_chat);
|
|
||||||
_adminsUpdatedSubscription = subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(
|
|
||||||
Notify::PeerUpdate::Flag::AdminsChanged, [this](
|
|
||||||
const Notify::PeerUpdate &update) {
|
|
||||||
if (update.peer == _chat) {
|
|
||||||
rebuildRows();
|
|
||||||
if (delegate()->peerListFullRowsCount()) {
|
|
||||||
unsubscribe(_adminsUpdatedSubscription);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
_allAdmins->checkedChanges(
|
|
||||||
) | rpl::start_with_next([=](bool checked) {
|
|
||||||
delegate()->peerListSetSearchMode(checked ? PeerListSearchMode::Disabled : PeerListSearchMode::Enabled);
|
|
||||||
for (auto i = 0, count = delegate()->peerListFullRowsCount(); i != count; ++i) {
|
|
||||||
auto row = delegate()->peerListRowAt(i);
|
|
||||||
auto user = row->peer()->asUser();
|
|
||||||
if (checked || user->id == peerFromUser(_chat->creator)) {
|
|
||||||
row->setDisabledState(PeerListRow::State::DisabledChecked);
|
|
||||||
} else {
|
|
||||||
row->setDisabledState(PeerListRow::State::Active);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, _allAdmins->lifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditChatAdminsBoxController::createAllAdminsCheckbox() {
|
|
||||||
// #TODO groups
|
|
||||||
auto labelWidth = st::boxWideWidth - st::contactsPadding.left() - st::contactsPadding.right();
|
|
||||||
auto checkbox = object_ptr<LabeledCheckbox>(nullptr, lang(lng_chat_all_members_admins), /*!_chat->adminsEnabled()*/false, st::defaultBoxCheckbox);
|
|
||||||
checkbox->setLabelText(true, st::defaultTextStyle, lang(lng_chat_about_all_admins), _defaultOptions, labelWidth);
|
|
||||||
checkbox->setLabelText(false, st::defaultTextStyle, lang(lng_chat_about_admins), _defaultOptions, labelWidth);
|
|
||||||
_allAdmins = checkbox;
|
|
||||||
delegate()->peerListSetAboveWidget(std::move(checkbox));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditChatAdminsBoxController::rebuildRows() {
|
|
||||||
if (_chat->participants.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto allAdmins = allAreAdmins();
|
|
||||||
|
|
||||||
auto admins = std::vector<not_null<UserData*>>();
|
|
||||||
auto others = admins;
|
|
||||||
admins.reserve(allAdmins ? _chat->participants.size() : _chat->admins.size());
|
|
||||||
others.reserve(_chat->participants.size());
|
|
||||||
|
|
||||||
for (const auto [user, version] : _chat->participants) {
|
|
||||||
if (user->id == peerFromUser(_chat->creator)) continue;
|
|
||||||
if (_chat->admins.contains(user)) {
|
|
||||||
admins.push_back(user);
|
|
||||||
} else {
|
|
||||||
others.push_back(user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!admins.empty()) {
|
|
||||||
delegate()->peerListAddSelectedRows(admins);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allAdmins) {
|
|
||||||
admins.insert(admins.end(), others.begin(), others.end());
|
|
||||||
others.clear();
|
|
||||||
}
|
|
||||||
auto sortByName = [](not_null<UserData*> a, auto b) {
|
|
||||||
return (a->name.compare(b->name, Qt::CaseInsensitive) < 0);
|
|
||||||
};
|
|
||||||
ranges::sort(admins, sortByName);
|
|
||||||
ranges::sort(others, sortByName);
|
|
||||||
|
|
||||||
auto addOne = [this](not_null<UserData*> user) {
|
|
||||||
if (auto row = createRow(user)) {
|
|
||||||
delegate()->peerListAppendRow(std::move(row));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (auto creator = App::userLoaded(_chat->creator)) {
|
|
||||||
if (_chat->participants.contains(creator)) {
|
|
||||||
addOne(creator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ranges::for_each(admins, addOne);
|
|
||||||
ranges::for_each(others, addOne);
|
|
||||||
|
|
||||||
delegate()->peerListRefreshRows();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<PeerListRow> EditChatAdminsBoxController::createRow(not_null<UserData*> user) {
|
|
||||||
auto result = std::make_unique<PeerListRow>(user);
|
|
||||||
if (allAreAdmins() || user->id == peerFromUser(_chat->creator)) {
|
|
||||||
result->setDisabledState(PeerListRow::State::DisabledChecked);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditChatAdminsBoxController::rowClicked(not_null<PeerListRow*> row) {
|
|
||||||
delegate()->peerListSetRowChecked(row, !row->checked());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditChatAdminsBoxController::Start(not_null<ChatData*> chat) {
|
|
||||||
auto controller = std::make_unique<EditChatAdminsBoxController>(chat);
|
|
||||||
auto initBox = [chat, controller = controller.get()](not_null<PeerListBox*> box) {
|
|
||||||
box->addButton(langFactory(lng_settings_save), [box, chat, controller] {
|
|
||||||
auto rows = box->peerListCollectSelectedRows();
|
|
||||||
auto users = std::vector<not_null<UserData*>>();
|
|
||||||
for (auto peer : rows) {
|
|
||||||
auto user = peer->asUser();
|
|
||||||
Assert(user != nullptr);
|
|
||||||
Assert(!user->isSelf());
|
|
||||||
users.push_back(peer->asUser());
|
|
||||||
}
|
|
||||||
Auth().api().editChatAdmins(chat, !controller->allAreAdmins(), { users.cbegin(), users.cend() });
|
|
||||||
box->closeBox();
|
|
||||||
});
|
|
||||||
box->addButton(langFactory(lng_cancel), [box] { box->closeBox(); });
|
|
||||||
};
|
|
||||||
Ui::show(
|
|
||||||
Box<PeerListBox>(std::move(controller), std::move(initBox)),
|
|
||||||
LayerOption::KeepOther);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddBotToGroupBoxController::Start(not_null<UserData*> bot) {
|
void AddBotToGroupBoxController::Start(not_null<UserData*> bot) {
|
||||||
auto initBox = [=](not_null<PeerListBox*> box) {
|
auto initBox = [=](not_null<PeerListBox*> box) {
|
||||||
box->addButton(langFactory(lng_cancel), [box] { box->closeBox(); });
|
box->addButton(langFactory(lng_cancel), [box] { box->closeBox(); });
|
||||||
|
@ -136,30 +136,6 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EditChatAdminsBoxController : public PeerListController, private base::Subscriber {
|
|
||||||
public:
|
|
||||||
static void Start(not_null<ChatData*> chat);
|
|
||||||
|
|
||||||
EditChatAdminsBoxController(not_null<ChatData*> chat);
|
|
||||||
|
|
||||||
bool allAreAdmins() const;
|
|
||||||
|
|
||||||
void prepare() override;
|
|
||||||
void rowClicked(not_null<PeerListRow*> row) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void createAllAdminsCheckbox();
|
|
||||||
void rebuildRows();
|
|
||||||
std::unique_ptr<PeerListRow> createRow(not_null<UserData*> user);
|
|
||||||
|
|
||||||
not_null<ChatData*> _chat;
|
|
||||||
int _adminsUpdatedSubscription = 0;
|
|
||||||
|
|
||||||
class LabeledCheckbox;
|
|
||||||
QPointer<LabeledCheckbox> _allAdmins;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class AddParticipantsBoxController : public ContactsBoxController {
|
class AddParticipantsBoxController : public ContactsBoxController {
|
||||||
public:
|
public:
|
||||||
static void Start(not_null<ChatData*> chat);
|
static void Start(not_null<ChatData*> chat);
|
||||||
|
@ -291,20 +291,25 @@ void EditRestrictedBox::prepare() {
|
|||||||
object_ptr<BoxContentDivider>(this),
|
object_ptr<BoxContentDivider>(this),
|
||||||
st::rightsDividerMargin);
|
st::rightsDividerMargin);
|
||||||
|
|
||||||
const auto prepareRights = _oldRights.c_chatBannedRights().vflags.v
|
const auto prepareRights = (_oldRights.c_chatBannedRights().vflags.v
|
||||||
? _oldRights
|
? _oldRights
|
||||||
: Defaults(channel());
|
: Defaults(channel()));
|
||||||
|
const auto prepareFlags = prepareRights.c_chatBannedRights().vflags.v
|
||||||
|
| (channel()->defaultRestrictions()
|
||||||
|
| (channel()->isPublic()
|
||||||
|
? (Flag::f_change_info | Flag::f_pin_messages)
|
||||||
|
: Flags(0)));
|
||||||
const auto disabledFlags = canSave()
|
const auto disabledFlags = canSave()
|
||||||
? (channel()->defaultRestrictions()
|
? (channel()->defaultRestrictions()
|
||||||
/*| (channel()->isPublic()
|
| (channel()->isPublic()
|
||||||
? (Flag::f_change_info | Flag::f_pin_messages)
|
? (Flag::f_change_info | Flag::f_pin_messages)
|
||||||
: Flags(0))*/) // #TODO groups
|
: Flags(0))) // #TODO groups
|
||||||
: ~Flags(0);
|
: ~Flags(0);
|
||||||
|
|
||||||
auto [checkboxes, getRestrictions, changes] = CreateEditRestrictions(
|
auto [checkboxes, getRestrictions, changes] = CreateEditRestrictions(
|
||||||
this,
|
this,
|
||||||
lng_rights_user_restrictions_header,
|
lng_rights_user_restrictions_header,
|
||||||
prepareRights.c_chatBannedRights().vflags.v,
|
prepareFlags,
|
||||||
disabledFlags);
|
disabledFlags);
|
||||||
addControl(std::move(checkboxes), QMargins());
|
addControl(std::move(checkboxes), QMargins());
|
||||||
|
|
||||||
@ -345,14 +350,7 @@ void EditRestrictedBox::prepare() {
|
|||||||
|
|
||||||
MTPChatBannedRights EditRestrictedBox::Defaults(
|
MTPChatBannedRights EditRestrictedBox::Defaults(
|
||||||
not_null<ChannelData*> channel) {
|
not_null<ChannelData*> channel) {
|
||||||
const auto defaultRights = Flag::f_send_messages
|
return MTP_chatBannedRights(MTP_flags(0), MTP_int(0));
|
||||||
| Flag::f_send_media
|
|
||||||
| Flag::f_embed_links
|
|
||||||
| Flag::f_send_stickers
|
|
||||||
| Flag::f_send_gifs
|
|
||||||
| Flag::f_send_games
|
|
||||||
| Flag::f_send_inline;
|
|
||||||
return MTP_chatBannedRights(MTP_flags(defaultRights), MTP_int(0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditRestrictedBox::showRestrictUntil() {
|
void EditRestrictedBox::showRestrictUntil() {
|
||||||
|
@ -111,8 +111,6 @@ private:
|
|||||||
object_ptr<Ui::RpWidget> createHistoryVisibilityEdit();
|
object_ptr<Ui::RpWidget> createHistoryVisibilityEdit();
|
||||||
object_ptr<Ui::RpWidget> createSignaturesEdit();
|
object_ptr<Ui::RpWidget> createSignaturesEdit();
|
||||||
object_ptr<Ui::RpWidget> createStickersEdit();
|
object_ptr<Ui::RpWidget> createStickersEdit();
|
||||||
object_ptr<Ui::RpWidget> createManageAdminsButton();
|
|
||||||
object_ptr<Ui::RpWidget> createUpgradeButton();
|
|
||||||
object_ptr<Ui::RpWidget> createDeleteButton();
|
object_ptr<Ui::RpWidget> createDeleteButton();
|
||||||
|
|
||||||
QString inviteLinkText() const;
|
QString inviteLinkText() const;
|
||||||
@ -210,8 +208,6 @@ object_ptr<Ui::VerticalLayout> Controller::createContent() {
|
|||||||
_wrap->add(createHistoryVisibilityEdit());
|
_wrap->add(createHistoryVisibilityEdit());
|
||||||
_wrap->add(createSignaturesEdit());
|
_wrap->add(createSignaturesEdit());
|
||||||
_wrap->add(createStickersEdit());
|
_wrap->add(createStickersEdit());
|
||||||
_wrap->add(createManageAdminsButton());
|
|
||||||
_wrap->add(createUpgradeButton());
|
|
||||||
_wrap->add(createDeleteButton());
|
_wrap->add(createDeleteButton());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -312,11 +308,6 @@ object_ptr<Ui::RpWidget> Controller::createTitleEdit() {
|
|||||||
object_ptr<Ui::RpWidget> Controller::createDescriptionEdit() {
|
object_ptr<Ui::RpWidget> Controller::createDescriptionEdit() {
|
||||||
Expects(_wrap != nullptr);
|
Expects(_wrap != nullptr);
|
||||||
|
|
||||||
auto channel = _peer->asChannel();
|
|
||||||
if (!channel || !channel->canEditInformation()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto result = object_ptr<Ui::PaddingWrap<Ui::InputField>>(
|
auto result = object_ptr<Ui::PaddingWrap<Ui::InputField>>(
|
||||||
_wrap,
|
_wrap,
|
||||||
object_ptr<Ui::InputField>(
|
object_ptr<Ui::InputField>(
|
||||||
@ -324,7 +315,7 @@ object_ptr<Ui::RpWidget> Controller::createDescriptionEdit() {
|
|||||||
st::editPeerDescription,
|
st::editPeerDescription,
|
||||||
Ui::InputField::Mode::MultiLine,
|
Ui::InputField::Mode::MultiLine,
|
||||||
langFactory(lng_create_group_description),
|
langFactory(lng_create_group_description),
|
||||||
channel->about()),
|
_peer->about()),
|
||||||
st::editPeerDescriptionMargins);
|
st::editPeerDescriptionMargins);
|
||||||
result->entity()->setMaxLength(kMaxChannelDescription);
|
result->entity()->setMaxLength(kMaxChannelDescription);
|
||||||
result->entity()->setInstantReplaces(Ui::InstantReplaces::Default());
|
result->entity()->setInstantReplaces(Ui::InstantReplaces::Default());
|
||||||
@ -346,8 +337,15 @@ object_ptr<Ui::RpWidget> Controller::createDescriptionEdit() {
|
|||||||
object_ptr<Ui::RpWidget> Controller::createPrivaciesEdit() {
|
object_ptr<Ui::RpWidget> Controller::createPrivaciesEdit() {
|
||||||
Expects(_wrap != nullptr);
|
Expects(_wrap != nullptr);
|
||||||
|
|
||||||
auto channel = _peer->asChannel();
|
const auto canEditUsername = [&] {
|
||||||
if (!channel || !channel->canEditUsername()) {
|
if (const auto chat = _peer->asChat()) {
|
||||||
|
return chat->canEditUsername();
|
||||||
|
} else if (const auto channel = _peer->asChannel()) {
|
||||||
|
return channel->canEditUsername();
|
||||||
|
}
|
||||||
|
Unexpected("Peer type in Controller::createPrivaciesEdit.");
|
||||||
|
}();
|
||||||
|
if (!canEditUsername) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto result = object_ptr<Ui::PaddingWrap<Ui::VerticalLayout>>(
|
auto result = object_ptr<Ui::PaddingWrap<Ui::VerticalLayout>>(
|
||||||
@ -356,8 +354,10 @@ object_ptr<Ui::RpWidget> Controller::createPrivaciesEdit() {
|
|||||||
st::editPeerPrivaciesMargins);
|
st::editPeerPrivaciesMargins);
|
||||||
auto container = result->entity();
|
auto container = result->entity();
|
||||||
|
|
||||||
|
const auto isPublic = _peer->isChannel()
|
||||||
|
&& _peer->asChannel()->isPublic();
|
||||||
_controls.privacy = std::make_shared<Ui::RadioenumGroup<Privacy>>(
|
_controls.privacy = std::make_shared<Ui::RadioenumGroup<Privacy>>(
|
||||||
channel->isPublic() ? Privacy::Public : Privacy::Private);
|
isPublic ? Privacy::Public : Privacy::Private);
|
||||||
auto addButton = [&](
|
auto addButton = [&](
|
||||||
Privacy value,
|
Privacy value,
|
||||||
LangKey groupTextKey,
|
LangKey groupTextKey,
|
||||||
@ -401,7 +401,7 @@ object_ptr<Ui::RpWidget> Controller::createPrivaciesEdit() {
|
|||||||
_controls.privacy->setChangedCallback([this](Privacy value) {
|
_controls.privacy->setChangedCallback([this](Privacy value) {
|
||||||
privacyChanged(value);
|
privacyChanged(value);
|
||||||
});
|
});
|
||||||
if (!channel->isPublic()) {
|
if (!isPublic) {
|
||||||
checkUsernameAvailability();
|
checkUsernameAvailability();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,8 +411,8 @@ object_ptr<Ui::RpWidget> Controller::createPrivaciesEdit() {
|
|||||||
object_ptr<Ui::RpWidget> Controller::createUsernameEdit() {
|
object_ptr<Ui::RpWidget> Controller::createUsernameEdit() {
|
||||||
Expects(_wrap != nullptr);
|
Expects(_wrap != nullptr);
|
||||||
|
|
||||||
auto channel = _peer->asChannel();
|
const auto channel = _peer->asChannel();
|
||||||
Assert(channel != nullptr);
|
const auto username = channel ? channel->username : QString();
|
||||||
|
|
||||||
auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
_wrap,
|
_wrap,
|
||||||
@ -434,7 +434,7 @@ object_ptr<Ui::RpWidget> Controller::createUsernameEdit() {
|
|||||||
container,
|
container,
|
||||||
st::setupChannelLink,
|
st::setupChannelLink,
|
||||||
Fn<QString()>(),
|
Fn<QString()>(),
|
||||||
channel->username,
|
username,
|
||||||
true));
|
true));
|
||||||
_controls.username->heightValue(
|
_controls.username->heightValue(
|
||||||
) | rpl::start_with_next([placeholder](int height) {
|
) | rpl::start_with_next([placeholder](int height) {
|
||||||
@ -506,9 +506,6 @@ void Controller::checkUsernameAvailability() {
|
|||||||
if (!_controls.username) {
|
if (!_controls.username) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto channel = _peer->asChannel();
|
|
||||||
Assert(channel != nullptr);
|
|
||||||
|
|
||||||
auto initial = (_controls.privacy->value() != Privacy::Public);
|
auto initial = (_controls.privacy->value() != Privacy::Public);
|
||||||
auto checking = initial
|
auto checking = initial
|
||||||
? qsl(".bad.")
|
? qsl(".bad.")
|
||||||
@ -519,15 +516,17 @@ void Controller::checkUsernameAvailability() {
|
|||||||
if (_checkUsernameRequestId) {
|
if (_checkUsernameRequestId) {
|
||||||
request(_checkUsernameRequestId).cancel();
|
request(_checkUsernameRequestId).cancel();
|
||||||
}
|
}
|
||||||
|
const auto channel = _peer->asChannel();
|
||||||
|
const auto username = channel ? channel->username : QString();
|
||||||
_checkUsernameRequestId = request(MTPchannels_CheckUsername(
|
_checkUsernameRequestId = request(MTPchannels_CheckUsername(
|
||||||
channel->inputChannel,
|
channel ? channel->inputChannel : MTP_inputChannelEmpty(),
|
||||||
MTP_string(checking)
|
MTP_string(checking)
|
||||||
)).done([=](const MTPBool &result) {
|
)).done([=](const MTPBool &result) {
|
||||||
_checkUsernameRequestId = 0;
|
_checkUsernameRequestId = 0;
|
||||||
if (initial) {
|
if (initial) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!mtpIsTrue(result) && checking != channel->username) {
|
if (!mtpIsTrue(result) && checking != username) {
|
||||||
showUsernameError(
|
showUsernameError(
|
||||||
Lang::Viewer(lng_create_channel_link_occupied));
|
Lang::Viewer(lng_create_channel_link_occupied));
|
||||||
} else {
|
} else {
|
||||||
@ -555,7 +554,7 @@ void Controller::checkUsernameAvailability() {
|
|||||||
showUsernameError(
|
showUsernameError(
|
||||||
Lang::Viewer(lng_create_channel_link_invalid));
|
Lang::Viewer(lng_create_channel_link_invalid));
|
||||||
} else if (type == qstr("USERNAME_OCCUPIED")
|
} else if (type == qstr("USERNAME_OCCUPIED")
|
||||||
&& checking != channel->username) {
|
&& checking != username) {
|
||||||
showUsernameError(
|
showUsernameError(
|
||||||
Lang::Viewer(lng_create_channel_link_occupied));
|
Lang::Viewer(lng_create_channel_link_occupied));
|
||||||
}
|
}
|
||||||
@ -656,13 +655,13 @@ void Controller::exportInviteLink(const QString &confirmation) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Controller::canEditInviteLink() const {
|
bool Controller::canEditInviteLink() const {
|
||||||
if (auto channel = _peer->asChannel()) {
|
if (const auto channel = _peer->asChannel()) {
|
||||||
if (channel->canEditUsername()) {
|
if (channel->canEditUsername()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return (!channel->isPublic() && channel->canAddMembers());
|
return (!channel->isPublic() && channel->canAddMembers());
|
||||||
} else if (auto chat = _peer->asChat()) {
|
} else if (const auto chat = _peer->asChat()) {
|
||||||
return !chat->inviteLink().isEmpty() || chat->amCreator();
|
return chat->amCreator() || !chat->inviteLink().isEmpty();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -673,9 +672,9 @@ bool Controller::inviteLinkShown() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString Controller::inviteLinkText() const {
|
QString Controller::inviteLinkText() const {
|
||||||
if (auto channel = _peer->asChannel()) {
|
if (const auto channel = _peer->asChannel()) {
|
||||||
return channel->inviteLink();
|
return channel->inviteLink();
|
||||||
} else if (auto chat = _peer->asChat()) {
|
} else if (const auto chat = _peer->asChat()) {
|
||||||
return chat->inviteLink();
|
return chat->inviteLink();
|
||||||
}
|
}
|
||||||
return QString();
|
return QString();
|
||||||
@ -808,13 +807,19 @@ void Controller::refreshCreateInviteLink() {
|
|||||||
object_ptr<Ui::RpWidget> Controller::createHistoryVisibilityEdit() {
|
object_ptr<Ui::RpWidget> Controller::createHistoryVisibilityEdit() {
|
||||||
Expects(_wrap != nullptr);
|
Expects(_wrap != nullptr);
|
||||||
|
|
||||||
auto channel = _peer->asChannel();
|
const auto canEdit = [&] {
|
||||||
if (!channel
|
if (const auto chat = _peer->asChat()) {
|
||||||
|| !channel->canEditPreHistoryHidden()
|
return chat->canEditPreHistoryHidden();
|
||||||
|| !channel->isMegagroup()
|
} else if (const auto channel = _peer->asChannel()) {
|
||||||
|| (channel->isPublic() && !channel->canEditUsername())) {
|
return channel->canEditPreHistoryHidden();
|
||||||
|
}
|
||||||
|
Unexpected("User in Controller::createHistoryVisibilityEdit.");
|
||||||
|
}();
|
||||||
|
if (!canEdit) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
const auto channel = _peer->asChannel();
|
||||||
|
|
||||||
auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
_wrap,
|
_wrap,
|
||||||
object_ptr<Ui::VerticalLayout>(_wrap),
|
object_ptr<Ui::VerticalLayout>(_wrap),
|
||||||
@ -824,7 +829,7 @@ object_ptr<Ui::RpWidget> Controller::createHistoryVisibilityEdit() {
|
|||||||
|
|
||||||
_controls.historyVisibility
|
_controls.historyVisibility
|
||||||
= std::make_shared<Ui::RadioenumGroup<HistoryVisibility>>(
|
= std::make_shared<Ui::RadioenumGroup<HistoryVisibility>>(
|
||||||
channel->hiddenPreHistory()
|
(!channel || channel->hiddenPreHistory())
|
||||||
? HistoryVisibility::Hidden
|
? HistoryVisibility::Hidden
|
||||||
: HistoryVisibility::Visible);
|
: HistoryVisibility::Visible);
|
||||||
auto addButton = [&](
|
auto addButton = [&](
|
||||||
@ -941,53 +946,13 @@ object_ptr<Ui::RpWidget> Controller::createStickersEdit() {
|
|||||||
_wrap,
|
_wrap,
|
||||||
lang(lng_group_stickers_add),
|
lang(lng_group_stickers_add),
|
||||||
st::editPeerInviteLinkButton)
|
st::editPeerInviteLinkButton)
|
||||||
)->addClickHandler([channel] {
|
)->addClickHandler([=] {
|
||||||
Ui::show(Box<StickersBox>(channel), LayerOption::KeepOther);
|
Ui::show(Box<StickersBox>(channel), LayerOption::KeepOther);
|
||||||
});
|
});
|
||||||
|
|
||||||
return std::move(result);
|
return std::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
object_ptr<Ui::RpWidget> Controller::createManageAdminsButton() {
|
|
||||||
Expects(_wrap != nullptr);
|
|
||||||
|
|
||||||
auto chat = _peer->asChat();
|
|
||||||
if (!chat || !chat->amCreator() || chat->isDeactivated()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
auto result = object_ptr<Ui::PaddingWrap<Ui::LinkButton>>(
|
|
||||||
_wrap,
|
|
||||||
object_ptr<Ui::LinkButton>(
|
|
||||||
_wrap,
|
|
||||||
lang(lng_profile_manage_admins),
|
|
||||||
st::editPeerInviteLinkButton),
|
|
||||||
st::editPeerDeleteButtonMargins);
|
|
||||||
result->entity()->addClickHandler([=] {
|
|
||||||
EditChatAdminsBoxController::Start(chat);
|
|
||||||
});
|
|
||||||
return std::move(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
object_ptr<Ui::RpWidget> Controller::createUpgradeButton() {
|
|
||||||
Expects(_wrap != nullptr);
|
|
||||||
|
|
||||||
auto chat = _peer->asChat();
|
|
||||||
if (!chat || !chat->amCreator() || chat->isDeactivated()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
auto result = object_ptr<Ui::PaddingWrap<Ui::LinkButton>>(
|
|
||||||
_wrap,
|
|
||||||
object_ptr<Ui::LinkButton>(
|
|
||||||
_wrap,
|
|
||||||
lang(lng_profile_migrate_button),
|
|
||||||
st::editPeerInviteLinkButton),
|
|
||||||
st::editPeerDeleteButtonMargins);
|
|
||||||
result->entity()->addClickHandler([=] {
|
|
||||||
Ui::show(Box<ConvertToSupergroupBox>(chat), LayerOption::KeepOther);
|
|
||||||
});
|
|
||||||
return std::move(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
object_ptr<Ui::RpWidget> Controller::createDeleteButton() {
|
object_ptr<Ui::RpWidget> Controller::createDeleteButton() {
|
||||||
Expects(_wrap != nullptr);
|
Expects(_wrap != nullptr);
|
||||||
|
|
||||||
@ -1139,12 +1104,15 @@ void Controller::cancelSave() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Controller::saveUsername() {
|
void Controller::saveUsername() {
|
||||||
auto channel = _peer->asChannel();
|
const auto channel = _peer->asChannel();
|
||||||
if (!_savingData.username
|
const auto username = (channel ? channel->username : QString());
|
||||||
|| !channel
|
if (!_savingData.username || *_savingData.username == username) {
|
||||||
|| *_savingData.username == channel->username) {
|
return continueSave();
|
||||||
|
} else if (!channel) {
|
||||||
|
// #TODO groups convert and save.
|
||||||
return continueSave();
|
return continueSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
request(MTPchannels_UpdateUsername(
|
request(MTPchannels_UpdateUsername(
|
||||||
channel->inputChannel,
|
channel->inputChannel,
|
||||||
MTP_string(*_savingData.username)
|
MTP_string(*_savingData.username)
|
||||||
@ -1154,7 +1122,7 @@ void Controller::saveUsername() {
|
|||||||
*_savingData.username);
|
*_savingData.username);
|
||||||
continueSave();
|
continueSave();
|
||||||
}).fail([=](const RPCError &error) {
|
}).fail([=](const RPCError &error) {
|
||||||
auto type = error.type();
|
const auto type = error.type();
|
||||||
if (type == qstr("USERNAME_NOT_MODIFIED")) {
|
if (type == qstr("USERNAME_NOT_MODIFIED")) {
|
||||||
channel->setName(
|
channel->setName(
|
||||||
TextUtilities::SingleLine(channel->name),
|
TextUtilities::SingleLine(channel->name),
|
||||||
@ -1162,7 +1130,7 @@ void Controller::saveUsername() {
|
|||||||
continueSave();
|
continueSave();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto errorKey = [&] {
|
const auto errorKey = [&] {
|
||||||
if (type == qstr("USERNAME_INVALID")) {
|
if (type == qstr("USERNAME_INVALID")) {
|
||||||
return lng_create_channel_link_invalid;
|
return lng_create_channel_link_invalid;
|
||||||
} else if (type == qstr("USERNAME_OCCUPIED")
|
} else if (type == qstr("USERNAME_OCCUPIED")
|
||||||
@ -1183,17 +1151,17 @@ void Controller::saveTitle() {
|
|||||||
return continueSave();
|
return continueSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto onDone = [this](const MTPUpdates &result) {
|
const auto onDone = [=](const MTPUpdates &result) {
|
||||||
Auth().api().applyUpdates(result);
|
Auth().api().applyUpdates(result);
|
||||||
continueSave();
|
continueSave();
|
||||||
};
|
};
|
||||||
auto onFail = [this](const RPCError &error) {
|
const auto onFail = [=](const RPCError &error) {
|
||||||
auto type = error.type();
|
const auto type = error.type();
|
||||||
if (type == qstr("CHAT_NOT_MODIFIED")
|
if (type == qstr("CHAT_NOT_MODIFIED")
|
||||||
|| type == qstr("CHAT_TITLE_NOT_MODIFIED")) {
|
|| type == qstr("CHAT_TITLE_NOT_MODIFIED")) {
|
||||||
if (auto channel = _peer->asChannel()) {
|
if (const auto channel = _peer->asChannel()) {
|
||||||
channel->setName(*_savingData.title, channel->username);
|
channel->setName(*_savingData.title, channel->username);
|
||||||
} else if (auto chat = _peer->asChat()) {
|
} else if (const auto chat = _peer->asChat()) {
|
||||||
chat->setName(*_savingData.title);
|
chat->setName(*_savingData.title);
|
||||||
}
|
}
|
||||||
continueSave();
|
continueSave();
|
||||||
@ -1206,14 +1174,14 @@ void Controller::saveTitle() {
|
|||||||
cancelSave();
|
cancelSave();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (auto channel = _peer->asChannel()) {
|
if (const auto channel = _peer->asChannel()) {
|
||||||
request(MTPchannels_EditTitle(
|
request(MTPchannels_EditTitle(
|
||||||
channel->inputChannel,
|
channel->inputChannel,
|
||||||
MTP_string(*_savingData.title)
|
MTP_string(*_savingData.title)
|
||||||
)).done(std::move(onDone)
|
)).done(std::move(onDone)
|
||||||
).fail(std::move(onFail)
|
).fail(std::move(onFail)
|
||||||
).send();
|
).send();
|
||||||
} else if (auto chat = _peer->asChat()) {
|
} else if (const auto chat = _peer->asChat()) {
|
||||||
request(MTPmessages_EditChatTitle(
|
request(MTPmessages_EditChatTitle(
|
||||||
chat->inputChat,
|
chat->inputChat,
|
||||||
MTP_string(*_savingData.title)
|
MTP_string(*_savingData.title)
|
||||||
@ -1226,18 +1194,17 @@ void Controller::saveTitle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Controller::saveDescription() {
|
void Controller::saveDescription() {
|
||||||
auto channel = _peer->asChannel();
|
const auto channel = _peer->asChannel();
|
||||||
if (!_savingData.description
|
if (!_savingData.description
|
||||||
|| !channel
|
|| *_savingData.description == _peer->about()) {
|
||||||
|| *_savingData.description == channel->about()) {
|
|
||||||
return continueSave();
|
return continueSave();
|
||||||
}
|
}
|
||||||
auto successCallback = [=] {
|
const auto successCallback = [=] {
|
||||||
channel->setAbout(*_savingData.description);
|
_peer->setAbout(*_savingData.description);
|
||||||
continueSave();
|
continueSave();
|
||||||
};
|
};
|
||||||
request(MTPmessages_EditChatAbout(
|
request(MTPmessages_EditChatAbout(
|
||||||
channel->input,
|
_peer->input,
|
||||||
MTP_string(*_savingData.description)
|
MTP_string(*_savingData.description)
|
||||||
)).done([=](const MTPBool &result) {
|
)).done([=](const MTPBool &result) {
|
||||||
successCallback();
|
successCallback();
|
||||||
@ -1253,10 +1220,13 @@ void Controller::saveDescription() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Controller::saveHistoryVisibility() {
|
void Controller::saveHistoryVisibility() {
|
||||||
auto channel = _peer->asChannel();
|
const auto channel = _peer->asChannel();
|
||||||
|
const auto hidden = channel ? channel->hiddenPreHistory() : true;
|
||||||
if (!_savingData.hiddenPreHistory
|
if (!_savingData.hiddenPreHistory
|
||||||
|| !channel
|
|| *_savingData.hiddenPreHistory == hidden) {
|
||||||
|| *_savingData.hiddenPreHistory == channel->hiddenPreHistory()) {
|
return continueSave();
|
||||||
|
} else if (!channel) {
|
||||||
|
// #TODO groups convert and save.
|
||||||
return continueSave();
|
return continueSave();
|
||||||
}
|
}
|
||||||
request(MTPchannels_TogglePreHistoryHidden(
|
request(MTPchannels_TogglePreHistoryHidden(
|
||||||
@ -1280,7 +1250,7 @@ void Controller::saveHistoryVisibility() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Controller::saveSignatures() {
|
void Controller::saveSignatures() {
|
||||||
auto channel = _peer->asChannel();
|
const auto channel = _peer->asChannel();
|
||||||
if (!_savingData.signatures
|
if (!_savingData.signatures
|
||||||
|| !channel
|
|| !channel
|
||||||
|| *_savingData.signatures == channel->addsSignature()) {
|
|| *_savingData.signatures == channel->addsSignature()) {
|
||||||
@ -1315,21 +1285,25 @@ void Controller::deleteWithConfirmation() {
|
|||||||
const auto channel = _peer->asChannel();
|
const auto channel = _peer->asChannel();
|
||||||
Assert(channel != nullptr);
|
Assert(channel != nullptr);
|
||||||
|
|
||||||
auto text = lang(_isGroup
|
const auto text = lang(_isGroup
|
||||||
? lng_sure_delete_group
|
? lng_sure_delete_group
|
||||||
: lng_sure_delete_channel);
|
: lng_sure_delete_channel);
|
||||||
auto deleteCallback = crl::guard(this, [=] {
|
const auto deleteCallback = crl::guard(this, [=] {
|
||||||
deleteChannel();
|
deleteChannel();
|
||||||
});
|
});
|
||||||
Ui::show(Box<ConfirmBox>(
|
Ui::show(
|
||||||
|
Box<ConfirmBox>(
|
||||||
text,
|
text,
|
||||||
lang(lng_box_delete),
|
lang(lng_box_delete),
|
||||||
st::attentionBoxButton,
|
st::attentionBoxButton,
|
||||||
std::move(deleteCallback)), LayerOption::KeepOther);
|
deleteCallback),
|
||||||
|
LayerOption::KeepOther);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::deleteChannel() {
|
void Controller::deleteChannel() {
|
||||||
const auto channel = _peer->asChannel();
|
const auto channel = _peer->asChannel();
|
||||||
|
Assert(channel != nullptr);
|
||||||
|
|
||||||
const auto chat = channel->migrateFrom();
|
const auto chat = channel->migrateFrom();
|
||||||
|
|
||||||
Ui::hideLayer();
|
Ui::hideLayer();
|
||||||
|
@ -189,7 +189,6 @@ auto ToPositiveNumberString() {
|
|||||||
|
|
||||||
ChatRestrictions DisabledByAdminRights(not_null<PeerData*> peer) {
|
ChatRestrictions DisabledByAdminRights(not_null<PeerData*> peer) {
|
||||||
using Flag = ChatRestriction;
|
using Flag = ChatRestriction;
|
||||||
using Flags = ChatRestrictions;
|
|
||||||
using Admin = ChatAdminRight;
|
using Admin = ChatAdminRight;
|
||||||
using Admins = ChatAdminRights;
|
using Admins = ChatAdminRights;
|
||||||
|
|
||||||
@ -241,13 +240,13 @@ void EditPeerPermissionsBox::prepare() {
|
|||||||
const auto restrictions = [&] {
|
const auto restrictions = [&] {
|
||||||
if (const auto chat = _peer->asChat()) {
|
if (const auto chat = _peer->asChat()) {
|
||||||
return chat->defaultRestrictions()
|
return chat->defaultRestrictions()
|
||||||
/*| disabledByAdminRights*/; // #TODO groups
|
| disabledByAdminRights; // #TODO groups
|
||||||
} else if (const auto channel = _peer->asChannel()) {
|
} else if (const auto channel = _peer->asChannel()) {
|
||||||
return (channel->defaultRestrictions()
|
return (channel->defaultRestrictions()
|
||||||
/*| (channel->isPublic()
|
| (channel->isPublic()
|
||||||
? (Flag::f_change_info | Flag::f_pin_messages)
|
? (Flag::f_change_info | Flag::f_pin_messages)
|
||||||
: Flags(0))
|
: Flags(0))
|
||||||
| disabledByAdminRights*/); // #TODO groups
|
| disabledByAdminRights); // #TODO groups
|
||||||
}
|
}
|
||||||
Unexpected("User in EditPeerPermissionsBox.");
|
Unexpected("User in EditPeerPermissionsBox.");
|
||||||
}();
|
}();
|
||||||
|
@ -55,15 +55,6 @@ void ChannelData::setName(const QString &newName, const QString &newUsername) {
|
|||||||
updateNameDelayed(newName.isEmpty() ? name : newName, QString(), newUsername);
|
updateNameDelayed(newName.isEmpty() ? name : newName, QString(), newUsername);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChannelData::setAbout(const QString &newAbout) {
|
|
||||||
if (_about == newAbout) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_about = newAbout;
|
|
||||||
Notify::peerUpdatedDelayed(this, UpdateFlag::AboutChanged);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChannelData::setInviteLink(const QString &newInviteLink) {
|
void ChannelData::setInviteLink(const QString &newInviteLink) {
|
||||||
if (newInviteLink != _inviteLink) {
|
if (newInviteLink != _inviteLink) {
|
||||||
_inviteLink = newInviteLink;
|
_inviteLink = newInviteLink;
|
||||||
@ -365,7 +356,9 @@ bool ChannelData::canEditSignatures() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ChannelData::canEditPreHistoryHidden() const {
|
bool ChannelData::canEditPreHistoryHidden() const {
|
||||||
return canEditInformation();
|
return canEditInformation()
|
||||||
|
&& isMegagroup()
|
||||||
|
&& (!isPublic() || canEditUsername());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChannelData::canEditUsername() const {
|
bool ChannelData::canEditUsername() const {
|
||||||
|
@ -124,12 +124,6 @@ public:
|
|||||||
return _fullFlags.value();
|
return _fullFlags.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if about text was changed.
|
|
||||||
bool setAbout(const QString &newAbout);
|
|
||||||
const QString &about() const {
|
|
||||||
return _about;
|
|
||||||
}
|
|
||||||
|
|
||||||
int membersCount() const {
|
int membersCount() const {
|
||||||
return _membersCount;
|
return _membersCount;
|
||||||
}
|
}
|
||||||
@ -249,6 +243,8 @@ public:
|
|||||||
bool canWrite() const;
|
bool canWrite() const;
|
||||||
bool canEditInformation() const;
|
bool canEditInformation() const;
|
||||||
bool canEditPermissions() const;
|
bool canEditPermissions() const;
|
||||||
|
bool canEditUsername() const;
|
||||||
|
bool canEditPreHistoryHidden() const;
|
||||||
bool canAddMembers() const;
|
bool canAddMembers() const;
|
||||||
|
|
||||||
bool canBanMembers() const;
|
bool canBanMembers() const;
|
||||||
@ -262,8 +258,6 @@ public:
|
|||||||
bool canViewAdmins() const;
|
bool canViewAdmins() const;
|
||||||
bool canViewBanned() const;
|
bool canViewBanned() const;
|
||||||
bool canEditSignatures() const;
|
bool canEditSignatures() const;
|
||||||
bool canEditPreHistoryHidden() const;
|
|
||||||
bool canEditUsername() const;
|
|
||||||
bool canEditStickers() const;
|
bool canEditStickers() const;
|
||||||
bool canDelete() const;
|
bool canDelete() const;
|
||||||
bool canEditAdmin(not_null<UserData*> user) const;
|
bool canEditAdmin(not_null<UserData*> user) const;
|
||||||
@ -346,9 +340,6 @@ public:
|
|||||||
TimeId inviteDate = 0;
|
TimeId inviteDate = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void flagsUpdated(MTPDchannel::Flags diff);
|
|
||||||
void fullFlagsUpdated(MTPDchannelFull::Flags diff);
|
|
||||||
|
|
||||||
bool canEditLastAdmin(not_null<UserData*> user) const;
|
bool canEditLastAdmin(not_null<UserData*> user) const;
|
||||||
void setFeedPointer(Data::Feed *feed);
|
void setFeedPointer(Data::Feed *feed);
|
||||||
|
|
||||||
@ -369,7 +360,6 @@ private:
|
|||||||
TimeId _restrictedUntil;
|
TimeId _restrictedUntil;
|
||||||
|
|
||||||
QString _unavailableReason;
|
QString _unavailableReason;
|
||||||
QString _about;
|
|
||||||
|
|
||||||
QString _inviteLink;
|
QString _inviteLink;
|
||||||
Data::Feed *_feed = nullptr;
|
Data::Feed *_feed = nullptr;
|
||||||
|
@ -53,6 +53,15 @@ bool ChatData::canEditPermissions() const {
|
|||||||
&& (amCreator() || hasAdminRights());
|
&& (amCreator() || hasAdminRights());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChatData::canEditUsername() const {
|
||||||
|
return amCreator()
|
||||||
|
&& (fullFlags() & MTPDchatFull::Flag::f_can_set_username);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChatData::canEditPreHistoryHidden() const {
|
||||||
|
return amCreator();
|
||||||
|
}
|
||||||
|
|
||||||
bool ChatData::canAddMembers() const {
|
bool ChatData::canAddMembers() const {
|
||||||
return !actionsUnavailable()
|
return !actionsUnavailable()
|
||||||
&& !amRestricted(ChatRestriction::f_invite_users);
|
&& !amRestricted(ChatRestriction::f_invite_users);
|
||||||
|
@ -23,6 +23,12 @@ public:
|
|||||||
MTPDchat::Flags,
|
MTPDchat::Flags,
|
||||||
kEssentialFlags>;
|
kEssentialFlags>;
|
||||||
|
|
||||||
|
static constexpr auto kEssentialFullFlags = 0
|
||||||
|
| MTPDchatFull::Flag::f_can_set_username;
|
||||||
|
using FullFlags = Data::Flags<
|
||||||
|
MTPDchatFull::Flags,
|
||||||
|
kEssentialFullFlags>;
|
||||||
|
|
||||||
using AdminRight = ChatAdminRight;
|
using AdminRight = ChatAdminRight;
|
||||||
using Restriction = ChatRestriction;
|
using Restriction = ChatRestriction;
|
||||||
using AdminRights = ChatAdminRights;
|
using AdminRights = ChatAdminRights;
|
||||||
@ -58,6 +64,22 @@ public:
|
|||||||
return _flags.value();
|
return _flags.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setFullFlags(MTPDchatFull::Flags which) {
|
||||||
|
_fullFlags.set(which);
|
||||||
|
}
|
||||||
|
void addFullFlags(MTPDchatFull::Flags which) {
|
||||||
|
_fullFlags.add(which);
|
||||||
|
}
|
||||||
|
void removeFullFlags(MTPDchatFull::Flags which) {
|
||||||
|
_fullFlags.remove(which);
|
||||||
|
}
|
||||||
|
auto fullFlags() const {
|
||||||
|
return _fullFlags.current();
|
||||||
|
}
|
||||||
|
auto fullFlagsValue() const {
|
||||||
|
return _fullFlags.value();
|
||||||
|
}
|
||||||
|
|
||||||
auto adminRights() const {
|
auto adminRights() const {
|
||||||
return _adminRights.current();
|
return _adminRights.current();
|
||||||
}
|
}
|
||||||
@ -103,6 +125,8 @@ public:
|
|||||||
bool canWrite() const;
|
bool canWrite() const;
|
||||||
bool canEditInformation() const;
|
bool canEditInformation() const;
|
||||||
bool canEditPermissions() const;
|
bool canEditPermissions() const;
|
||||||
|
bool canEditUsername() const;
|
||||||
|
bool canEditPreHistoryHidden() const;
|
||||||
bool canAddMembers() const;
|
bool canAddMembers() const;
|
||||||
|
|
||||||
void setInviteLink(const QString &newInviteLink);
|
void setInviteLink(const QString &newInviteLink);
|
||||||
@ -130,9 +154,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] bool actionsUnavailable() const;
|
[[nodiscard]] bool actionsUnavailable() const;
|
||||||
void flagsUpdated(MTPDchat::Flags diff);
|
|
||||||
|
|
||||||
Flags _flags;
|
Flags _flags;
|
||||||
|
FullFlags _fullFlags;
|
||||||
QString _inviteLink;
|
QString _inviteLink;
|
||||||
|
|
||||||
RestrictionFlags _defaultRestrictions;
|
RestrictionFlags _defaultRestrictions;
|
||||||
|
@ -381,6 +381,15 @@ void PeerData::setPinnedMessageId(MsgId messageId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PeerData::setAbout(const QString &newAbout) {
|
||||||
|
if (_about == newAbout) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_about = newAbout;
|
||||||
|
Notify::peerUpdatedDelayed(this, UpdateFlag::AboutChanged);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void PeerData::fillNames() {
|
void PeerData::fillNames() {
|
||||||
_nameWords.clear();
|
_nameWords.clear();
|
||||||
_nameFirstLetters.clear();
|
_nameFirstLetters.clear();
|
||||||
|
@ -224,6 +224,12 @@ public:
|
|||||||
setPinnedMessageId(0);
|
setPinnedMessageId(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if about text was changed.
|
||||||
|
bool setAbout(const QString &newAbout);
|
||||||
|
const QString &about() const {
|
||||||
|
return _about;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateNameDelayed(
|
void updateNameDelayed(
|
||||||
const QString &newName,
|
const QString &newName,
|
||||||
@ -260,4 +266,6 @@ private:
|
|||||||
TimeMs _lastFullUpdate = 0;
|
TimeMs _lastFullUpdate = 0;
|
||||||
MsgId _pinnedMessageId = 0;
|
MsgId _pinnedMessageId = 0;
|
||||||
|
|
||||||
|
QString _about;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -82,15 +82,6 @@ void UserData::setPhoto(const MTPUserProfilePhoto &photo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UserData::setAbout(const QString &newAbout) {
|
|
||||||
if (_about == newAbout) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_about = newAbout;
|
|
||||||
Notify::peerUpdatedDelayed(this, UpdateFlag::AboutChanged);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString UserData::unavailableReason() const {
|
QString UserData::unavailableReason() const {
|
||||||
return _unavailableReason;
|
return _unavailableReason;
|
||||||
}
|
}
|
||||||
|
@ -195,11 +195,6 @@ public:
|
|||||||
bool hasCalls() const;
|
bool hasCalls() const;
|
||||||
void setCallsStatus(CallsStatus callsStatus);
|
void setCallsStatus(CallsStatus callsStatus);
|
||||||
|
|
||||||
bool setAbout(const QString &newAbout);
|
|
||||||
const QString &about() const {
|
|
||||||
return _about;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<BotInfo> botInfo;
|
std::unique_ptr<BotInfo> botInfo;
|
||||||
|
|
||||||
QString unavailableReason() const override;
|
QString unavailableReason() const override;
|
||||||
@ -215,7 +210,6 @@ private:
|
|||||||
FullFlags _fullFlags;
|
FullFlags _fullFlags;
|
||||||
|
|
||||||
QString _unavailableReason;
|
QString _unavailableReason;
|
||||||
QString _about;
|
|
||||||
QString _phone;
|
QString _phone;
|
||||||
ContactStatus _contactStatus = ContactStatus::PhoneUnknown;
|
ContactStatus _contactStatus = ContactStatus::PhoneUnknown;
|
||||||
BlockStatus _blockStatus = BlockStatus::Unknown;
|
BlockStatus _blockStatus = BlockStatus::Unknown;
|
||||||
|
@ -2738,8 +2738,8 @@ int HistoryInner::itemTop(const Element *view) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::notifyIsBotChanged() {
|
void HistoryInner::notifyIsBotChanged() {
|
||||||
const auto newinfo = (_history && _history->peer->isUser())
|
const auto newinfo = (_peer && _peer->isUser())
|
||||||
? _history->peer->asUser()->botInfo.get()
|
? _peer->asUser()->botInfo.get()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
if ((!newinfo && !_botAbout)
|
if ((!newinfo && !_botAbout)
|
||||||
|| (newinfo && _botAbout && _botAbout->info == newinfo)) {
|
|| (newinfo && _botAbout && _botAbout->info == newinfo)) {
|
||||||
|
@ -3686,7 +3686,7 @@ void HistoryWidget::setMembersShowAreaActive(bool active) {
|
|||||||
void HistoryWidget::onMembersDropdownShow() {
|
void HistoryWidget::onMembersDropdownShow() {
|
||||||
if (!_membersDropdown) {
|
if (!_membersDropdown) {
|
||||||
_membersDropdown.create(this, st::membersInnerDropdown);
|
_membersDropdown.create(this, st::membersInnerDropdown);
|
||||||
_membersDropdown->setOwnedWidget(object_ptr<Profile::GroupMembersWidget>(this, _peer, Profile::GroupMembersWidget::TitleVisibility::Hidden, st::membersInnerItem));
|
_membersDropdown->setOwnedWidget(object_ptr<Profile::GroupMembersWidget>(this, _peer, st::membersInnerItem));
|
||||||
_membersDropdown->resizeToWidth(st::membersInnerWidth);
|
_membersDropdown->resizeToWidth(st::membersInnerWidth);
|
||||||
|
|
||||||
_membersDropdown->setMaxHeight(countMembersDropdownHeightMax());
|
_membersDropdown->setMaxHeight(countMembersDropdownHeightMax());
|
||||||
|
@ -324,7 +324,7 @@ void Members::updateHeaderControlsGeometry(int newWidth) {
|
|||||||
void Members::addMember() {
|
void Members::addMember() {
|
||||||
if (const auto chat = _peer->asChat()) {
|
if (const auto chat = _peer->asChat()) {
|
||||||
if (chat->count >= Global::ChatSizeMax() && chat->amCreator()) {
|
if (chat->count >= Global::ChatSizeMax() && chat->amCreator()) {
|
||||||
Ui::show(Box<ConvertToSupergroupBox>(chat));
|
// #TODO convert and add inside AddParticipantsBoxController?
|
||||||
} else {
|
} else {
|
||||||
AddParticipantsBoxController::Start(chat);
|
AddParticipantsBoxController::Start(chat);
|
||||||
}
|
}
|
||||||
|
@ -77,20 +77,17 @@ rpl::producer<TextWithEntities> UsernameValue(not_null<UserData*> user) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<QString> PlainAboutValue(not_null<PeerData*> peer) {
|
rpl::producer<QString> PlainAboutValue(not_null<PeerData*> peer) {
|
||||||
if (auto channel = peer->asChannel()) {
|
if (const auto user = peer->asUser()) {
|
||||||
return Notify::PeerUpdateValue(
|
if (!user->botInfo) {
|
||||||
channel,
|
|
||||||
Notify::PeerUpdate::Flag::AboutChanged
|
|
||||||
) | rpl::map([channel] { return channel->about(); });
|
|
||||||
} else if (auto user = peer->asUser()) {
|
|
||||||
if (user->botInfo) {
|
|
||||||
return PlainBioValue(user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rpl::single(QString());
|
return rpl::single(QString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Notify::PeerUpdateValue(
|
||||||
|
peer,
|
||||||
|
Notify::PeerUpdate::Flag::AboutChanged
|
||||||
|
) | rpl::map([=] { return peer->about(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
rpl::producer<TextWithEntities> AboutValue(not_null<PeerData*> peer) {
|
rpl::producer<TextWithEntities> AboutValue(not_null<PeerData*> peer) {
|
||||||
auto flags = TextParseLinks
|
auto flags = TextParseLinks
|
||||||
| TextParseMentions
|
| TextParseMentions
|
||||||
@ -177,7 +174,7 @@ rpl::producer<int> MembersCountValue(not_null<PeerData*> peer) {
|
|||||||
if (const auto chat = peer->asChat()) {
|
if (const auto chat = peer->asChat()) {
|
||||||
return Notify::PeerUpdateValue(
|
return Notify::PeerUpdateValue(
|
||||||
peer,
|
peer,
|
||||||
Notify::PeerUpdate::Flag::MembersChanged
|
Flag::MembersChanged
|
||||||
) | rpl::map([chat] {
|
) | rpl::map([chat] {
|
||||||
return chat->amIn()
|
return chat->amIn()
|
||||||
? std::max(chat->count, int(chat->participants.size()))
|
? std::max(chat->count, int(chat->participants.size()))
|
||||||
@ -186,7 +183,7 @@ rpl::producer<int> MembersCountValue(not_null<PeerData*> peer) {
|
|||||||
} else if (const auto channel = peer->asChannel()) {
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
return Notify::PeerUpdateValue(
|
return Notify::PeerUpdateValue(
|
||||||
channel,
|
channel,
|
||||||
Notify::PeerUpdate::Flag::MembersChanged
|
Flag::MembersChanged
|
||||||
) | rpl::map([channel] {
|
) | rpl::map([channel] {
|
||||||
return channel->membersCount();
|
return channel->membersCount();
|
||||||
});
|
});
|
||||||
|
@ -3875,14 +3875,15 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) {
|
|||||||
case mtpc_updateShortChatMessage: {
|
case mtpc_updateShortChatMessage: {
|
||||||
auto &d = updates.c_updateShortChatMessage();
|
auto &d = updates.c_updateShortChatMessage();
|
||||||
bool noFrom = !App::userLoaded(d.vfrom_id.v);
|
bool noFrom = !App::userLoaded(d.vfrom_id.v);
|
||||||
if (!App::chatLoaded(d.vchat_id.v)
|
const auto chat = App::chatLoaded(d.vchat_id.v);
|
||||||
|
if (!chat
|
||||||
|| noFrom
|
|| noFrom
|
||||||
|| (d.has_via_bot_id() && !App::userLoaded(d.vvia_bot_id.v))
|
|| (d.has_via_bot_id() && !App::userLoaded(d.vvia_bot_id.v))
|
||||||
|| (d.has_entities() && !mentionUsersLoaded(d.ventities))
|
|| (d.has_entities() && !mentionUsersLoaded(d.ventities))
|
||||||
|| (d.has_fwd_from() && !fwdInfoDataLoaded(d.vfwd_from))) {
|
|| (d.has_fwd_from() && !fwdInfoDataLoaded(d.vfwd_from))) {
|
||||||
MTP_LOG(0, ("getDifference { good - getting user for updateShortChatMessage }%1").arg(cTestMode() ? " TESTMODE" : ""));
|
MTP_LOG(0, ("getDifference { good - getting user for updateShortChatMessage }%1").arg(cTestMode() ? " TESTMODE" : ""));
|
||||||
if (noFrom) {
|
if (chat && noFrom) {
|
||||||
Auth().api().requestFullPeer(App::chatLoaded(d.vchat_id.v));
|
Auth().api().requestFullPeer(chat);
|
||||||
}
|
}
|
||||||
return getDifference();
|
return getDifference();
|
||||||
}
|
}
|
||||||
@ -4240,8 +4241,13 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
|||||||
Auth().api().requestPeer(chat);
|
Auth().api().requestPeer(chat);
|
||||||
}
|
}
|
||||||
} else if (const auto channel = peer->asChannel()) {
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
|
if (data.vversion.v == channel->version + 1) {
|
||||||
channel->setDefaultRestrictions(
|
channel->setDefaultRestrictions(
|
||||||
data.vdefault_banned_rights);
|
data.vdefault_banned_rights);
|
||||||
|
} else {
|
||||||
|
channel->version = data.vversion.v;
|
||||||
|
Auth().api().requestPeer(channel);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG(("API Error: "
|
LOG(("API Error: "
|
||||||
"User received in updateChatDefaultBannedRights."));
|
"User received in updateChatDefaultBannedRights."));
|
||||||
|
@ -108,13 +108,6 @@ profileInviteLinkText: FlatLabel(profileBlockTextPart) {
|
|||||||
|
|
||||||
profileLimitReachedSkip: 6px;
|
profileLimitReachedSkip: 6px;
|
||||||
|
|
||||||
profileMemberItem: PeerListItem(defaultPeerListItem) {
|
|
||||||
left: 8px;
|
|
||||||
bottom: profileBlockMarginBottom;
|
|
||||||
button: defaultLeftOutlineButton;
|
|
||||||
maximalWidth: profileBlockWideWidthMax;
|
|
||||||
statusFgOver: profileStatusFgOver;
|
|
||||||
}
|
|
||||||
profileMemberPaddingLeft: 16px;
|
profileMemberPaddingLeft: 16px;
|
||||||
profileMemberNameFg: windowBoldFg;
|
profileMemberNameFg: windowBoldFg;
|
||||||
profileMemberCreatorIcon: icon {{ "profile_admin_star", profileAdminStartFg, point(4px, 3px) }};
|
profileMemberCreatorIcon: icon {{ "profile_admin_star", profileAdminStartFg, point(4px, 3px) }};
|
||||||
|
@ -40,13 +40,8 @@ UserData *GroupMembersWidget::Member::user() const {
|
|||||||
GroupMembersWidget::GroupMembersWidget(
|
GroupMembersWidget::GroupMembersWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
PeerData *peer,
|
PeerData *peer,
|
||||||
TitleVisibility titleVisibility,
|
|
||||||
const style::PeerListItem &st)
|
const style::PeerListItem &st)
|
||||||
: PeerListWidget(parent
|
: PeerListWidget(parent, peer, QString(), st, lang(lng_profile_kick)) {
|
||||||
, peer
|
|
||||||
, (titleVisibility == TitleVisibility::Visible) ? lang(lng_profile_participants_section) : QString()
|
|
||||||
, st
|
|
||||||
, lang(lng_profile_kick)) {
|
|
||||||
_updateOnlineTimer.setSingleShot(true);
|
_updateOnlineTimer.setSingleShot(true);
|
||||||
connect(&_updateOnlineTimer, SIGNAL(timeout()), this, SLOT(onUpdateOnlineDisplay()));
|
connect(&_updateOnlineTimer, SIGNAL(timeout()), this, SLOT(onUpdateOnlineDisplay()));
|
||||||
|
|
||||||
@ -203,83 +198,6 @@ void GroupMembersWidget::preloadMore() {
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ui::PopupMenu *GroupMembersWidget::fillPeerMenu(PeerData *selectedPeer) {
|
|
||||||
Expects(selectedPeer->isUser());
|
|
||||||
if (emptyTitle()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
auto user = selectedPeer->asUser();
|
|
||||||
auto result = new Ui::PopupMenu(this);
|
|
||||||
result->addAction(lang(lng_context_view_profile), [selectedPeer] {
|
|
||||||
Ui::showPeerProfile(selectedPeer);
|
|
||||||
});
|
|
||||||
auto chat = peer()->asChat();
|
|
||||||
auto channel = peer()->asMegagroup();
|
|
||||||
for_const (auto item, items()) {
|
|
||||||
if (item->peer == selectedPeer) {
|
|
||||||
auto canRemoveAdmin = [item, chat, channel] {
|
|
||||||
if ((item->adminState == Item::AdminState::Admin) && !item->peer->isSelf()) {
|
|
||||||
if (chat) {
|
|
||||||
// Adding of admins from context menu of chat participants
|
|
||||||
// is not supported, so the removing is also disabled.
|
|
||||||
return false;//chat->amCreator();
|
|
||||||
} else if (channel) {
|
|
||||||
return channel->amCreator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
if (channel) {
|
|
||||||
if (channel->canEditAdmin(user)) {
|
|
||||||
auto label = lang((item->adminState != Item::AdminState::None) ? lng_context_edit_permissions : lng_context_promote_admin);
|
|
||||||
result->addAction(label, crl::guard(this, [this, user] {
|
|
||||||
editAdmin(user);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
if (channel->canRestrictUser(user)) {
|
|
||||||
result->addAction(lang(lng_context_restrict_user), crl::guard(this, [this, user] {
|
|
||||||
restrictUser(user);
|
|
||||||
}));
|
|
||||||
result->addAction(lang(lng_context_remove_from_group), crl::guard(this, [this, selectedPeer] {
|
|
||||||
removePeer(selectedPeer);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
} else if (item->hasRemoveLink) {
|
|
||||||
result->addAction(lang(lng_context_remove_from_group), crl::guard(this, [this, selectedPeer] {
|
|
||||||
removePeer(selectedPeer);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GroupMembersWidget::updateItemStatusText(Item *item) {
|
void GroupMembersWidget::updateItemStatusText(Item *item) {
|
||||||
auto member = getMember(item);
|
auto member = getMember(item);
|
||||||
auto user = member->user();
|
auto user = member->user();
|
||||||
@ -303,15 +221,6 @@ void GroupMembersWidget::updateItemStatusText(Item *item) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int GroupMembersWidget::getListTop() const {
|
|
||||||
int result = contentTop();
|
|
||||||
if (_limitReachedInfo) {
|
|
||||||
result += _limitReachedInfo->height();
|
|
||||||
result += st::profileLimitReachedSkip;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GroupMembersWidget::refreshMembers() {
|
void GroupMembersWidget::refreshMembers() {
|
||||||
_now = unixtime();
|
_now = unixtime();
|
||||||
if (auto chat = peer()->asChat()) {
|
if (auto chat = peer()->asChat()) {
|
||||||
@ -320,7 +229,6 @@ void GroupMembersWidget::refreshMembers() {
|
|||||||
Auth().api().requestFullPeer(chat);
|
Auth().api().requestFullPeer(chat);
|
||||||
}
|
}
|
||||||
fillChatMembers(chat);
|
fillChatMembers(chat);
|
||||||
refreshLimitReached();
|
|
||||||
} else if (auto megagroup = peer()->asMegagroup()) {
|
} else if (auto megagroup = peer()->asMegagroup()) {
|
||||||
auto &megagroupInfo = megagroup->mgInfo;
|
auto &megagroupInfo = megagroup->mgInfo;
|
||||||
if (megagroupInfo->lastParticipants.empty() || megagroup->lastParticipantsCountOutdated()) {
|
if (megagroupInfo->lastParticipants.empty() || megagroup->lastParticipantsCountOutdated()) {
|
||||||
@ -333,27 +241,6 @@ void GroupMembersWidget::refreshMembers() {
|
|||||||
refreshVisibility();
|
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);
|
|
||||||
QString title = TextUtilities::EscapeForRichParsing(lng_profile_migrate_reached(lt_count, Global::ChatSizeMax()));
|
|
||||||
QString body = TextUtilities::EscapeForRichParsing(lang(lng_profile_migrate_body));
|
|
||||||
QString link = TextUtilities::EscapeForRichParsing(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->setClickHandlerFilter([=](auto&&...) {
|
|
||||||
Ui::show(Box<ConvertToSupergroupBox>(peer()->asChat()));
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
} else if (!limitReachedShown && _limitReachedInfo) {
|
|
||||||
_limitReachedInfo.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GroupMembersWidget::checkSelfAdmin(ChatData *chat) {
|
void GroupMembersWidget::checkSelfAdmin(ChatData *chat) {
|
||||||
if (chat->participants.empty()) return;
|
if (chat->participants.empty()) return;
|
||||||
|
|
||||||
|
@ -24,11 +24,7 @@ class GroupMembersWidget : public PeerListWidget {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class TitleVisibility {
|
GroupMembersWidget(QWidget *parent, PeerData *peer, const style::PeerListItem &st);
|
||||||
Visible,
|
|
||||||
Hidden,
|
|
||||||
};
|
|
||||||
GroupMembersWidget(QWidget *parent, PeerData *peer, TitleVisibility titleVisibility = TitleVisibility::Visible, const style::PeerListItem &st = st::profileMemberItem);
|
|
||||||
|
|
||||||
int onlineCount() const {
|
int onlineCount() const {
|
||||||
return _onlineCount;
|
return _onlineCount;
|
||||||
@ -36,14 +32,6 @@ public:
|
|||||||
|
|
||||||
~GroupMembersWidget();
|
~GroupMembersWidget();
|
||||||
|
|
||||||
protected:
|
|
||||||
// Resizes content and counts natural widget height for the desired width.
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
|
||||||
|
|
||||||
void paintContents(Painter &p) override;
|
|
||||||
|
|
||||||
Ui::PopupMenu *fillPeerMenu(PeerData *peer) override;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void onlineCountUpdated(int onlineCount);
|
void onlineCountUpdated(int onlineCount);
|
||||||
|
|
||||||
@ -63,16 +51,10 @@ private:
|
|||||||
void sortMembers();
|
void sortMembers();
|
||||||
void updateOnlineCount();
|
void updateOnlineCount();
|
||||||
void checkSelfAdmin(ChatData *chat);
|
void checkSelfAdmin(ChatData *chat);
|
||||||
void refreshLimitReached();
|
|
||||||
|
|
||||||
void preloadMore();
|
void preloadMore();
|
||||||
|
|
||||||
bool limitReachedHook(const ClickHandlerPtr &handler, Qt::MouseButton button);
|
|
||||||
|
|
||||||
void refreshUserOnline(UserData *user);
|
void refreshUserOnline(UserData *user);
|
||||||
|
|
||||||
int getListTop() const override;
|
|
||||||
|
|
||||||
struct Member : public Item {
|
struct Member : public Item {
|
||||||
explicit Member(UserData *user);
|
explicit Member(UserData *user);
|
||||||
UserData *user() const;
|
UserData *user() const;
|
||||||
@ -93,8 +75,6 @@ private:
|
|||||||
void setItemFlags(Item *item, ChannelData *megagroup);
|
void setItemFlags(Item *item, ChannelData *megagroup);
|
||||||
bool addUsersToEnd(ChannelData *megagroup);
|
bool addUsersToEnd(ChannelData *megagroup);
|
||||||
|
|
||||||
object_ptr<Ui::FlatLabel> _limitReachedInfo = { nullptr };
|
|
||||||
|
|
||||||
QMap<UserData*, Member*> _membersByUser;
|
QMap<UserData*, Member*> _membersByUser;
|
||||||
bool _sortByOnline = false;
|
bool _sortByOnline = false;
|
||||||
TimeId _now = 0;
|
TimeId _now = 0;
|
||||||
|
@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "profile/profile_block_peer_list.h"
|
#include "profile/profile_block_peer_list.h"
|
||||||
|
|
||||||
#include "ui/effects/ripple_animation.h"
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
|
||||||
#include "ui/text_options.h"
|
#include "ui/text_options.h"
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
@ -60,7 +59,7 @@ void PeerListWidget::paintContents(Painter &p) {
|
|||||||
auto to = ceilclamp(_visibleBottom - top, _st.height, 0, _items.size());
|
auto to = ceilclamp(_visibleBottom - top, _st.height, 0, _items.size());
|
||||||
for (auto i = from; i < to; ++i) {
|
for (auto i = from; i < to; ++i) {
|
||||||
auto y = top + i * _st.height;
|
auto y = top + i * _st.height;
|
||||||
auto selected = (_menuRowIndex >= 0) ? (i == _menuRowIndex) : (_pressed >= 0) ? (i == _pressed) : (i == _selected);
|
auto selected = (_pressed >= 0) ? (i == _pressed) : (i == _selected);
|
||||||
auto selectedRemove = selected && _selectedRemove;
|
auto selectedRemove = selected && _selectedRemove;
|
||||||
if (_pressed >= 0 && !_pressedRemove) {
|
if (_pressed >= 0 && !_pressedRemove) {
|
||||||
selectedRemove = false;
|
selectedRemove = false;
|
||||||
@ -182,46 +181,6 @@ void PeerListWidget::mousePressReleased(Qt::MouseButton button) {
|
|||||||
repaintSelectedRow();
|
repaintSelectedRow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerListWidget::contextMenuEvent(QContextMenuEvent *e) {
|
|
||||||
if (_menu) {
|
|
||||||
_menu->deleteLater();
|
|
||||||
_menu = nullptr;
|
|
||||||
}
|
|
||||||
if (_menuRowIndex >= 0) {
|
|
||||||
repaintRow(_menuRowIndex);
|
|
||||||
_menuRowIndex = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e->reason() == QContextMenuEvent::Mouse) {
|
|
||||||
_mousePosition = e->globalPos();
|
|
||||||
updateSelection();
|
|
||||||
}
|
|
||||||
|
|
||||||
_menuRowIndex = _selected;
|
|
||||||
if (_pressButton != Qt::LeftButton) {
|
|
||||||
mousePressReleased(_pressButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_selected < 0 || _selected >= _items.size()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_menu = fillPeerMenu(_items[_selected]->peer);
|
|
||||||
if (_menu) {
|
|
||||||
_menu->setDestroyedCallback(crl::guard(this, [this, menu = _menu] {
|
|
||||||
if (_menu == menu) {
|
|
||||||
_menu = nullptr;
|
|
||||||
}
|
|
||||||
repaintRow(_menuRowIndex);
|
|
||||||
_menuRowIndex = -1;
|
|
||||||
_mousePosition = QCursor::pos();
|
|
||||||
updateSelection();
|
|
||||||
}));
|
|
||||||
_menu->popup(e->globalPos());
|
|
||||||
e->accept();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PeerListWidget::enterEventHook(QEvent *e) {
|
void PeerListWidget::enterEventHook(QEvent *e) {
|
||||||
_mousePosition = QCursor::pos();
|
_mousePosition = QCursor::pos();
|
||||||
updateSelection();
|
updateSelection();
|
||||||
|
@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "profile/profile_block_widget.h"
|
#include "profile/profile_block_widget.h"
|
||||||
#include "styles/style_profile.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class RippleAnimation;
|
class RippleAnimation;
|
||||||
@ -19,11 +18,15 @@ namespace Notify {
|
|||||||
struct PeerUpdate;
|
struct PeerUpdate;
|
||||||
} // namespace Notify
|
} // namespace Notify
|
||||||
|
|
||||||
|
namespace style {
|
||||||
|
struct PeerListItem;
|
||||||
|
} // namespace style
|
||||||
|
|
||||||
namespace Profile {
|
namespace Profile {
|
||||||
|
|
||||||
class PeerListWidget : public BlockWidget {
|
class PeerListWidget : public BlockWidget {
|
||||||
public:
|
public:
|
||||||
PeerListWidget(QWidget *parent, PeerData *peer, const QString &title, const style::PeerListItem &st = st::profileMemberItem, const QString &removeText = QString());
|
PeerListWidget(QWidget *parent, PeerData *peer, const QString &title, const style::PeerListItem &st, const QString &removeText);
|
||||||
|
|
||||||
struct Item {
|
struct Item {
|
||||||
explicit Item(PeerData *peer);
|
explicit Item(PeerData *peer);
|
||||||
@ -42,7 +45,7 @@ public:
|
|||||||
bool hasRemoveLink = false;
|
bool hasRemoveLink = false;
|
||||||
std::unique_ptr<Ui::RippleAnimation> ripple;
|
std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||||
};
|
};
|
||||||
virtual int getListTop() const {
|
int getListTop() const {
|
||||||
return contentTop();
|
return contentTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +101,6 @@ protected:
|
|||||||
void mouseMoveEvent(QMouseEvent *e) override;
|
void mouseMoveEvent(QMouseEvent *e) override;
|
||||||
void mousePressEvent(QMouseEvent *e) override;
|
void mousePressEvent(QMouseEvent *e) override;
|
||||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||||
void contextMenuEvent(QContextMenuEvent *e) override;
|
|
||||||
void enterEventHook(QEvent *e) override;
|
void enterEventHook(QEvent *e) override;
|
||||||
void enterFromChildEvent(QEvent *e, QWidget *child) override {
|
void enterFromChildEvent(QEvent *e, QWidget *child) override {
|
||||||
enterEventHook(e);
|
enterEventHook(e);
|
||||||
@ -108,10 +110,6 @@ protected:
|
|||||||
leaveEventHook(e);
|
leaveEventHook(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Ui::PopupMenu *fillPeerMenu(PeerData *peer) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void mousePressReleased(Qt::MouseButton button);
|
void mousePressReleased(Qt::MouseButton button);
|
||||||
void updateSelection();
|
void updateSelection();
|
||||||
@ -145,9 +143,6 @@ private:
|
|||||||
QString _removeText;
|
QString _removeText;
|
||||||
int _removeWidth = 0;
|
int _removeWidth = 0;
|
||||||
|
|
||||||
Ui::PopupMenu *_menu = nullptr;
|
|
||||||
int _menuRowIndex = -1;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Profile
|
} // namespace Profile
|
||||||
|
@ -109,7 +109,7 @@ History *FindWastedPin() {
|
|||||||
|
|
||||||
void AddChatMembers(not_null<ChatData*> chat) {
|
void AddChatMembers(not_null<ChatData*> chat) {
|
||||||
if (chat->count >= Global::ChatSizeMax() && chat->amCreator()) {
|
if (chat->count >= Global::ChatSizeMax() && chat->amCreator()) {
|
||||||
Ui::show(Box<ConvertToSupergroupBox>(chat));
|
// #TODO convert and add inside AddParticipantsBoxController?
|
||||||
} else {
|
} else {
|
||||||
AddParticipantsBoxController::Start(chat);
|
AddParticipantsBoxController::Start(chat);
|
||||||
}
|
}
|
||||||
@ -122,7 +122,7 @@ bool PinnedLimitReached(Dialogs::Key key) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Some old chat, that was converted, maybe is still pinned.
|
// Some old chat, that was converted, maybe is still pinned.
|
||||||
if (auto wasted = FindWastedPin()) {
|
if (const auto wasted = FindWastedPin()) {
|
||||||
Auth().data().setPinnedDialog(wasted, false);
|
Auth().data().setPinnedDialog(wasted, false);
|
||||||
Auth().data().setPinnedDialog(key, true);
|
Auth().data().setPinnedDialog(key, true);
|
||||||
Auth().api().savePinnedOrder();
|
Auth().api().savePinnedOrder();
|
||||||
|
Loading…
Reference in New Issue
Block a user