mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Unify legacy and megagroups information edit.
This commit is contained in:
parent
ff728e2fc1
commit
18c6be0d3b
28 changed files with 273 additions and 759 deletions
|
@ -878,11 +878,13 @@ void ApiWrap::changeDialogUnreadMark(
|
|||
)).send();
|
||||
}
|
||||
|
||||
void ApiWrap::requestFullPeer(PeerData *peer) {
|
||||
if (!peer || _fullPeerRequests.contains(peer)) return;
|
||||
void ApiWrap::requestFullPeer(not_null<PeerData*> peer) {
|
||||
if (_fullPeerRequests.contains(peer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto sendRequest = [this, peer] {
|
||||
auto failHandler = [this, peer](const RPCError &error) {
|
||||
const auto requestId = [&] {
|
||||
const auto failHandler = [=](const RPCError &error) {
|
||||
_fullPeerRequests.remove(peer);
|
||||
};
|
||||
if (const auto user = peer->asUser()) {
|
||||
|
@ -897,32 +899,41 @@ void ApiWrap::requestFullPeer(PeerData *peer) {
|
|||
} else if (const auto chat = peer->asChat()) {
|
||||
return request(MTPmessages_GetFullChat(
|
||||
chat->inputChat
|
||||
)).done([=](const MTPmessages_ChatFull &result, mtpRequestId requestId) {
|
||||
)).done([=](
|
||||
const MTPmessages_ChatFull &result,
|
||||
mtpRequestId requestId) {
|
||||
gotChatFull(peer, result, requestId);
|
||||
}).fail(failHandler).send();
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
return request(MTPchannels_GetFullChannel(
|
||||
channel->inputChannel
|
||||
)).done([=](const MTPmessages_ChatFull &result, mtpRequestId requestId) {
|
||||
)).done([=](
|
||||
const MTPmessages_ChatFull &result,
|
||||
mtpRequestId requestId) {
|
||||
gotChatFull(peer, result, requestId);
|
||||
}).fail(failHandler).send();
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
if (auto requestId = sendRequest()) {
|
||||
_fullPeerRequests.insert(peer, requestId);
|
||||
}
|
||||
Unexpected("Peer type in requestFullPeer.");
|
||||
}();
|
||||
_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));
|
||||
}
|
||||
|
||||
void ApiWrap::processFullPeer(UserData *user, const MTPUserFull &result) {
|
||||
void ApiWrap::processFullPeer(
|
||||
not_null<UserData*> user,
|
||||
const MTPUserFull &result) {
|
||||
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 &vc = d.vchats.v;
|
||||
auto badVersion = false;
|
||||
|
@ -940,9 +951,10 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
|||
App::feedChats(d.vchats);
|
||||
|
||||
using UpdateFlag = Notify::PeerUpdate::Flag;
|
||||
if (auto chat = peer->asChat()) {
|
||||
if (const auto chat = peer->asChat()) {
|
||||
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;
|
||||
}
|
||||
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()
|
||||
? f.vchat_photo
|
||||
: MTPPhoto(MTP_photoEmpty(MTP_long(0))));
|
||||
|
@ -971,10 +984,13 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
|||
}
|
||||
chat->fullUpdated();
|
||||
|
||||
notifySettingReceived(MTP_inputNotifyPeer(peer->input), f.vnotify_settings);
|
||||
} else if (auto channel = peer->asChannel()) {
|
||||
notifySettingReceived(
|
||||
MTP_inputNotifyPeer(peer->input),
|
||||
f.vnotify_settings);
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
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;
|
||||
}
|
||||
auto &f = d.vfull_chat.c_channelFull();
|
||||
|
@ -1084,8 +1100,11 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
|||
fullPeerUpdated().notify(peer);
|
||||
}
|
||||
|
||||
void ApiWrap::gotUserFull(UserData *user, const MTPUserFull &result, mtpRequestId req) {
|
||||
auto &d = result.c_userFull();
|
||||
void ApiWrap::gotUserFull(
|
||||
not_null<UserData*> user,
|
||||
const MTPUserFull &result,
|
||||
mtpRequestId req) {
|
||||
const auto &d = result.c_userFull();
|
||||
|
||||
if (user == _session->user() && !_session->validateSelf(d.vuser)) {
|
||||
constexpr auto kRequestUserAgainTimeout = TimeMs(10000);
|
||||
|
@ -1129,17 +1148,19 @@ void ApiWrap::gotUserFull(UserData *user, const MTPUserFull &result, mtpRequestI
|
|||
fullPeerUpdated().notify(user);
|
||||
}
|
||||
|
||||
void ApiWrap::requestPeer(PeerData *peer) {
|
||||
if (!peer || _fullPeerRequests.contains(peer) || _peerRequests.contains(peer)) return;
|
||||
void ApiWrap::requestPeer(not_null<PeerData*> peer) {
|
||||
if (_fullPeerRequests.contains(peer) || _peerRequests.contains(peer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto sendRequest = [this, peer] {
|
||||
auto failHandler = [this, peer](const RPCError &error) {
|
||||
const auto requestId = [&] {
|
||||
const auto failHandler = [=](const RPCError &error) {
|
||||
_peerRequests.remove(peer);
|
||||
};
|
||||
auto chatHandler = [this, peer](const MTPmessages_Chats &result) {
|
||||
const auto chatHandler = [=](const MTPmessages_Chats &result) {
|
||||
_peerRequests.remove(peer);
|
||||
|
||||
if (auto chats = Api::getChatsFromMessagesChats(result)) {
|
||||
if (const auto chats = Api::getChatsFromMessagesChats(result)) {
|
||||
auto &v = chats->v;
|
||||
bool badVersion = false;
|
||||
if (const auto chat = peer->asChat()) {
|
||||
|
@ -1151,12 +1172,12 @@ void ApiWrap::requestPeer(PeerData *peer) {
|
|||
&& (v[0].type() == mtpc_channel)
|
||||
&& (v[0].c_channel().vversion.v < channel->version);
|
||||
}
|
||||
auto chat = App::feedChats(*chats);
|
||||
const auto chat = App::feedChats(*chats);
|
||||
if (chat == peer) {
|
||||
if (badVersion) {
|
||||
if (auto chat = peer->asChat()) {
|
||||
if (const auto chat = peer->asChat()) {
|
||||
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;
|
||||
}
|
||||
requestPeer(peer);
|
||||
|
@ -1164,21 +1185,25 @@ void ApiWrap::requestPeer(PeerData *peer) {
|
|||
}
|
||||
}
|
||||
};
|
||||
if (auto user = peer->asUser()) {
|
||||
return request(MTPusers_GetUsers(MTP_vector<MTPInputUser>(1, user->inputUser))).done([this, user](const MTPVector<MTPUser> &result) {
|
||||
if (const auto user = peer->asUser()) {
|
||||
return request(MTPusers_GetUsers(
|
||||
MTP_vector<MTPInputUser>(1, user->inputUser)
|
||||
)).done([=](const MTPVector<MTPUser> &result) {
|
||||
_peerRequests.remove(user);
|
||||
App::feedUsers(result);
|
||||
}).fail(failHandler).send();
|
||||
} else if (auto chat = peer->asChat()) {
|
||||
return request(MTPmessages_GetChats(MTP_vector<MTPint>(1, chat->inputChat))).done(chatHandler).fail(failHandler).send();
|
||||
} else if (auto channel = peer->asChannel()) {
|
||||
return request(MTPchannels_GetChannels(MTP_vector<MTPInputChannel>(1, channel->inputChannel))).done(chatHandler).fail(failHandler).send();
|
||||
} else if (const auto chat = peer->asChat()) {
|
||||
return request(MTPmessages_GetChats(
|
||||
MTP_vector<MTPint>(1, chat->inputChat)
|
||||
)).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;
|
||||
};
|
||||
if (auto requestId = sendRequest()) {
|
||||
_peerRequests.insert(peer, requestId);
|
||||
}
|
||||
Unexpected("Peer type in requestPeer.");
|
||||
}();
|
||||
_peerRequests.insert(peer, requestId);
|
||||
}
|
||||
|
||||
void ApiWrap::markMediaRead(
|
||||
|
@ -1629,7 +1654,7 @@ void ApiWrap::unblockParticipant(
|
|||
} else {
|
||||
channel->updateFullForced();
|
||||
}
|
||||
}).fail([this, kick](const RPCError &error) {
|
||||
}).fail([=](const RPCError &error) {
|
||||
_kickRequests.remove(kick);
|
||||
}).send();
|
||||
|
||||
|
|
|
@ -99,8 +99,8 @@ public:
|
|||
void changeDialogUnreadMark(not_null<History*> history, bool unread);
|
||||
//void changeDialogUnreadMark(not_null<Data::Feed*> feed, bool unread); // #feed
|
||||
|
||||
void requestFullPeer(PeerData *peer);
|
||||
void requestPeer(PeerData *peer);
|
||||
void requestFullPeer(not_null<PeerData*> peer);
|
||||
void requestPeer(not_null<PeerData*> peer);
|
||||
void requestPeers(const QList<PeerData*> &peers);
|
||||
void requestLastParticipants(not_null<ChannelData*> channel);
|
||||
void requestBots(not_null<ChannelData*> channel);
|
||||
|
@ -138,8 +138,12 @@ public:
|
|||
void requestChannelMembersForAdd(
|
||||
not_null<ChannelData*> channel,
|
||||
Fn<void(const MTPchannels_ChannelParticipants&)> callback);
|
||||
void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result);
|
||||
void processFullPeer(UserData *user, const MTPUserFull &result);
|
||||
void processFullPeer(
|
||||
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(not_null<HistoryItem*> item);
|
||||
|
@ -435,8 +439,14 @@ private:
|
|||
not_null<Data::Feed*> feed,
|
||||
const MTPmessages_Dialogs &dialogs);
|
||||
|
||||
void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req);
|
||||
void gotUserFull(UserData *user, const MTPUserFull &result, mtpRequestId req);
|
||||
void gotChatFull(
|
||||
not_null<PeerData*> peer,
|
||||
const MTPmessages_ChatFull &result,
|
||||
mtpRequestId req);
|
||||
void gotUserFull(
|
||||
not_null<UserData*> user,
|
||||
const MTPUserFull &result,
|
||||
mtpRequestId req);
|
||||
void applyLastParticipantsList(
|
||||
not_null<ChannelData*> channel,
|
||||
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);
|
||||
}
|
||||
|
||||
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(
|
||||
QWidget*,
|
||||
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 {
|
||||
public:
|
||||
PinMessageBox(QWidget*, not_null<PeerData*> peer, MsgId msgId);
|
||||
|
|
|
@ -132,44 +132,6 @@ bool InviteSelectedUsers(
|
|||
// 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) {
|
||||
_action = action;
|
||||
refreshActionLink();
|
||||
|
@ -595,191 +557,6 @@ void AddParticipantsBoxController::Start(not_null<ChannelData*> channel) {
|
|||
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) {
|
||||
auto initBox = [=](not_null<PeerListBox*> box) {
|
||||
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 {
|
||||
public:
|
||||
static void Start(not_null<ChatData*> chat);
|
||||
|
|
|
@ -291,20 +291,25 @@ void EditRestrictedBox::prepare() {
|
|||
object_ptr<BoxContentDivider>(this),
|
||||
st::rightsDividerMargin);
|
||||
|
||||
const auto prepareRights = _oldRights.c_chatBannedRights().vflags.v
|
||||
const auto prepareRights = (_oldRights.c_chatBannedRights().vflags.v
|
||||
? _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()
|
||||
? (channel()->defaultRestrictions()
|
||||
/*| (channel()->isPublic()
|
||||
| (channel()->isPublic()
|
||||
? (Flag::f_change_info | Flag::f_pin_messages)
|
||||
: Flags(0))*/) // #TODO groups
|
||||
: Flags(0))) // #TODO groups
|
||||
: ~Flags(0);
|
||||
|
||||
auto [checkboxes, getRestrictions, changes] = CreateEditRestrictions(
|
||||
this,
|
||||
lng_rights_user_restrictions_header,
|
||||
prepareRights.c_chatBannedRights().vflags.v,
|
||||
prepareFlags,
|
||||
disabledFlags);
|
||||
addControl(std::move(checkboxes), QMargins());
|
||||
|
||||
|
@ -345,14 +350,7 @@ void EditRestrictedBox::prepare() {
|
|||
|
||||
MTPChatBannedRights EditRestrictedBox::Defaults(
|
||||
not_null<ChannelData*> channel) {
|
||||
const auto defaultRights = Flag::f_send_messages
|
||||
| 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));
|
||||
return MTP_chatBannedRights(MTP_flags(0), MTP_int(0));
|
||||
}
|
||||
|
||||
void EditRestrictedBox::showRestrictUntil() {
|
||||
|
|
|
@ -111,8 +111,6 @@ private:
|
|||
object_ptr<Ui::RpWidget> createHistoryVisibilityEdit();
|
||||
object_ptr<Ui::RpWidget> createSignaturesEdit();
|
||||
object_ptr<Ui::RpWidget> createStickersEdit();
|
||||
object_ptr<Ui::RpWidget> createManageAdminsButton();
|
||||
object_ptr<Ui::RpWidget> createUpgradeButton();
|
||||
object_ptr<Ui::RpWidget> createDeleteButton();
|
||||
|
||||
QString inviteLinkText() const;
|
||||
|
@ -210,8 +208,6 @@ object_ptr<Ui::VerticalLayout> Controller::createContent() {
|
|||
_wrap->add(createHistoryVisibilityEdit());
|
||||
_wrap->add(createSignaturesEdit());
|
||||
_wrap->add(createStickersEdit());
|
||||
_wrap->add(createManageAdminsButton());
|
||||
_wrap->add(createUpgradeButton());
|
||||
_wrap->add(createDeleteButton());
|
||||
|
||||
return result;
|
||||
|
@ -312,11 +308,6 @@ object_ptr<Ui::RpWidget> Controller::createTitleEdit() {
|
|||
object_ptr<Ui::RpWidget> Controller::createDescriptionEdit() {
|
||||
Expects(_wrap != nullptr);
|
||||
|
||||
auto channel = _peer->asChannel();
|
||||
if (!channel || !channel->canEditInformation()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto result = object_ptr<Ui::PaddingWrap<Ui::InputField>>(
|
||||
_wrap,
|
||||
object_ptr<Ui::InputField>(
|
||||
|
@ -324,7 +315,7 @@ object_ptr<Ui::RpWidget> Controller::createDescriptionEdit() {
|
|||
st::editPeerDescription,
|
||||
Ui::InputField::Mode::MultiLine,
|
||||
langFactory(lng_create_group_description),
|
||||
channel->about()),
|
||||
_peer->about()),
|
||||
st::editPeerDescriptionMargins);
|
||||
result->entity()->setMaxLength(kMaxChannelDescription);
|
||||
result->entity()->setInstantReplaces(Ui::InstantReplaces::Default());
|
||||
|
@ -346,8 +337,15 @@ object_ptr<Ui::RpWidget> Controller::createDescriptionEdit() {
|
|||
object_ptr<Ui::RpWidget> Controller::createPrivaciesEdit() {
|
||||
Expects(_wrap != nullptr);
|
||||
|
||||
auto channel = _peer->asChannel();
|
||||
if (!channel || !channel->canEditUsername()) {
|
||||
const auto 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;
|
||||
}
|
||||
auto result = object_ptr<Ui::PaddingWrap<Ui::VerticalLayout>>(
|
||||
|
@ -356,8 +354,10 @@ object_ptr<Ui::RpWidget> Controller::createPrivaciesEdit() {
|
|||
st::editPeerPrivaciesMargins);
|
||||
auto container = result->entity();
|
||||
|
||||
const auto isPublic = _peer->isChannel()
|
||||
&& _peer->asChannel()->isPublic();
|
||||
_controls.privacy = std::make_shared<Ui::RadioenumGroup<Privacy>>(
|
||||
channel->isPublic() ? Privacy::Public : Privacy::Private);
|
||||
isPublic ? Privacy::Public : Privacy::Private);
|
||||
auto addButton = [&](
|
||||
Privacy value,
|
||||
LangKey groupTextKey,
|
||||
|
@ -401,7 +401,7 @@ object_ptr<Ui::RpWidget> Controller::createPrivaciesEdit() {
|
|||
_controls.privacy->setChangedCallback([this](Privacy value) {
|
||||
privacyChanged(value);
|
||||
});
|
||||
if (!channel->isPublic()) {
|
||||
if (!isPublic) {
|
||||
checkUsernameAvailability();
|
||||
}
|
||||
|
||||
|
@ -411,8 +411,8 @@ object_ptr<Ui::RpWidget> Controller::createPrivaciesEdit() {
|
|||
object_ptr<Ui::RpWidget> Controller::createUsernameEdit() {
|
||||
Expects(_wrap != nullptr);
|
||||
|
||||
auto channel = _peer->asChannel();
|
||||
Assert(channel != nullptr);
|
||||
const auto channel = _peer->asChannel();
|
||||
const auto username = channel ? channel->username : QString();
|
||||
|
||||
auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||
_wrap,
|
||||
|
@ -434,7 +434,7 @@ object_ptr<Ui::RpWidget> Controller::createUsernameEdit() {
|
|||
container,
|
||||
st::setupChannelLink,
|
||||
Fn<QString()>(),
|
||||
channel->username,
|
||||
username,
|
||||
true));
|
||||
_controls.username->heightValue(
|
||||
) | rpl::start_with_next([placeholder](int height) {
|
||||
|
@ -506,9 +506,6 @@ void Controller::checkUsernameAvailability() {
|
|||
if (!_controls.username) {
|
||||
return;
|
||||
}
|
||||
auto channel = _peer->asChannel();
|
||||
Assert(channel != nullptr);
|
||||
|
||||
auto initial = (_controls.privacy->value() != Privacy::Public);
|
||||
auto checking = initial
|
||||
? qsl(".bad.")
|
||||
|
@ -519,15 +516,17 @@ void Controller::checkUsernameAvailability() {
|
|||
if (_checkUsernameRequestId) {
|
||||
request(_checkUsernameRequestId).cancel();
|
||||
}
|
||||
const auto channel = _peer->asChannel();
|
||||
const auto username = channel ? channel->username : QString();
|
||||
_checkUsernameRequestId = request(MTPchannels_CheckUsername(
|
||||
channel->inputChannel,
|
||||
channel ? channel->inputChannel : MTP_inputChannelEmpty(),
|
||||
MTP_string(checking)
|
||||
)).done([=](const MTPBool &result) {
|
||||
_checkUsernameRequestId = 0;
|
||||
if (initial) {
|
||||
return;
|
||||
}
|
||||
if (!mtpIsTrue(result) && checking != channel->username) {
|
||||
if (!mtpIsTrue(result) && checking != username) {
|
||||
showUsernameError(
|
||||
Lang::Viewer(lng_create_channel_link_occupied));
|
||||
} else {
|
||||
|
@ -555,7 +554,7 @@ void Controller::checkUsernameAvailability() {
|
|||
showUsernameError(
|
||||
Lang::Viewer(lng_create_channel_link_invalid));
|
||||
} else if (type == qstr("USERNAME_OCCUPIED")
|
||||
&& checking != channel->username) {
|
||||
&& checking != username) {
|
||||
showUsernameError(
|
||||
Lang::Viewer(lng_create_channel_link_occupied));
|
||||
}
|
||||
|
@ -656,13 +655,13 @@ void Controller::exportInviteLink(const QString &confirmation) {
|
|||
}
|
||||
|
||||
bool Controller::canEditInviteLink() const {
|
||||
if (auto channel = _peer->asChannel()) {
|
||||
if (const auto channel = _peer->asChannel()) {
|
||||
if (channel->canEditUsername()) {
|
||||
return true;
|
||||
}
|
||||
return (!channel->isPublic() && channel->canAddMembers());
|
||||
} else if (auto chat = _peer->asChat()) {
|
||||
return !chat->inviteLink().isEmpty() || chat->amCreator();
|
||||
} else if (const auto chat = _peer->asChat()) {
|
||||
return chat->amCreator() || !chat->inviteLink().isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -673,9 +672,9 @@ bool Controller::inviteLinkShown() const {
|
|||
}
|
||||
|
||||
QString Controller::inviteLinkText() const {
|
||||
if (auto channel = _peer->asChannel()) {
|
||||
if (const auto channel = _peer->asChannel()) {
|
||||
return channel->inviteLink();
|
||||
} else if (auto chat = _peer->asChat()) {
|
||||
} else if (const auto chat = _peer->asChat()) {
|
||||
return chat->inviteLink();
|
||||
}
|
||||
return QString();
|
||||
|
@ -808,13 +807,19 @@ void Controller::refreshCreateInviteLink() {
|
|||
object_ptr<Ui::RpWidget> Controller::createHistoryVisibilityEdit() {
|
||||
Expects(_wrap != nullptr);
|
||||
|
||||
auto channel = _peer->asChannel();
|
||||
if (!channel
|
||||
|| !channel->canEditPreHistoryHidden()
|
||||
|| !channel->isMegagroup()
|
||||
|| (channel->isPublic() && !channel->canEditUsername())) {
|
||||
const auto canEdit = [&] {
|
||||
if (const auto chat = _peer->asChat()) {
|
||||
return chat->canEditPreHistoryHidden();
|
||||
} else if (const auto channel = _peer->asChannel()) {
|
||||
return channel->canEditPreHistoryHidden();
|
||||
}
|
||||
Unexpected("User in Controller::createHistoryVisibilityEdit.");
|
||||
}();
|
||||
if (!canEdit) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto channel = _peer->asChannel();
|
||||
|
||||
auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||
_wrap,
|
||||
object_ptr<Ui::VerticalLayout>(_wrap),
|
||||
|
@ -824,7 +829,7 @@ object_ptr<Ui::RpWidget> Controller::createHistoryVisibilityEdit() {
|
|||
|
||||
_controls.historyVisibility
|
||||
= std::make_shared<Ui::RadioenumGroup<HistoryVisibility>>(
|
||||
channel->hiddenPreHistory()
|
||||
(!channel || channel->hiddenPreHistory())
|
||||
? HistoryVisibility::Hidden
|
||||
: HistoryVisibility::Visible);
|
||||
auto addButton = [&](
|
||||
|
@ -941,53 +946,13 @@ object_ptr<Ui::RpWidget> Controller::createStickersEdit() {
|
|||
_wrap,
|
||||
lang(lng_group_stickers_add),
|
||||
st::editPeerInviteLinkButton)
|
||||
)->addClickHandler([channel] {
|
||||
)->addClickHandler([=] {
|
||||
Ui::show(Box<StickersBox>(channel), LayerOption::KeepOther);
|
||||
});
|
||||
|
||||
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() {
|
||||
Expects(_wrap != nullptr);
|
||||
|
||||
|
@ -1139,12 +1104,15 @@ void Controller::cancelSave() {
|
|||
}
|
||||
|
||||
void Controller::saveUsername() {
|
||||
auto channel = _peer->asChannel();
|
||||
if (!_savingData.username
|
||||
|| !channel
|
||||
|| *_savingData.username == channel->username) {
|
||||
const auto channel = _peer->asChannel();
|
||||
const auto username = (channel ? channel->username : QString());
|
||||
if (!_savingData.username || *_savingData.username == username) {
|
||||
return continueSave();
|
||||
} else if (!channel) {
|
||||
// #TODO groups convert and save.
|
||||
return continueSave();
|
||||
}
|
||||
|
||||
request(MTPchannels_UpdateUsername(
|
||||
channel->inputChannel,
|
||||
MTP_string(*_savingData.username)
|
||||
|
@ -1154,7 +1122,7 @@ void Controller::saveUsername() {
|
|||
*_savingData.username);
|
||||
continueSave();
|
||||
}).fail([=](const RPCError &error) {
|
||||
auto type = error.type();
|
||||
const auto type = error.type();
|
||||
if (type == qstr("USERNAME_NOT_MODIFIED")) {
|
||||
channel->setName(
|
||||
TextUtilities::SingleLine(channel->name),
|
||||
|
@ -1162,7 +1130,7 @@ void Controller::saveUsername() {
|
|||
continueSave();
|
||||
return;
|
||||
}
|
||||
auto errorKey = [&] {
|
||||
const auto errorKey = [&] {
|
||||
if (type == qstr("USERNAME_INVALID")) {
|
||||
return lng_create_channel_link_invalid;
|
||||
} else if (type == qstr("USERNAME_OCCUPIED")
|
||||
|
@ -1183,17 +1151,17 @@ void Controller::saveTitle() {
|
|||
return continueSave();
|
||||
}
|
||||
|
||||
auto onDone = [this](const MTPUpdates &result) {
|
||||
const auto onDone = [=](const MTPUpdates &result) {
|
||||
Auth().api().applyUpdates(result);
|
||||
continueSave();
|
||||
};
|
||||
auto onFail = [this](const RPCError &error) {
|
||||
auto type = error.type();
|
||||
const auto onFail = [=](const RPCError &error) {
|
||||
const auto type = error.type();
|
||||
if (type == qstr("CHAT_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);
|
||||
} else if (auto chat = _peer->asChat()) {
|
||||
} else if (const auto chat = _peer->asChat()) {
|
||||
chat->setName(*_savingData.title);
|
||||
}
|
||||
continueSave();
|
||||
|
@ -1206,14 +1174,14 @@ void Controller::saveTitle() {
|
|||
cancelSave();
|
||||
};
|
||||
|
||||
if (auto channel = _peer->asChannel()) {
|
||||
if (const auto channel = _peer->asChannel()) {
|
||||
request(MTPchannels_EditTitle(
|
||||
channel->inputChannel,
|
||||
MTP_string(*_savingData.title)
|
||||
)).done(std::move(onDone)
|
||||
).fail(std::move(onFail)
|
||||
).send();
|
||||
} else if (auto chat = _peer->asChat()) {
|
||||
} else if (const auto chat = _peer->asChat()) {
|
||||
request(MTPmessages_EditChatTitle(
|
||||
chat->inputChat,
|
||||
MTP_string(*_savingData.title)
|
||||
|
@ -1226,18 +1194,17 @@ void Controller::saveTitle() {
|
|||
}
|
||||
|
||||
void Controller::saveDescription() {
|
||||
auto channel = _peer->asChannel();
|
||||
const auto channel = _peer->asChannel();
|
||||
if (!_savingData.description
|
||||
|| !channel
|
||||
|| *_savingData.description == channel->about()) {
|
||||
|| *_savingData.description == _peer->about()) {
|
||||
return continueSave();
|
||||
}
|
||||
auto successCallback = [=] {
|
||||
channel->setAbout(*_savingData.description);
|
||||
const auto successCallback = [=] {
|
||||
_peer->setAbout(*_savingData.description);
|
||||
continueSave();
|
||||
};
|
||||
request(MTPmessages_EditChatAbout(
|
||||
channel->input,
|
||||
_peer->input,
|
||||
MTP_string(*_savingData.description)
|
||||
)).done([=](const MTPBool &result) {
|
||||
successCallback();
|
||||
|
@ -1253,10 +1220,13 @@ void Controller::saveDescription() {
|
|||
}
|
||||
|
||||
void Controller::saveHistoryVisibility() {
|
||||
auto channel = _peer->asChannel();
|
||||
const auto channel = _peer->asChannel();
|
||||
const auto hidden = channel ? channel->hiddenPreHistory() : true;
|
||||
if (!_savingData.hiddenPreHistory
|
||||
|| !channel
|
||||
|| *_savingData.hiddenPreHistory == channel->hiddenPreHistory()) {
|
||||
|| *_savingData.hiddenPreHistory == hidden) {
|
||||
return continueSave();
|
||||
} else if (!channel) {
|
||||
// #TODO groups convert and save.
|
||||
return continueSave();
|
||||
}
|
||||
request(MTPchannels_TogglePreHistoryHidden(
|
||||
|
@ -1280,7 +1250,7 @@ void Controller::saveHistoryVisibility() {
|
|||
}
|
||||
|
||||
void Controller::saveSignatures() {
|
||||
auto channel = _peer->asChannel();
|
||||
const auto channel = _peer->asChannel();
|
||||
if (!_savingData.signatures
|
||||
|| !channel
|
||||
|| *_savingData.signatures == channel->addsSignature()) {
|
||||
|
@ -1315,21 +1285,25 @@ void Controller::deleteWithConfirmation() {
|
|||
const auto channel = _peer->asChannel();
|
||||
Assert(channel != nullptr);
|
||||
|
||||
auto text = lang(_isGroup
|
||||
const auto text = lang(_isGroup
|
||||
? lng_sure_delete_group
|
||||
: lng_sure_delete_channel);
|
||||
auto deleteCallback = crl::guard(this, [=] {
|
||||
const auto deleteCallback = crl::guard(this, [=] {
|
||||
deleteChannel();
|
||||
});
|
||||
Ui::show(Box<ConfirmBox>(
|
||||
text,
|
||||
lang(lng_box_delete),
|
||||
st::attentionBoxButton,
|
||||
std::move(deleteCallback)), LayerOption::KeepOther);
|
||||
Ui::show(
|
||||
Box<ConfirmBox>(
|
||||
text,
|
||||
lang(lng_box_delete),
|
||||
st::attentionBoxButton,
|
||||
deleteCallback),
|
||||
LayerOption::KeepOther);
|
||||
}
|
||||
|
||||
void Controller::deleteChannel() {
|
||||
const auto channel = _peer->asChannel();
|
||||
Assert(channel != nullptr);
|
||||
|
||||
const auto chat = channel->migrateFrom();
|
||||
|
||||
Ui::hideLayer();
|
||||
|
|
|
@ -189,7 +189,6 @@ auto ToPositiveNumberString() {
|
|||
|
||||
ChatRestrictions DisabledByAdminRights(not_null<PeerData*> peer) {
|
||||
using Flag = ChatRestriction;
|
||||
using Flags = ChatRestrictions;
|
||||
using Admin = ChatAdminRight;
|
||||
using Admins = ChatAdminRights;
|
||||
|
||||
|
@ -241,13 +240,13 @@ void EditPeerPermissionsBox::prepare() {
|
|||
const auto restrictions = [&] {
|
||||
if (const auto chat = _peer->asChat()) {
|
||||
return chat->defaultRestrictions()
|
||||
/*| disabledByAdminRights*/; // #TODO groups
|
||||
| disabledByAdminRights; // #TODO groups
|
||||
} else if (const auto channel = _peer->asChannel()) {
|
||||
return (channel->defaultRestrictions()
|
||||
/*| (channel->isPublic()
|
||||
| (channel->isPublic()
|
||||
? (Flag::f_change_info | Flag::f_pin_messages)
|
||||
: Flags(0))
|
||||
| disabledByAdminRights*/); // #TODO groups
|
||||
| disabledByAdminRights); // #TODO groups
|
||||
}
|
||||
Unexpected("User in EditPeerPermissionsBox.");
|
||||
}();
|
||||
|
|
|
@ -55,15 +55,6 @@ void ChannelData::setName(const QString &newName, const 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) {
|
||||
if (newInviteLink != _inviteLink) {
|
||||
_inviteLink = newInviteLink;
|
||||
|
@ -365,7 +356,9 @@ bool ChannelData::canEditSignatures() const {
|
|||
}
|
||||
|
||||
bool ChannelData::canEditPreHistoryHidden() const {
|
||||
return canEditInformation();
|
||||
return canEditInformation()
|
||||
&& isMegagroup()
|
||||
&& (!isPublic() || canEditUsername());
|
||||
}
|
||||
|
||||
bool ChannelData::canEditUsername() const {
|
||||
|
|
|
@ -124,12 +124,6 @@ public:
|
|||
return _fullFlags.value();
|
||||
}
|
||||
|
||||
// Returns true if about text was changed.
|
||||
bool setAbout(const QString &newAbout);
|
||||
const QString &about() const {
|
||||
return _about;
|
||||
}
|
||||
|
||||
int membersCount() const {
|
||||
return _membersCount;
|
||||
}
|
||||
|
@ -249,6 +243,8 @@ public:
|
|||
bool canWrite() const;
|
||||
bool canEditInformation() const;
|
||||
bool canEditPermissions() const;
|
||||
bool canEditUsername() const;
|
||||
bool canEditPreHistoryHidden() const;
|
||||
bool canAddMembers() const;
|
||||
|
||||
bool canBanMembers() const;
|
||||
|
@ -262,8 +258,6 @@ public:
|
|||
bool canViewAdmins() const;
|
||||
bool canViewBanned() const;
|
||||
bool canEditSignatures() const;
|
||||
bool canEditPreHistoryHidden() const;
|
||||
bool canEditUsername() const;
|
||||
bool canEditStickers() const;
|
||||
bool canDelete() const;
|
||||
bool canEditAdmin(not_null<UserData*> user) const;
|
||||
|
@ -346,9 +340,6 @@ public:
|
|||
TimeId inviteDate = 0;
|
||||
|
||||
private:
|
||||
void flagsUpdated(MTPDchannel::Flags diff);
|
||||
void fullFlagsUpdated(MTPDchannelFull::Flags diff);
|
||||
|
||||
bool canEditLastAdmin(not_null<UserData*> user) const;
|
||||
void setFeedPointer(Data::Feed *feed);
|
||||
|
||||
|
@ -369,7 +360,6 @@ private:
|
|||
TimeId _restrictedUntil;
|
||||
|
||||
QString _unavailableReason;
|
||||
QString _about;
|
||||
|
||||
QString _inviteLink;
|
||||
Data::Feed *_feed = nullptr;
|
||||
|
|
|
@ -53,6 +53,15 @@ bool ChatData::canEditPermissions() const {
|
|||
&& (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 {
|
||||
return !actionsUnavailable()
|
||||
&& !amRestricted(ChatRestriction::f_invite_users);
|
||||
|
|
|
@ -23,6 +23,12 @@ public:
|
|||
MTPDchat::Flags,
|
||||
kEssentialFlags>;
|
||||
|
||||
static constexpr auto kEssentialFullFlags = 0
|
||||
| MTPDchatFull::Flag::f_can_set_username;
|
||||
using FullFlags = Data::Flags<
|
||||
MTPDchatFull::Flags,
|
||||
kEssentialFullFlags>;
|
||||
|
||||
using AdminRight = ChatAdminRight;
|
||||
using Restriction = ChatRestriction;
|
||||
using AdminRights = ChatAdminRights;
|
||||
|
@ -58,6 +64,22 @@ public:
|
|||
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 {
|
||||
return _adminRights.current();
|
||||
}
|
||||
|
@ -103,6 +125,8 @@ public:
|
|||
bool canWrite() const;
|
||||
bool canEditInformation() const;
|
||||
bool canEditPermissions() const;
|
||||
bool canEditUsername() const;
|
||||
bool canEditPreHistoryHidden() const;
|
||||
bool canAddMembers() const;
|
||||
|
||||
void setInviteLink(const QString &newInviteLink);
|
||||
|
@ -130,9 +154,9 @@ public:
|
|||
|
||||
private:
|
||||
[[nodiscard]] bool actionsUnavailable() const;
|
||||
void flagsUpdated(MTPDchat::Flags diff);
|
||||
|
||||
Flags _flags;
|
||||
FullFlags _fullFlags;
|
||||
QString _inviteLink;
|
||||
|
||||
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() {
|
||||
_nameWords.clear();
|
||||
_nameFirstLetters.clear();
|
||||
|
|
|
@ -224,6 +224,12 @@ public:
|
|||
setPinnedMessageId(0);
|
||||
}
|
||||
|
||||
// Returns true if about text was changed.
|
||||
bool setAbout(const QString &newAbout);
|
||||
const QString &about() const {
|
||||
return _about;
|
||||
}
|
||||
|
||||
protected:
|
||||
void updateNameDelayed(
|
||||
const QString &newName,
|
||||
|
@ -260,4 +266,6 @@ private:
|
|||
TimeMs _lastFullUpdate = 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 {
|
||||
return _unavailableReason;
|
||||
}
|
||||
|
|
|
@ -195,11 +195,6 @@ public:
|
|||
bool hasCalls() const;
|
||||
void setCallsStatus(CallsStatus callsStatus);
|
||||
|
||||
bool setAbout(const QString &newAbout);
|
||||
const QString &about() const {
|
||||
return _about;
|
||||
}
|
||||
|
||||
std::unique_ptr<BotInfo> botInfo;
|
||||
|
||||
QString unavailableReason() const override;
|
||||
|
@ -215,7 +210,6 @@ private:
|
|||
FullFlags _fullFlags;
|
||||
|
||||
QString _unavailableReason;
|
||||
QString _about;
|
||||
QString _phone;
|
||||
ContactStatus _contactStatus = ContactStatus::PhoneUnknown;
|
||||
BlockStatus _blockStatus = BlockStatus::Unknown;
|
||||
|
|
|
@ -2738,8 +2738,8 @@ int HistoryInner::itemTop(const Element *view) const {
|
|||
}
|
||||
|
||||
void HistoryInner::notifyIsBotChanged() {
|
||||
const auto newinfo = (_history && _history->peer->isUser())
|
||||
? _history->peer->asUser()->botInfo.get()
|
||||
const auto newinfo = (_peer && _peer->isUser())
|
||||
? _peer->asUser()->botInfo.get()
|
||||
: nullptr;
|
||||
if ((!newinfo && !_botAbout)
|
||||
|| (newinfo && _botAbout && _botAbout->info == newinfo)) {
|
||||
|
|
|
@ -3686,7 +3686,7 @@ void HistoryWidget::setMembersShowAreaActive(bool active) {
|
|||
void HistoryWidget::onMembersDropdownShow() {
|
||||
if (!_membersDropdown) {
|
||||
_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->setMaxHeight(countMembersDropdownHeightMax());
|
||||
|
|
|
@ -324,7 +324,7 @@ void Members::updateHeaderControlsGeometry(int newWidth) {
|
|||
void Members::addMember() {
|
||||
if (const auto chat = _peer->asChat()) {
|
||||
if (chat->count >= Global::ChatSizeMax() && chat->amCreator()) {
|
||||
Ui::show(Box<ConvertToSupergroupBox>(chat));
|
||||
// #TODO convert and add inside AddParticipantsBoxController?
|
||||
} else {
|
||||
AddParticipantsBoxController::Start(chat);
|
||||
}
|
||||
|
|
|
@ -46,8 +46,8 @@ rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user) {
|
|||
|
||||
auto PlainBioValue(not_null<UserData*> user) {
|
||||
return Notify::PeerUpdateValue(
|
||||
user,
|
||||
Notify::PeerUpdate::Flag::AboutChanged
|
||||
user,
|
||||
Notify::PeerUpdate::Flag::AboutChanged
|
||||
) | rpl::map([user] { return user->about(); });
|
||||
}
|
||||
|
||||
|
@ -77,20 +77,17 @@ rpl::producer<TextWithEntities> UsernameValue(not_null<UserData*> user) {
|
|||
}
|
||||
|
||||
rpl::producer<QString> PlainAboutValue(not_null<PeerData*> peer) {
|
||||
if (auto channel = peer->asChannel()) {
|
||||
return Notify::PeerUpdateValue(
|
||||
channel,
|
||||
Notify::PeerUpdate::Flag::AboutChanged
|
||||
) | rpl::map([channel] { return channel->about(); });
|
||||
} else if (auto user = peer->asUser()) {
|
||||
if (user->botInfo) {
|
||||
return PlainBioValue(user);
|
||||
if (const auto user = peer->asUser()) {
|
||||
if (!user->botInfo) {
|
||||
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) {
|
||||
auto flags = TextParseLinks
|
||||
| TextParseMentions
|
||||
|
@ -160,9 +157,9 @@ rpl::producer<bool> CanShareContactValue(not_null<UserData*> user) {
|
|||
rpl::producer<bool> CanAddContactValue(not_null<UserData*> user) {
|
||||
using namespace rpl::mappers;
|
||||
return rpl::combine(
|
||||
IsContactValue(user),
|
||||
CanShareContactValue(user),
|
||||
!_1 && _2);
|
||||
IsContactValue(user),
|
||||
CanShareContactValue(user),
|
||||
!_1 && _2);
|
||||
}
|
||||
|
||||
rpl::producer<bool> AmInChannelValue(not_null<ChannelData*> channel) {
|
||||
|
@ -177,7 +174,7 @@ rpl::producer<int> MembersCountValue(not_null<PeerData*> peer) {
|
|||
if (const auto chat = peer->asChat()) {
|
||||
return Notify::PeerUpdateValue(
|
||||
peer,
|
||||
Notify::PeerUpdate::Flag::MembersChanged
|
||||
Flag::MembersChanged
|
||||
) | rpl::map([chat] {
|
||||
return chat->amIn()
|
||||
? std::max(chat->count, int(chat->participants.size()))
|
||||
|
@ -185,8 +182,8 @@ rpl::producer<int> MembersCountValue(not_null<PeerData*> peer) {
|
|||
});
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
return Notify::PeerUpdateValue(
|
||||
channel,
|
||||
Notify::PeerUpdate::Flag::MembersChanged
|
||||
channel,
|
||||
Flag::MembersChanged
|
||||
) | rpl::map([channel] {
|
||||
return channel->membersCount();
|
||||
});
|
||||
|
|
|
@ -3875,14 +3875,15 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) {
|
|||
case mtpc_updateShortChatMessage: {
|
||||
auto &d = updates.c_updateShortChatMessage();
|
||||
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
|
||||
|| (d.has_via_bot_id() && !App::userLoaded(d.vvia_bot_id.v))
|
||||
|| (d.has_entities() && !mentionUsersLoaded(d.ventities))
|
||||
|| (d.has_fwd_from() && !fwdInfoDataLoaded(d.vfwd_from))) {
|
||||
MTP_LOG(0, ("getDifference { good - getting user for updateShortChatMessage }%1").arg(cTestMode() ? " TESTMODE" : ""));
|
||||
if (noFrom) {
|
||||
Auth().api().requestFullPeer(App::chatLoaded(d.vchat_id.v));
|
||||
if (chat && noFrom) {
|
||||
Auth().api().requestFullPeer(chat);
|
||||
}
|
||||
return getDifference();
|
||||
}
|
||||
|
@ -4240,8 +4241,13 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
|||
Auth().api().requestPeer(chat);
|
||||
}
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
channel->setDefaultRestrictions(
|
||||
data.vdefault_banned_rights);
|
||||
if (data.vversion.v == channel->version + 1) {
|
||||
channel->setDefaultRestrictions(
|
||||
data.vdefault_banned_rights);
|
||||
} else {
|
||||
channel->version = data.vversion.v;
|
||||
Auth().api().requestPeer(channel);
|
||||
}
|
||||
} else {
|
||||
LOG(("API Error: "
|
||||
"User received in updateChatDefaultBannedRights."));
|
||||
|
|
|
@ -108,13 +108,6 @@ profileInviteLinkText: FlatLabel(profileBlockTextPart) {
|
|||
|
||||
profileLimitReachedSkip: 6px;
|
||||
|
||||
profileMemberItem: PeerListItem(defaultPeerListItem) {
|
||||
left: 8px;
|
||||
bottom: profileBlockMarginBottom;
|
||||
button: defaultLeftOutlineButton;
|
||||
maximalWidth: profileBlockWideWidthMax;
|
||||
statusFgOver: profileStatusFgOver;
|
||||
}
|
||||
profileMemberPaddingLeft: 16px;
|
||||
profileMemberNameFg: windowBoldFg;
|
||||
profileMemberCreatorIcon: icon {{ "profile_admin_star", profileAdminStartFg, point(4px, 3px) }};
|
||||
|
|
|
@ -40,13 +40,8 @@ UserData *GroupMembersWidget::Member::user() const {
|
|||
GroupMembersWidget::GroupMembersWidget(
|
||||
QWidget *parent,
|
||||
PeerData *peer,
|
||||
TitleVisibility titleVisibility,
|
||||
const style::PeerListItem &st)
|
||||
: PeerListWidget(parent
|
||||
, peer
|
||||
, (titleVisibility == TitleVisibility::Visible) ? lang(lng_profile_participants_section) : QString()
|
||||
, st
|
||||
, lang(lng_profile_kick)) {
|
||||
: PeerListWidget(parent, peer, QString(), st, lang(lng_profile_kick)) {
|
||||
_updateOnlineTimer.setSingleShot(true);
|
||||
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) {
|
||||
auto member = getMember(item);
|
||||
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() {
|
||||
_now = unixtime();
|
||||
if (auto chat = peer()->asChat()) {
|
||||
|
@ -320,7 +229,6 @@ void GroupMembersWidget::refreshMembers() {
|
|||
Auth().api().requestFullPeer(chat);
|
||||
}
|
||||
fillChatMembers(chat);
|
||||
refreshLimitReached();
|
||||
} else if (auto megagroup = peer()->asMegagroup()) {
|
||||
auto &megagroupInfo = megagroup->mgInfo;
|
||||
if (megagroupInfo->lastParticipants.empty() || megagroup->lastParticipantsCountOutdated()) {
|
||||
|
@ -333,27 +241,6 @@ void GroupMembersWidget::refreshMembers() {
|
|||
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) {
|
||||
if (chat->participants.empty()) return;
|
||||
|
||||
|
|
|
@ -24,11 +24,7 @@ class GroupMembersWidget : public PeerListWidget {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class TitleVisibility {
|
||||
Visible,
|
||||
Hidden,
|
||||
};
|
||||
GroupMembersWidget(QWidget *parent, PeerData *peer, TitleVisibility titleVisibility = TitleVisibility::Visible, const style::PeerListItem &st = st::profileMemberItem);
|
||||
GroupMembersWidget(QWidget *parent, PeerData *peer, const style::PeerListItem &st);
|
||||
|
||||
int onlineCount() const {
|
||||
return _onlineCount;
|
||||
|
@ -36,14 +32,6 @@ public:
|
|||
|
||||
~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:
|
||||
void onlineCountUpdated(int onlineCount);
|
||||
|
||||
|
@ -63,16 +51,10 @@ private:
|
|||
void sortMembers();
|
||||
void updateOnlineCount();
|
||||
void checkSelfAdmin(ChatData *chat);
|
||||
void refreshLimitReached();
|
||||
|
||||
void preloadMore();
|
||||
|
||||
bool limitReachedHook(const ClickHandlerPtr &handler, Qt::MouseButton button);
|
||||
|
||||
void refreshUserOnline(UserData *user);
|
||||
|
||||
int getListTop() const override;
|
||||
|
||||
struct Member : public Item {
|
||||
explicit Member(UserData *user);
|
||||
UserData *user() const;
|
||||
|
@ -93,8 +75,6 @@ private:
|
|||
void setItemFlags(Item *item, ChannelData *megagroup);
|
||||
bool addUsersToEnd(ChannelData *megagroup);
|
||||
|
||||
object_ptr<Ui::FlatLabel> _limitReachedInfo = { nullptr };
|
||||
|
||||
QMap<UserData*, Member*> _membersByUser;
|
||||
bool _sortByOnline = false;
|
||||
TimeId _now = 0;
|
||||
|
|
|
@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "profile/profile_block_peer_list.h"
|
||||
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/text_options.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "auth_session.h"
|
||||
|
@ -60,7 +59,7 @@ void PeerListWidget::paintContents(Painter &p) {
|
|||
auto to = ceilclamp(_visibleBottom - top, _st.height, 0, _items.size());
|
||||
for (auto i = from; i < to; ++i) {
|
||||
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;
|
||||
if (_pressed >= 0 && !_pressedRemove) {
|
||||
selectedRemove = false;
|
||||
|
@ -182,46 +181,6 @@ void PeerListWidget::mousePressReleased(Qt::MouseButton button) {
|
|||
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) {
|
||||
_mousePosition = QCursor::pos();
|
||||
updateSelection();
|
||||
|
|
|
@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "profile/profile_block_widget.h"
|
||||
#include "styles/style_profile.h"
|
||||
|
||||
namespace Ui {
|
||||
class RippleAnimation;
|
||||
|
@ -19,11 +18,15 @@ namespace Notify {
|
|||
struct PeerUpdate;
|
||||
} // namespace Notify
|
||||
|
||||
namespace style {
|
||||
struct PeerListItem;
|
||||
} // namespace style
|
||||
|
||||
namespace Profile {
|
||||
|
||||
class PeerListWidget : public BlockWidget {
|
||||
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 {
|
||||
explicit Item(PeerData *peer);
|
||||
|
@ -42,7 +45,7 @@ public:
|
|||
bool hasRemoveLink = false;
|
||||
std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||
};
|
||||
virtual int getListTop() const {
|
||||
int getListTop() const {
|
||||
return contentTop();
|
||||
}
|
||||
|
||||
|
@ -98,7 +101,6 @@ protected:
|
|||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void contextMenuEvent(QContextMenuEvent *e) override;
|
||||
void enterEventHook(QEvent *e) override;
|
||||
void enterFromChildEvent(QEvent *e, QWidget *child) override {
|
||||
enterEventHook(e);
|
||||
|
@ -108,10 +110,6 @@ protected:
|
|||
leaveEventHook(e);
|
||||
}
|
||||
|
||||
virtual Ui::PopupMenu *fillPeerMenu(PeerData *peer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
void mousePressReleased(Qt::MouseButton button);
|
||||
void updateSelection();
|
||||
|
@ -145,9 +143,6 @@ private:
|
|||
QString _removeText;
|
||||
int _removeWidth = 0;
|
||||
|
||||
Ui::PopupMenu *_menu = nullptr;
|
||||
int _menuRowIndex = -1;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Profile
|
||||
|
|
|
@ -109,7 +109,7 @@ History *FindWastedPin() {
|
|||
|
||||
void AddChatMembers(not_null<ChatData*> chat) {
|
||||
if (chat->count >= Global::ChatSizeMax() && chat->amCreator()) {
|
||||
Ui::show(Box<ConvertToSupergroupBox>(chat));
|
||||
// #TODO convert and add inside AddParticipantsBoxController?
|
||||
} else {
|
||||
AddParticipantsBoxController::Start(chat);
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ bool PinnedLimitReached(Dialogs::Key key) {
|
|||
return false;
|
||||
}
|
||||
// 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(key, true);
|
||||
Auth().api().savePinnedOrder();
|
||||
|
|
Loading…
Add table
Reference in a new issue