mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-22 09:07:05 +02:00
Edit join public group request requirement.
This commit is contained in:
parent
a752c4d9f3
commit
c3386fba52
8 changed files with 275 additions and 89 deletions
|
@ -1000,6 +1000,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_profile_view_discussion" = "View discussion";
|
"lng_profile_view_discussion" = "View discussion";
|
||||||
"lng_profile_join_channel" = "Join Channel";
|
"lng_profile_join_channel" = "Join Channel";
|
||||||
"lng_profile_join_group" = "Join Group";
|
"lng_profile_join_group" = "Join Group";
|
||||||
|
"lng_profile_apply_to_join_group" = "Apply to Join Group";
|
||||||
"lng_profile_delete_and_exit" = "Leave";
|
"lng_profile_delete_and_exit" = "Leave";
|
||||||
"lng_profile_kick" = "Remove";
|
"lng_profile_kick" = "Remove";
|
||||||
"lng_profile_delete_removed" = "Delete";
|
"lng_profile_delete_removed" = "Delete";
|
||||||
|
@ -1128,6 +1129,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_manage_public_group_title" = "Public";
|
"lng_manage_public_group_title" = "Public";
|
||||||
"lng_manage_private_peer_title" = "Private";
|
"lng_manage_private_peer_title" = "Private";
|
||||||
"lng_manage_public_peer_title" = "Public";
|
"lng_manage_public_peer_title" = "Public";
|
||||||
|
"lng_manage_peer_send_title" = "Who can send new messages?";
|
||||||
|
"lng_manage_peer_send_only_members" = "Only members";
|
||||||
|
"lng_manage_peer_send_only_members_about" = "Turn this on if you expect users to join your group before being able to send messages.";
|
||||||
|
"lng_manage_peer_send_approve_members" = "Approve new members";
|
||||||
|
"lng_manage_peer_send_approve_members_about" = "Turn this on if you want users to join the group only after they are approved by an admin.";
|
||||||
"lng_manage_peer_no_forwards_title" = "Saving content";
|
"lng_manage_peer_no_forwards_title" = "Saving content";
|
||||||
"lng_manage_peer_no_forwards" = "Restrict saving content";
|
"lng_manage_peer_no_forwards" = "Restrict saving content";
|
||||||
"lng_manage_peer_no_forwards_about" = "Members won't be able to forward messages from this group or save media files.";
|
"lng_manage_peer_no_forwards_about" = "Members won't be able to forward messages from this group or save media files.";
|
||||||
|
|
|
@ -269,6 +269,8 @@ private:
|
||||||
std::optional<bool> hiddenPreHistory;
|
std::optional<bool> hiddenPreHistory;
|
||||||
std::optional<bool> signatures;
|
std::optional<bool> signatures;
|
||||||
std::optional<bool> noForwards;
|
std::optional<bool> noForwards;
|
||||||
|
std::optional<bool> joinToWrite;
|
||||||
|
std::optional<bool> requestToJoin;
|
||||||
std::optional<ChannelData*> linkedChat;
|
std::optional<ChannelData*> linkedChat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -306,6 +308,8 @@ private:
|
||||||
[[nodiscard]] bool validateHistoryVisibility(Saving &to) const;
|
[[nodiscard]] bool validateHistoryVisibility(Saving &to) const;
|
||||||
[[nodiscard]] bool validateSignatures(Saving &to) const;
|
[[nodiscard]] bool validateSignatures(Saving &to) const;
|
||||||
[[nodiscard]] bool validateForwards(Saving &to) const;
|
[[nodiscard]] bool validateForwards(Saving &to) const;
|
||||||
|
[[nodiscard]] bool validateJoinToWrite(Saving &to) const;
|
||||||
|
[[nodiscard]] bool validateRequestToJoin(Saving &to) const;
|
||||||
|
|
||||||
void save();
|
void save();
|
||||||
void saveUsername();
|
void saveUsername();
|
||||||
|
@ -315,6 +319,8 @@ private:
|
||||||
void saveHistoryVisibility();
|
void saveHistoryVisibility();
|
||||||
void saveSignatures();
|
void saveSignatures();
|
||||||
void saveForwards();
|
void saveForwards();
|
||||||
|
void saveJoinToWrite();
|
||||||
|
void saveRequestToJoin();
|
||||||
void savePhoto();
|
void savePhoto();
|
||||||
void pushSaveStage(FnMut<void()> &&lambda);
|
void pushSaveStage(FnMut<void()> &&lambda);
|
||||||
void continueSave();
|
void continueSave();
|
||||||
|
@ -329,14 +335,12 @@ private:
|
||||||
void subscribeToMigration();
|
void subscribeToMigration();
|
||||||
void migrate(not_null<ChannelData*> channel);
|
void migrate(not_null<ChannelData*> channel);
|
||||||
|
|
||||||
std::optional<Privacy> _privacySavedValue;
|
|
||||||
std::optional<ChannelData*> _linkedChatSavedValue;
|
std::optional<ChannelData*> _linkedChatSavedValue;
|
||||||
ChannelData *_linkedChatOriginalValue = nullptr;
|
ChannelData *_linkedChatOriginalValue = nullptr;
|
||||||
bool _channelHasLocationOriginalValue = false;
|
bool _channelHasLocationOriginalValue = false;
|
||||||
std::optional<HistoryVisibility> _historyVisibilitySavedValue;
|
std::optional<HistoryVisibility> _historyVisibilitySavedValue;
|
||||||
std::optional<QString> _usernameSavedValue;
|
std::optional<EditPeerTypeData> _typeDataSavedValue;
|
||||||
std::optional<bool> _signaturesSavedValue;
|
std::optional<bool> _signaturesSavedValue;
|
||||||
std::optional<bool> _noForwardsSavedValue;
|
|
||||||
|
|
||||||
const not_null<Window::SessionNavigation*> _navigation;
|
const not_null<Window::SessionNavigation*> _navigation;
|
||||||
const not_null<Ui::BoxContent*> _box;
|
const not_null<Ui::BoxContent*> _box;
|
||||||
|
@ -602,8 +606,10 @@ void Controller::refreshHistoryVisibility() {
|
||||||
if (!_controls.historyVisibilityWrap) {
|
if (!_controls.historyVisibilityWrap) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const auto withUsername = _typeDataSavedValue
|
||||||
|
&& (_typeDataSavedValue->privacy == Privacy::HasUsername);
|
||||||
_controls.historyVisibilityWrap->toggle(
|
_controls.historyVisibilityWrap->toggle(
|
||||||
(_privacySavedValue != Privacy::HasUsername
|
(withUsername
|
||||||
&& !_channelHasLocationOriginalValue
|
&& !_channelHasLocationOriginalValue
|
||||||
&& (!_linkedChatSavedValue || !*_linkedChatSavedValue)),
|
&& (!_linkedChatSavedValue || !*_linkedChatSavedValue)),
|
||||||
anim::type::instant);
|
anim::type::instant);
|
||||||
|
@ -611,22 +617,19 @@ void Controller::refreshHistoryVisibility() {
|
||||||
|
|
||||||
void Controller::showEditPeerTypeBox(
|
void Controller::showEditPeerTypeBox(
|
||||||
std::optional<rpl::producer<QString>> error) {
|
std::optional<rpl::producer<QString>> error) {
|
||||||
const auto boxCallback = crl::guard(this, [=](
|
const auto boxCallback = crl::guard(this, [=](EditPeerTypeData data) {
|
||||||
Privacy checked, QString publicLink, bool noForwards) {
|
_privacyTypeUpdates.fire_copy(data.privacy);
|
||||||
_privacyTypeUpdates.fire(std::move(checked));
|
_typeDataSavedValue = data;
|
||||||
_privacySavedValue = checked;
|
|
||||||
_usernameSavedValue = publicLink;
|
|
||||||
_noForwardsSavedValue = noForwards;
|
|
||||||
refreshHistoryVisibility();
|
refreshHistoryVisibility();
|
||||||
});
|
});
|
||||||
|
_typeDataSavedValue->hasLinkedChat
|
||||||
|
= (_linkedChatSavedValue.value_or(nullptr) != nullptr);
|
||||||
_navigation->parentController()->show(
|
_navigation->parentController()->show(
|
||||||
Box<EditPeerTypeBox>(
|
Box<EditPeerTypeBox>(
|
||||||
_peer,
|
_peer,
|
||||||
_channelHasLocationOriginalValue,
|
_channelHasLocationOriginalValue,
|
||||||
boxCallback,
|
boxCallback,
|
||||||
_privacySavedValue,
|
_typeDataSavedValue,
|
||||||
_usernameSavedValue,
|
|
||||||
_noForwardsSavedValue,
|
|
||||||
error),
|
error),
|
||||||
Ui::LayerOption::KeepOther);
|
Ui::LayerOption::KeepOther);
|
||||||
}
|
}
|
||||||
|
@ -698,12 +701,20 @@ void Controller::fillPrivacyTypeButton() {
|
||||||
// Create Privacy Button.
|
// Create Privacy Button.
|
||||||
const auto hasLocation = _peer->isChannel()
|
const auto hasLocation = _peer->isChannel()
|
||||||
&& _peer->asChannel()->hasLocation();
|
&& _peer->asChannel()->hasLocation();
|
||||||
_privacySavedValue = (_peer->isChannel()
|
_typeDataSavedValue = EditPeerTypeData{
|
||||||
&& _peer->asChannel()->hasUsername())
|
.privacy = ((_peer->isChannel()
|
||||||
? Privacy::HasUsername
|
&& _peer->asChannel()->hasUsername())
|
||||||
: Privacy::NoUsername;
|
? Privacy::HasUsername
|
||||||
_noForwardsSavedValue = !_peer->allowsForwarding();
|
: Privacy::NoUsername),
|
||||||
|
.username = (_peer->isChannel()
|
||||||
|
? _peer->asChannel()->username
|
||||||
|
: QString()),
|
||||||
|
.noForwards = !_peer->allowsForwarding(),
|
||||||
|
.joinToWrite = (_peer->isMegagroup()
|
||||||
|
&& _peer->asChannel()->joinToWrite()),
|
||||||
|
.requestToJoin = (_peer->isMegagroup()
|
||||||
|
&& _peer->asChannel()->requestToJoin()),
|
||||||
|
};
|
||||||
const auto isGroup = (_peer->isChat() || _peer->isMegagroup());
|
const auto isGroup = (_peer->isChat() || _peer->isMegagroup());
|
||||||
const auto icon = isGroup
|
const auto icon = isGroup
|
||||||
? &st::settingsIconGroup
|
? &st::settingsIconGroup
|
||||||
|
@ -732,7 +743,7 @@ void Controller::fillPrivacyTypeButton() {
|
||||||
[=] { showEditPeerTypeBox(); },
|
[=] { showEditPeerTypeBox(); },
|
||||||
{ icon, Settings::kIconLightBlue });
|
{ icon, Settings::kIconLightBlue });
|
||||||
|
|
||||||
_privacyTypeUpdates.fire_copy(*_privacySavedValue);
|
_privacyTypeUpdates.fire_copy(_typeDataSavedValue->privacy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::fillLinkedChatButton() {
|
void Controller::fillLinkedChatButton() {
|
||||||
|
@ -1060,9 +1071,9 @@ void Controller::fillManageSection() {
|
||||||
},
|
},
|
||||||
{ &st::infoRoundedIconInviteLinks, Settings::kIconLightOrange });
|
{ &st::infoRoundedIconInviteLinks, Settings::kIconLightOrange });
|
||||||
|
|
||||||
if (_privacySavedValue) {
|
if (_typeDataSavedValue) {
|
||||||
_privacyTypeUpdates.events_starting_with_copy(
|
_privacyTypeUpdates.events_starting_with_copy(
|
||||||
*_privacySavedValue
|
_typeDataSavedValue->privacy
|
||||||
) | rpl::start_with_next([=](Privacy flag) {
|
) | rpl::start_with_next([=](Privacy flag) {
|
||||||
wrap->toggle(
|
wrap->toggle(
|
||||||
flag != Privacy::HasUsername,
|
flag != Privacy::HasUsername,
|
||||||
|
@ -1217,24 +1228,22 @@ std::optional<Controller::Saving> Controller::validate() const {
|
||||||
&& validateDescription(result)
|
&& validateDescription(result)
|
||||||
&& validateHistoryVisibility(result)
|
&& validateHistoryVisibility(result)
|
||||||
&& validateSignatures(result)
|
&& validateSignatures(result)
|
||||||
&& validateForwards(result)) {
|
&& validateForwards(result)
|
||||||
|
&& validateJoinToWrite(result)
|
||||||
|
&& validateRequestToJoin(result)) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Controller::validateUsername(Saving &to) const {
|
bool Controller::validateUsername(Saving &to) const {
|
||||||
if (!_privacySavedValue) {
|
if (!_typeDataSavedValue) {
|
||||||
return true;
|
return true;
|
||||||
} else if (_privacySavedValue != Privacy::HasUsername) {
|
} else if (_typeDataSavedValue->privacy != Privacy::HasUsername) {
|
||||||
to.username = QString();
|
to.username = QString();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const auto username = _usernameSavedValue.value_or(
|
const auto username = _typeDataSavedValue->username;
|
||||||
_peer->isChannel()
|
|
||||||
? _peer->asChannel()->username
|
|
||||||
: QString()
|
|
||||||
);
|
|
||||||
if (username.isEmpty()) {
|
if (username.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1276,7 +1285,8 @@ bool Controller::validateHistoryVisibility(Saving &to) const {
|
||||||
if (!_controls.historyVisibilityWrap
|
if (!_controls.historyVisibilityWrap
|
||||||
|| !_controls.historyVisibilityWrap->toggled()
|
|| !_controls.historyVisibilityWrap->toggled()
|
||||||
|| _channelHasLocationOriginalValue
|
|| _channelHasLocationOriginalValue
|
||||||
|| (_privacySavedValue == Privacy::HasUsername)) {
|
|| (_typeDataSavedValue
|
||||||
|
&& _typeDataSavedValue->privacy == Privacy::HasUsername)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
to.hiddenPreHistory
|
to.hiddenPreHistory
|
||||||
|
@ -1293,10 +1303,26 @@ bool Controller::validateSignatures(Saving &to) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Controller::validateForwards(Saving &to) const {
|
bool Controller::validateForwards(Saving &to) const {
|
||||||
if (!_noForwardsSavedValue.has_value()) {
|
if (!_typeDataSavedValue) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
to.noForwards = _noForwardsSavedValue;
|
to.noForwards = _typeDataSavedValue->noForwards;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::validateJoinToWrite(Saving &to) const {
|
||||||
|
if (!_typeDataSavedValue) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
to.joinToWrite = _typeDataSavedValue->joinToWrite;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::validateRequestToJoin(Saving &to) const {
|
||||||
|
if (!_typeDataSavedValue) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
to.requestToJoin = _typeDataSavedValue->requestToJoin;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1315,6 +1341,8 @@ void Controller::save() {
|
||||||
pushSaveStage([=] { saveHistoryVisibility(); });
|
pushSaveStage([=] { saveHistoryVisibility(); });
|
||||||
pushSaveStage([=] { saveSignatures(); });
|
pushSaveStage([=] { saveSignatures(); });
|
||||||
pushSaveStage([=] { saveForwards(); });
|
pushSaveStage([=] { saveForwards(); });
|
||||||
|
pushSaveStage([=] { saveJoinToWrite(); });
|
||||||
|
pushSaveStage([=] { saveRequestToJoin(); });
|
||||||
pushSaveStage([=] { savePhoto(); });
|
pushSaveStage([=] { savePhoto(); });
|
||||||
continueSave();
|
continueSave();
|
||||||
}
|
}
|
||||||
|
@ -1591,6 +1619,50 @@ void Controller::saveForwards() {
|
||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Controller::saveJoinToWrite() {
|
||||||
|
const auto joinToWrite = _peer->isMegagroup()
|
||||||
|
&& _peer->asChannel()->joinToWrite();
|
||||||
|
if (!_savingData.joinToWrite
|
||||||
|
|| *_savingData.joinToWrite == joinToWrite) {
|
||||||
|
return continueSave();
|
||||||
|
}
|
||||||
|
_api.request(MTPchannels_ToggleJoinToSend(
|
||||||
|
_peer->asChannel()->inputChannel,
|
||||||
|
MTP_bool(*_savingData.joinToWrite)
|
||||||
|
)).done([=](const MTPUpdates &result) {
|
||||||
|
_peer->session().api().applyUpdates(result);
|
||||||
|
continueSave();
|
||||||
|
}).fail([=](const MTP::Error &error) {
|
||||||
|
if (error.type() == qstr("CHAT_NOT_MODIFIED")) {
|
||||||
|
continueSave();
|
||||||
|
} else {
|
||||||
|
cancelSave();
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::saveRequestToJoin() {
|
||||||
|
const auto requestToJoin = _peer->isMegagroup()
|
||||||
|
&& _peer->asChannel()->requestToJoin();
|
||||||
|
if (!_savingData.requestToJoin
|
||||||
|
|| *_savingData.requestToJoin == requestToJoin) {
|
||||||
|
return continueSave();
|
||||||
|
}
|
||||||
|
_api.request(MTPchannels_ToggleJoinRequest(
|
||||||
|
_peer->asChannel()->inputChannel,
|
||||||
|
MTP_bool(*_savingData.requestToJoin)
|
||||||
|
)).done([=](const MTPUpdates &result) {
|
||||||
|
_peer->session().api().applyUpdates(result);
|
||||||
|
continueSave();
|
||||||
|
}).fail([=](const MTP::Error &error) {
|
||||||
|
if (error.type() == qstr("CHAT_NOT_MODIFIED")) {
|
||||||
|
continueSave();
|
||||||
|
} else {
|
||||||
|
cancelSave();
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
void Controller::savePhoto() {
|
void Controller::savePhoto() {
|
||||||
auto image = _controls.photo
|
auto image = _controls.photo
|
||||||
? _controls.photo->takeResultImage()
|
? _controls.photo->takeResultImage()
|
||||||
|
|
|
@ -52,16 +52,14 @@ public:
|
||||||
not_null<Ui::VerticalLayout*> container,
|
not_null<Ui::VerticalLayout*> container,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
bool useLocationPhrases,
|
bool useLocationPhrases,
|
||||||
std::optional<Privacy> privacySavedValue,
|
std::optional<EditPeerTypeData> dataSavedValue);
|
||||||
std::optional<QString> usernameSavedValue,
|
|
||||||
std::optional<bool> noForwardsSavedValue);
|
|
||||||
|
|
||||||
void createContent();
|
void createContent();
|
||||||
[[nodiscard]] QString getUsernameInput() const;
|
[[nodiscard]] QString getUsernameInput() const;
|
||||||
void setFocusUsername();
|
void setFocusUsername();
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<QString> getTitle() const {
|
[[nodiscard]] rpl::producer<QString> getTitle() const {
|
||||||
return !_privacySavedValue
|
return !_dataSavedValue
|
||||||
? tr::lng_create_invite_link_title()
|
? tr::lng_create_invite_link_title()
|
||||||
: _isGroup
|
: _isGroup
|
||||||
? tr::lng_manage_peer_group_type()
|
? tr::lng_manage_peer_group_type()
|
||||||
|
@ -79,6 +77,12 @@ public:
|
||||||
[[nodiscard]] bool noForwards() const {
|
[[nodiscard]] bool noForwards() const {
|
||||||
return _controls.noForwards->toggled();
|
return _controls.noForwards->toggled();
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] bool joinToWrite() const {
|
||||||
|
return _controls.joinToWrite && _controls.joinToWrite->toggled();
|
||||||
|
}
|
||||||
|
[[nodiscard]] bool requestToJoin() const {
|
||||||
|
return _controls.requestToJoin && _controls.requestToJoin->toggled();
|
||||||
|
}
|
||||||
|
|
||||||
void showError(rpl::producer<QString> text) {
|
void showError(rpl::producer<QString> text) {
|
||||||
_controls.usernameInput->showError();
|
_controls.usernameInput->showError();
|
||||||
|
@ -93,10 +97,13 @@ private:
|
||||||
base::unique_qptr<Ui::FlatLabel> usernameResult;
|
base::unique_qptr<Ui::FlatLabel> usernameResult;
|
||||||
const style::FlatLabel *usernameResultStyle = nullptr;
|
const style::FlatLabel *usernameResultStyle = nullptr;
|
||||||
|
|
||||||
Ui::SlideWrap<Ui::RpWidget> *inviteLinkWrap = nullptr;
|
Ui::SlideWrap<> *inviteLinkWrap = nullptr;
|
||||||
Ui::FlatLabel *inviteLink = nullptr;
|
Ui::FlatLabel *inviteLink = nullptr;
|
||||||
|
|
||||||
|
Ui::SlideWrap<Ui::VerticalLayout> *whoSendWrap = nullptr;
|
||||||
Ui::SettingsButton *noForwards = nullptr;
|
Ui::SettingsButton *noForwards = nullptr;
|
||||||
|
Ui::SettingsButton *joinToWrite = nullptr;
|
||||||
|
Ui::SettingsButton *requestToJoin = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
Controls _controls;
|
Controls _controls;
|
||||||
|
@ -130,9 +137,7 @@ private:
|
||||||
bool _linkOnly = false;
|
bool _linkOnly = false;
|
||||||
|
|
||||||
MTP::Sender _api;
|
MTP::Sender _api;
|
||||||
std::optional<Privacy> _privacySavedValue;
|
std::optional<EditPeerTypeData> _dataSavedValue;
|
||||||
std::optional<QString> _usernameSavedValue;
|
|
||||||
std::optional<bool> _noForwardsSavedValue;
|
|
||||||
|
|
||||||
bool _useLocationPhrases = false;
|
bool _useLocationPhrases = false;
|
||||||
bool _isGroup = false;
|
bool _isGroup = false;
|
||||||
|
@ -153,20 +158,17 @@ Controller::Controller(
|
||||||
not_null<Ui::VerticalLayout*> container,
|
not_null<Ui::VerticalLayout*> container,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
bool useLocationPhrases,
|
bool useLocationPhrases,
|
||||||
std::optional<Privacy> privacySavedValue,
|
std::optional<EditPeerTypeData> dataSavedValue)
|
||||||
std::optional<QString> usernameSavedValue,
|
|
||||||
std::optional<bool> noForwardsSavedValue)
|
|
||||||
: _show(show)
|
: _show(show)
|
||||||
, _peer(peer)
|
, _peer(peer)
|
||||||
, _linkOnly(!privacySavedValue.has_value())
|
, _linkOnly(!dataSavedValue.has_value())
|
||||||
, _api(&_peer->session().mtp())
|
, _api(&_peer->session().mtp())
|
||||||
, _privacySavedValue(privacySavedValue)
|
, _dataSavedValue(dataSavedValue)
|
||||||
, _usernameSavedValue(usernameSavedValue)
|
|
||||||
, _noForwardsSavedValue(noForwardsSavedValue)
|
|
||||||
, _useLocationPhrases(useLocationPhrases)
|
, _useLocationPhrases(useLocationPhrases)
|
||||||
, _isGroup(_peer->isChat() || _peer->isMegagroup())
|
, _isGroup(_peer->isChat() || _peer->isMegagroup())
|
||||||
, _goodUsername(!_usernameSavedValue.value_or(
|
, _goodUsername(_dataSavedValue
|
||||||
_peer->isChannel() ? _peer->asChannel()->username : QString()).isEmpty())
|
? !_dataSavedValue->username.isEmpty()
|
||||||
|
: (_peer->isChannel() && !_peer->asChannel()->username.isEmpty()))
|
||||||
, _wrap(container)
|
, _wrap(container)
|
||||||
, _checkUsernameTimer([=] { checkUsernameAvailability(); }) {
|
, _checkUsernameTimer([=] { checkUsernameAvailability(); }) {
|
||||||
_peer->updateFull();
|
_peer->updateFull();
|
||||||
|
@ -175,7 +177,12 @@ Controller::Controller(
|
||||||
void Controller::createContent() {
|
void Controller::createContent() {
|
||||||
_controls = Controls();
|
_controls = Controls();
|
||||||
|
|
||||||
fillPrivaciesButtons(_wrap, _privacySavedValue);
|
fillPrivaciesButtons(
|
||||||
|
_wrap,
|
||||||
|
(_dataSavedValue
|
||||||
|
? _dataSavedValue->privacy
|
||||||
|
: std::optional<Privacy>()));
|
||||||
|
|
||||||
// Skip.
|
// Skip.
|
||||||
if (!_linkOnly) {
|
if (!_linkOnly) {
|
||||||
_wrap->add(object_ptr<Ui::BoxContentDivider>(_wrap));
|
_wrap->add(object_ptr<Ui::BoxContentDivider>(_wrap));
|
||||||
|
@ -204,6 +211,63 @@ void Controller::createContent() {
|
||||||
AddDividerText(_wrap.get(), tr::lng_group_invite_manage_about());
|
AddDividerText(_wrap.get(), tr::lng_group_invite_manage_about());
|
||||||
|
|
||||||
if (!_linkOnly) {
|
if (!_linkOnly) {
|
||||||
|
if (_peer->isMegagroup()) {
|
||||||
|
_controls.whoSendWrap = _wrap->add(
|
||||||
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
|
_wrap.get(),
|
||||||
|
object_ptr<Ui::VerticalLayout>(_wrap.get())));
|
||||||
|
const auto wrap = _controls.whoSendWrap->entity();
|
||||||
|
|
||||||
|
AddSkip(wrap);
|
||||||
|
if (_dataSavedValue->hasLinkedChat) {
|
||||||
|
AddSubsectionTitle(wrap, tr::lng_manage_peer_send_title());
|
||||||
|
|
||||||
|
_controls.joinToWrite = wrap->add(EditPeerInfoBox::CreateButton(
|
||||||
|
wrap,
|
||||||
|
tr::lng_manage_peer_send_only_members(),
|
||||||
|
rpl::single(QString()),
|
||||||
|
[=] {},
|
||||||
|
st::manageGroupTopButtonWithText,
|
||||||
|
{}
|
||||||
|
));
|
||||||
|
_controls.joinToWrite->toggleOn(
|
||||||
|
rpl::single(_dataSavedValue->joinToWrite)
|
||||||
|
)->toggledValue(
|
||||||
|
) | rpl::start_with_next([=](bool toggled) {
|
||||||
|
_dataSavedValue->joinToWrite = toggled;
|
||||||
|
}, wrap->lifetime());
|
||||||
|
}
|
||||||
|
auto joinToWrite = _controls.joinToWrite
|
||||||
|
? _controls.joinToWrite->toggledValue()
|
||||||
|
: rpl::single(true);
|
||||||
|
|
||||||
|
const auto requestToJoinWrap = wrap->add(
|
||||||
|
object_ptr<Ui::SlideWrap<Ui::SettingsButton>>(
|
||||||
|
wrap,
|
||||||
|
EditPeerInfoBox::CreateButton(
|
||||||
|
wrap,
|
||||||
|
tr::lng_manage_peer_send_approve_members(),
|
||||||
|
rpl::single(QString()),
|
||||||
|
[=] {},
|
||||||
|
st::manageGroupTopButtonWithText,
|
||||||
|
{})))->setDuration(0);
|
||||||
|
requestToJoinWrap->toggleOn(rpl::duplicate(joinToWrite));
|
||||||
|
_controls.requestToJoin = requestToJoinWrap->entity();
|
||||||
|
_controls.requestToJoin->toggleOn(
|
||||||
|
rpl::single(_dataSavedValue->requestToJoin)
|
||||||
|
)->toggledValue(
|
||||||
|
) | rpl::start_with_next([=](bool toggled) {
|
||||||
|
_dataSavedValue->requestToJoin = toggled;
|
||||||
|
}, wrap->lifetime());
|
||||||
|
|
||||||
|
AddSkip(wrap);
|
||||||
|
AddDividerText(
|
||||||
|
wrap,
|
||||||
|
rpl::conditional(
|
||||||
|
std::move(joinToWrite),
|
||||||
|
tr::lng_manage_peer_send_approve_members_about(),
|
||||||
|
tr::lng_manage_peer_send_only_members_about()));
|
||||||
|
}
|
||||||
AddSkip(_wrap.get());
|
AddSkip(_wrap.get());
|
||||||
AddSubsectionTitle(
|
AddSubsectionTitle(
|
||||||
_wrap.get(),
|
_wrap.get(),
|
||||||
|
@ -216,10 +280,10 @@ void Controller::createContent() {
|
||||||
st::peerPermissionsButton,
|
st::peerPermissionsButton,
|
||||||
{}));
|
{}));
|
||||||
_controls.noForwards->toggleOn(
|
_controls.noForwards->toggleOn(
|
||||||
rpl::single(_noForwardsSavedValue.value_or(false))
|
rpl::single(_dataSavedValue->noForwards)
|
||||||
)->toggledValue(
|
)->toggledValue(
|
||||||
) | rpl::start_with_next([=](bool toggled) {
|
) | rpl::start_with_next([=](bool toggled) {
|
||||||
_noForwardsSavedValue = toggled;
|
_dataSavedValue->noForwards = toggled;
|
||||||
}, _wrap->lifetime());
|
}, _wrap->lifetime());
|
||||||
AddSkip(_wrap.get());
|
AddSkip(_wrap.get());
|
||||||
AddDividerText(
|
AddDividerText(
|
||||||
|
@ -234,8 +298,9 @@ void Controller::createContent() {
|
||||||
if (_controls.privacy->value() == Privacy::NoUsername) {
|
if (_controls.privacy->value() == Privacy::NoUsername) {
|
||||||
checkUsernameAvailability();
|
checkUsernameAvailability();
|
||||||
}
|
}
|
||||||
const auto forShowing = _privacySavedValue.value_or(
|
const auto forShowing = _dataSavedValue
|
||||||
Privacy::NoUsername);
|
? _dataSavedValue->privacy
|
||||||
|
: Privacy::NoUsername;
|
||||||
_controls.inviteLinkWrap->toggle(
|
_controls.inviteLinkWrap->toggle(
|
||||||
(forShowing != Privacy::HasUsername),
|
(forShowing != Privacy::HasUsername),
|
||||||
anim::type::instant);
|
anim::type::instant);
|
||||||
|
@ -332,8 +397,9 @@ object_ptr<Ui::RpWidget> Controller::createUsernameEdit() {
|
||||||
Expects(_wrap != nullptr);
|
Expects(_wrap != nullptr);
|
||||||
|
|
||||||
const auto channel = _peer->asChannel();
|
const auto channel = _peer->asChannel();
|
||||||
const auto username = _usernameSavedValue.value_or(
|
const auto username = (!_dataSavedValue || !channel)
|
||||||
channel ? channel->username : QString());
|
? QString()
|
||||||
|
: channel->username;
|
||||||
|
|
||||||
auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
_wrap,
|
_wrap,
|
||||||
|
@ -401,6 +467,15 @@ void Controller::privacyChanged(Privacy value) {
|
||||||
(value == Privacy::HasUsername),
|
(value == Privacy::HasUsername),
|
||||||
anim::type::instant);
|
anim::type::instant);
|
||||||
};
|
};
|
||||||
|
const auto toggleWhoSendWrap = [&] {
|
||||||
|
if (!_controls.whoSendWrap) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_controls.whoSendWrap->toggle(
|
||||||
|
(value == Privacy::HasUsername
|
||||||
|
|| (_dataSavedValue && _dataSavedValue->hasLinkedChat)),
|
||||||
|
anim::type::instant);
|
||||||
|
};
|
||||||
const auto refreshVisibilities = [&] {
|
const auto refreshVisibilities = [&] {
|
||||||
// Now first we need to hide that was shown.
|
// Now first we need to hide that was shown.
|
||||||
// Otherwise box will change own Y position.
|
// Otherwise box will change own Y position.
|
||||||
|
@ -408,10 +483,12 @@ void Controller::privacyChanged(Privacy value) {
|
||||||
if (value == Privacy::HasUsername) {
|
if (value == Privacy::HasUsername) {
|
||||||
toggleInviteLink();
|
toggleInviteLink();
|
||||||
toggleEditUsername();
|
toggleEditUsername();
|
||||||
|
toggleWhoSendWrap();
|
||||||
|
|
||||||
_controls.usernameResult = nullptr;
|
_controls.usernameResult = nullptr;
|
||||||
checkUsernameAvailability();
|
checkUsernameAvailability();
|
||||||
} else {
|
} else {
|
||||||
|
toggleWhoSendWrap();
|
||||||
toggleEditUsername();
|
toggleEditUsername();
|
||||||
toggleInviteLink();
|
toggleInviteLink();
|
||||||
}
|
}
|
||||||
|
@ -572,7 +649,7 @@ object_ptr<Ui::RpWidget> Controller::createInviteLinkBlock() {
|
||||||
const auto container = result->entity();
|
const auto container = result->entity();
|
||||||
|
|
||||||
using namespace Settings;
|
using namespace Settings;
|
||||||
if (_privacySavedValue) {
|
if (_dataSavedValue) {
|
||||||
AddSkip(container);
|
AddSkip(container);
|
||||||
|
|
||||||
AddSubsectionTitle(container, tr::lng_create_permanent_link_title());
|
AddSubsectionTitle(container, tr::lng_create_permanent_link_title());
|
||||||
|
@ -601,24 +678,20 @@ EditPeerTypeBox::EditPeerTypeBox(
|
||||||
QWidget*,
|
QWidget*,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
bool useLocationPhrases,
|
bool useLocationPhrases,
|
||||||
std::optional<FnMut<void(Privacy, QString, bool)>> savedCallback,
|
std::optional<FnMut<void(EditPeerTypeData)>> savedCallback,
|
||||||
std::optional<Privacy> privacySaved,
|
std::optional<EditPeerTypeData> dataSaved,
|
||||||
std::optional<QString> usernameSaved,
|
|
||||||
std::optional<bool> noForwardsValue,
|
|
||||||
std::optional<rpl::producer<QString>> usernameError)
|
std::optional<rpl::producer<QString>> usernameError)
|
||||||
: _peer(peer)
|
: _peer(peer)
|
||||||
, _useLocationPhrases(useLocationPhrases)
|
, _useLocationPhrases(useLocationPhrases)
|
||||||
, _savedCallback(std::move(savedCallback))
|
, _savedCallback(std::move(savedCallback))
|
||||||
, _privacySavedValue(privacySaved)
|
, _dataSavedValue(dataSaved)
|
||||||
, _usernameSavedValue(usernameSaved)
|
|
||||||
, _noForwardsValue(noForwardsValue)
|
|
||||||
, _usernameError(usernameError) {
|
, _usernameError(usernameError) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EditPeerTypeBox::EditPeerTypeBox(
|
EditPeerTypeBox::EditPeerTypeBox(
|
||||||
QWidget*,
|
QWidget*,
|
||||||
not_null<PeerData*> peer)
|
not_null<PeerData*> peer)
|
||||||
: EditPeerTypeBox(nullptr, peer, {}, {}, {}, {}, {}, {}) {
|
: EditPeerTypeBox(nullptr, peer, {}, {}, {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditPeerTypeBox::setInnerFocus() {
|
void EditPeerTypeBox::setInnerFocus() {
|
||||||
|
@ -636,9 +709,7 @@ void EditPeerTypeBox::prepare() {
|
||||||
content.data(),
|
content.data(),
|
||||||
_peer,
|
_peer,
|
||||||
_useLocationPhrases,
|
_useLocationPhrases,
|
||||||
_privacySavedValue,
|
_dataSavedValue);
|
||||||
_usernameSavedValue,
|
|
||||||
_noForwardsValue);
|
|
||||||
_focusRequests.events(
|
_focusRequests.events(
|
||||||
) | rpl::start_with_next(
|
) | rpl::start_with_next(
|
||||||
[=] {
|
[=] {
|
||||||
|
@ -662,12 +733,15 @@ void EditPeerTypeBox::prepare() {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto local = std::move(*_savedCallback);
|
auto local = std::move(*_savedCallback);
|
||||||
local(
|
local(EditPeerTypeData{
|
||||||
v,
|
.privacy = v,
|
||||||
(v == Privacy::HasUsername
|
.username = (v == Privacy::HasUsername
|
||||||
? controller->getUsernameInput()
|
? controller->getUsernameInput()
|
||||||
: QString()),
|
: QString()),
|
||||||
controller->noForwards()); // We don't need username with private type.
|
.noForwards = controller->noForwards(),
|
||||||
|
.joinToWrite = controller->joinToWrite(),
|
||||||
|
.requestToJoin = controller->requestToJoin(),
|
||||||
|
}); // We don't need username with private type.
|
||||||
closeBox();
|
closeBox();
|
||||||
});
|
});
|
||||||
addButton(tr::lng_cancel(), [=] { closeBox(); });
|
addButton(tr::lng_cancel(), [=] { closeBox(); });
|
||||||
|
|
|
@ -29,16 +29,23 @@ enum class UsernameState {
|
||||||
NotAvailable,
|
NotAvailable,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct EditPeerTypeData {
|
||||||
|
Privacy privacy = Privacy::NoUsername;
|
||||||
|
QString username;
|
||||||
|
bool hasLinkedChat = false;
|
||||||
|
bool noForwards = false;
|
||||||
|
bool joinToWrite = false;
|
||||||
|
bool requestToJoin = false;
|
||||||
|
};
|
||||||
|
|
||||||
class EditPeerTypeBox : public Ui::BoxContent {
|
class EditPeerTypeBox : public Ui::BoxContent {
|
||||||
public:
|
public:
|
||||||
EditPeerTypeBox(
|
EditPeerTypeBox(
|
||||||
QWidget*,
|
QWidget*,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
bool useLocationPhrases,
|
bool useLocationPhrases,
|
||||||
std::optional<FnMut<void(Privacy, QString, bool)>> savedCallback,
|
std::optional<FnMut<void(EditPeerTypeData)>> savedCallback,
|
||||||
std::optional<Privacy> privacySaved,
|
std::optional<EditPeerTypeData> dataSaved,
|
||||||
std::optional<QString> usernameSaved,
|
|
||||||
std::optional<bool> noForwardsSaved,
|
|
||||||
std::optional<rpl::producer<QString>> usernameError = {});
|
std::optional<rpl::producer<QString>> usernameError = {});
|
||||||
|
|
||||||
// For invite link only.
|
// For invite link only.
|
||||||
|
@ -53,11 +60,9 @@ protected:
|
||||||
private:
|
private:
|
||||||
not_null<PeerData*> _peer;
|
not_null<PeerData*> _peer;
|
||||||
bool _useLocationPhrases = false;
|
bool _useLocationPhrases = false;
|
||||||
std::optional<FnMut<void(Privacy, QString, bool)>> _savedCallback;
|
std::optional<FnMut<void(EditPeerTypeData)>> _savedCallback;
|
||||||
|
|
||||||
std::optional<Privacy> _privacySavedValue;
|
std::optional<EditPeerTypeData> _dataSavedValue;
|
||||||
std::optional<QString> _usernameSavedValue;
|
|
||||||
std::optional<bool> _noForwardsValue;
|
|
||||||
std::optional<rpl::producer<QString>> _usernameError;
|
std::optional<rpl::producer<QString>> _usernameError;
|
||||||
|
|
||||||
rpl::event_stream<> _focusRequests;
|
rpl::event_stream<> _focusRequests;
|
||||||
|
|
|
@ -52,6 +52,8 @@ enum class ChannelDataFlag {
|
||||||
HasLink = (1 << 18),
|
HasLink = (1 << 18),
|
||||||
SlowmodeEnabled = (1 << 19),
|
SlowmodeEnabled = (1 << 19),
|
||||||
NoForwards = (1 << 20),
|
NoForwards = (1 << 20),
|
||||||
|
JoinToWrite = (1 << 21),
|
||||||
|
RequestToJoin = (1 << 22),
|
||||||
};
|
};
|
||||||
inline constexpr bool is_flag_type(ChannelDataFlag) { return true; };
|
inline constexpr bool is_flag_type(ChannelDataFlag) { return true; };
|
||||||
using ChannelDataFlags = base::flags<ChannelDataFlag>;
|
using ChannelDataFlags = base::flags<ChannelDataFlag>;
|
||||||
|
@ -255,6 +257,12 @@ public:
|
||||||
[[nodiscard]] bool amCreator() const {
|
[[nodiscard]] bool amCreator() const {
|
||||||
return flags() & Flag::Creator;
|
return flags() & Flag::Creator;
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] bool joinToWrite() const {
|
||||||
|
return flags() & Flag::JoinToWrite;
|
||||||
|
}
|
||||||
|
[[nodiscard]] bool requestToJoin() const {
|
||||||
|
return flags() & Flag::RequestToJoin;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] auto adminRights() const {
|
[[nodiscard]] auto adminRights() const {
|
||||||
return _adminRights.current();
|
return _adminRights.current();
|
||||||
|
|
|
@ -741,7 +741,9 @@ not_null<PeerData*> Session::processChat(const MTPChat &data) {
|
||||||
| Flag::CallNotEmpty
|
| Flag::CallNotEmpty
|
||||||
| Flag::Forbidden
|
| Flag::Forbidden
|
||||||
| (!minimal ? (Flag::Left | Flag::Creator) : Flag())
|
| (!minimal ? (Flag::Left | Flag::Creator) : Flag())
|
||||||
| Flag::NoForwards;
|
| Flag::NoForwards
|
||||||
|
| Flag::JoinToWrite
|
||||||
|
| Flag::RequestToJoin;
|
||||||
const auto flagsSet = (data.is_broadcast() ? Flag::Broadcast : Flag())
|
const auto flagsSet = (data.is_broadcast() ? Flag::Broadcast : Flag())
|
||||||
| (data.is_verified() ? Flag::Verified : Flag())
|
| (data.is_verified() ? Flag::Verified : Flag())
|
||||||
| (data.is_scam() ? Flag::Scam : Flag())
|
| (data.is_scam() ? Flag::Scam : Flag())
|
||||||
|
@ -762,7 +764,9 @@ not_null<PeerData*> Session::processChat(const MTPChat &data) {
|
||||||
? (data.is_left() ? Flag::Left : Flag())
|
? (data.is_left() ? Flag::Left : Flag())
|
||||||
| (data.is_creator() ? Flag::Creator : Flag())
|
| (data.is_creator() ? Flag::Creator : Flag())
|
||||||
: Flag())
|
: Flag())
|
||||||
| (data.is_noforwards() ? Flag::NoForwards : Flag());
|
| (data.is_noforwards() ? Flag::NoForwards : Flag())
|
||||||
|
| (data.is_join_to_send() ? Flag::JoinToWrite : Flag())
|
||||||
|
| (data.is_join_request() ? Flag::RequestToJoin : Flag());
|
||||||
channel->setFlags((channel->flags() & ~flagsMask) | flagsSet);
|
channel->setFlags((channel->flags() & ~flagsMask) | flagsSet);
|
||||||
|
|
||||||
channel->setName(
|
channel->setName(
|
||||||
|
|
|
@ -913,6 +913,16 @@ Dialogs::EntryState HistoryWidget::computeDialogsEntryState() const {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::refreshJoinChannelText() {
|
||||||
|
if (const auto channel = _peer ? _peer->asChannel() : nullptr) {
|
||||||
|
_joinChannel->setText((channel->isBroadcast()
|
||||||
|
? tr::lng_profile_join_channel(tr::now)
|
||||||
|
: (channel->requestToJoin() && !channel->amCreator())
|
||||||
|
? tr::lng_profile_apply_to_join_group(tr::now)
|
||||||
|
: tr::lng_profile_join_group(tr::now)).toUpper());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::refreshTopBarActiveChat() {
|
void HistoryWidget::refreshTopBarActiveChat() {
|
||||||
const auto state = computeDialogsEntryState();
|
const auto state = computeDialogsEntryState();
|
||||||
_topBar->setActiveChat(state, _history->sendActionPainter());
|
_topBar->setActiveChat(state, _history->sendActionPainter());
|
||||||
|
@ -2210,12 +2220,6 @@ void HistoryWidget::showHistory(
|
||||||
&& !_peer->asUser()->isSupport())
|
&& !_peer->asUser()->isSupport())
|
||||||
? tr::lng_restart_button(tr::now)
|
? tr::lng_restart_button(tr::now)
|
||||||
: tr::lng_unblock_button(tr::now)).toUpper());
|
: tr::lng_unblock_button(tr::now)).toUpper());
|
||||||
if (const auto channel = _peer->asChannel()) {
|
|
||||||
channel->updateFull();
|
|
||||||
_joinChannel->setText((channel->isMegagroup()
|
|
||||||
? tr::lng_profile_join_group(tr::now)
|
|
||||||
: tr::lng_profile_join_channel(tr::now)).toUpper());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_nonEmptySelection = false;
|
_nonEmptySelection = false;
|
||||||
|
@ -2269,6 +2273,18 @@ void HistoryWidget::showHistory(
|
||||||
object_ptr<HistoryInner>(this, _scroll, controller(), _history));
|
object_ptr<HistoryInner>(this, _scroll, controller(), _history));
|
||||||
_list->show();
|
_list->show();
|
||||||
|
|
||||||
|
if (const auto channel = _peer->asChannel()) {
|
||||||
|
channel->updateFull();
|
||||||
|
if (!channel->isBroadcast()) {
|
||||||
|
channel->flagsValue(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
refreshJoinChannelText();
|
||||||
|
}, _list->lifetime());
|
||||||
|
} else {
|
||||||
|
refreshJoinChannelText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
controller()->adaptive().changes(
|
controller()->adaptive().changes(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
_history->forceFullResize();
|
_history->forceFullResize();
|
||||||
|
|
|
@ -375,6 +375,7 @@ private:
|
||||||
[[nodiscard]] Dialogs::EntryState computeDialogsEntryState() const;
|
[[nodiscard]] Dialogs::EntryState computeDialogsEntryState() const;
|
||||||
void refreshTopBarActiveChat();
|
void refreshTopBarActiveChat();
|
||||||
|
|
||||||
|
void refreshJoinChannelText();
|
||||||
void requestMessageData(MsgId msgId);
|
void requestMessageData(MsgId msgId);
|
||||||
void messageDataReceived(not_null<PeerData*> peer, MsgId msgId);
|
void messageDataReceived(not_null<PeerData*> peer, MsgId msgId);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue