2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-31 06:35:14 +00:00

Handle located groups as public.

This commit is contained in:
John Preston
2019-06-21 14:27:46 +02:00
parent 6537e524b8
commit 7d585ab72f
37 changed files with 468 additions and 275 deletions

View File

@@ -537,6 +537,8 @@ void EditAdminBox::sendTransferRequestFrom(
const auto problem = [&] {
if (type == qstr("CHANNELS_ADMIN_PUBLIC_TOO_MUCH")) {
return tr::lng_channels_too_much_public_other(tr::now);
} else if (type == qstr("CHANNELS_ADMIN_LOCATED_TOO_MUCH")) {
return tr::lng_channels_too_much_located_other(tr::now);
} else if (type == qstr("ADMINS_TOO_MUCH")) {
return (channel->isBroadcast()
? tr::lng_error_admin_limit_channel

View File

@@ -240,6 +240,7 @@ private:
std::optional<Privacy> _privacySavedValue;
std::optional<ChannelData*> _linkedChatSavedValue;
ChannelData *_linkedChatOriginalValue = nullptr;
bool _channelHasLocationOriginalValue = false;
std::optional<HistoryVisibility> _historyVisibilitySavedValue;
std::optional<QString> _usernameSavedValue;
std::optional<bool> _signaturesSavedValue;
@@ -489,7 +490,8 @@ void Controller::refreshHistoryVisibility(anim::type animated) {
return;
}
_controls.historyVisibilityWrap->toggle(
(_privacySavedValue != Privacy::Public
(_privacySavedValue != Privacy::HasUsername
&& !_channelHasLocationOriginalValue
&& (!_linkedChatSavedValue || !*_linkedChatSavedValue)),
animated);
};
@@ -506,6 +508,7 @@ void Controller::showEditPeerTypeBox(
Ui::show(
Box<EditPeerTypeBox>(
_peer,
_channelHasLocationOriginalValue,
boxCallback,
_privacySavedValue,
_usernameSavedValue,
@@ -569,26 +572,34 @@ void Controller::fillPrivacyTypeButton() {
Expects(_controls.buttonsLayout != nullptr);
// Create Privacy Button.
const auto hasLocation = _peer->isChannel()
&& _peer->asChannel()->hasLocation();
_privacySavedValue = (_peer->isChannel()
&& _peer->asChannel()->isPublic())
? Privacy::Public
: Privacy::Private;
&& _peer->asChannel()->hasUsername())
? Privacy::HasUsername
: Privacy::NoUsername;
const auto isGroup = (_peer->isChat() || _peer->isMegagroup());
AddButtonWithText(
_controls.buttonsLayout,
(isGroup
(hasLocation
? tr::lng_manage_peer_link_type
: isGroup
? tr::lng_manage_peer_group_type
: tr::lng_manage_peer_channel_type)(),
_privacyTypeUpdates.events(
) | rpl::map([=](Privacy flag) {
return (Privacy::Public == flag
? (isGroup
return (flag == Privacy::HasUsername)
? (hasLocation
? tr::lng_manage_peer_link_permanent
: isGroup
? tr::lng_manage_public_group_title
: tr::lng_manage_public_peer_title)
: (isGroup
: tr::lng_manage_public_peer_title)()
: (hasLocation
? tr::lng_manage_peer_link_invite
: isGroup
? tr::lng_manage_private_group_title
: tr::lng_manage_private_peer_title))();
: tr::lng_manage_private_peer_title)();
}) | rpl::flatten_latest(),
[=] { showEditPeerTypeBox(); });
@@ -640,9 +651,7 @@ void Controller::fillInviteLinkButton() {
Expects(_controls.buttonsLayout != nullptr);
const auto buttonCallback = [=] {
Ui::show(
Box<EditPeerTypeBox>(_peer),
LayerOption::KeepOther);
Ui::show(Box<EditPeerTypeBox>(_peer), LayerOption::KeepOther);
};
AddButtonWithText(
@@ -685,6 +694,7 @@ void Controller::fillHistoryVisibilityButton() {
_historyVisibilitySavedValue = (!channel || channel->hiddenPreHistory())
? HistoryVisibility::Hidden
: HistoryVisibility::Visible;
_channelHasLocationOriginalValue = channel && channel->hasLocation();
const auto updateHistoryVisibility =
std::make_shared<rpl::event_stream<HistoryVisibility>>();
@@ -945,7 +955,7 @@ std::optional<Controller::Saving> Controller::validate() const {
bool Controller::validateUsername(Saving &to) const {
if (!_privacySavedValue) {
return true;
} else if (_privacySavedValue != Privacy::Public) {
} else if (_privacySavedValue != Privacy::HasUsername) {
to.username = QString();
return true;
}
@@ -994,7 +1004,8 @@ bool Controller::validateDescription(Saving &to) const {
bool Controller::validateHistoryVisibility(Saving &to) const {
if (!_controls.historyVisibilityWrap
|| !_controls.historyVisibilityWrap->toggled()
|| (_privacySavedValue == Privacy::Public)) {
|| _channelHasLocationOriginalValue
|| (_privacySavedValue == Privacy::HasUsername)) {
return true;
}
to.hiddenPreHistory

View File

@@ -51,6 +51,7 @@ public:
Controller(
not_null<Ui::VerticalLayout*> container,
not_null<PeerData*> peer,
bool useLocationPhrases,
std::optional<Privacy> privacySavedValue,
std::optional<QString> usernameSavedValue);
@@ -129,10 +130,8 @@ private:
void addRoundButton(
not_null<Ui::VerticalLayout*> container,
Privacy value,
const QString &groupText,
const QString &channelText,
rpl::producer<QString> groupAbout,
rpl::producer<QString> channelAbout);
const QString &text,
rpl::producer<QString> about);
bool inviteLinkShown();
QString inviteLinkText();
@@ -141,6 +140,7 @@ private:
std::optional<Privacy> _privacySavedValue;
std::optional<QString> _usernameSavedValue;
bool _useLocationPhrases = false;
bool _isGroup = false;
bool _isInviteLink = false;
bool _isAllowSave = false;
@@ -158,11 +158,13 @@ private:
Controller::Controller(
not_null<Ui::VerticalLayout*> container,
not_null<PeerData*> peer,
bool useLocationPhrases,
std::optional<Privacy> privacySavedValue,
std::optional<QString> usernameSavedValue)
: _peer(peer)
, _privacySavedValue(privacySavedValue)
, _usernameSavedValue(usernameSavedValue)
, _useLocationPhrases(useLocationPhrases)
, _isGroup(_peer->isChat() || _peer->isMegagroup())
, _isInviteLink(!_privacySavedValue.has_value()
&& !_usernameSavedValue.has_value())
@@ -189,7 +191,7 @@ void Controller::createContent() {
_wrap->add(createInviteLinkEdit());
_wrap->add(createUsernameEdit());
if (_controls.privacy->value() == Privacy::Private) {
if (_controls.privacy->value() == Privacy::NoUsername) {
checkUsernameAvailability();
}
}
@@ -197,21 +199,19 @@ void Controller::createContent() {
void Controller::addRoundButton(
not_null<Ui::VerticalLayout*> container,
Privacy value,
const QString &groupText,
const QString &channelText,
rpl::producer<QString> groupAbout,
rpl::producer<QString> channelAbout) {
const QString &text,
rpl::producer<QString> about) {
container->add(object_ptr<Ui::Radioenum<Privacy>>(
container,
_controls.privacy,
value,
(_isGroup ? groupText : channelText),
text,
st::editPeerPrivacyBoxCheckbox));
container->add(object_ptr<Ui::PaddingWrap<Ui::FlatLabel>>(
container,
object_ptr<Ui::FlatLabel>(
container,
std::move(_isGroup ? groupAbout : channelAbout),
std::move(about),
st::editPeerPrivacyLabel),
st::editPeerPrivacyLabelMargins));
container->add(object_ptr<Ui::FixedHeightWidget>(
@@ -242,24 +242,35 @@ void Controller::fillPrivaciesButtons(
const auto container = result->entity();
const auto isPublic = _peer->isChannel()
&& _peer->asChannel()->isPublic();
&& _peer->asChannel()->hasUsername();
_controls.privacy = std::make_shared<Ui::RadioenumGroup<Privacy>>(
savedValue.value_or(isPublic ? Privacy::Public : Privacy::Private));
savedValue.value_or(
isPublic ? Privacy::HasUsername : Privacy::NoUsername));
addRoundButton(
container,
Privacy::Public,
tr::lng_create_public_group_title(tr::now),
tr::lng_create_public_channel_title(tr::now),
tr::lng_create_public_group_about(),
tr::lng_create_public_channel_about());
Privacy::HasUsername,
(_useLocationPhrases
? tr::lng_create_permanent_link_title
: _isGroup
? tr::lng_create_public_group_title
: tr::lng_create_public_channel_title)(tr::now),
(_isGroup
? tr::lng_create_public_group_about
: tr::lng_create_public_channel_about)());
addRoundButton(
container,
Privacy::Private,
tr::lng_create_private_group_title(tr::now),
tr::lng_create_private_channel_title(tr::now),
tr::lng_create_private_group_about(),
tr::lng_create_private_channel_about());
Privacy::NoUsername,
(_useLocationPhrases
? tr::lng_create_invite_link_title
: _isGroup
? tr::lng_create_private_group_title
: tr::lng_create_private_channel_title)(tr::now),
(_useLocationPhrases
? tr::lng_create_invite_link_about
: _isGroup
? tr::lng_create_private_group_about
: tr::lng_create_private_channel_about)());
_controls.privacy->setChangedCallback([=](Privacy value) {
privacyChanged(value);
@@ -343,7 +354,7 @@ object_ptr<Ui::RpWidget> Controller::createUsernameEdit() {
&Ui::UsernameInput::changed,
[this] { usernameChanged(); });
const auto shown = (_controls.privacy->value() == Privacy::Public);
const auto shown = (_controls.privacy->value() == Privacy::HasUsername);
result->toggle(shown, anim::type::instant);
return std::move(result);
@@ -352,14 +363,14 @@ object_ptr<Ui::RpWidget> Controller::createUsernameEdit() {
void Controller::privacyChanged(Privacy value) {
const auto toggleEditUsername = [&] {
_controls.usernameWrap->toggle(
(value == Privacy::Public),
(value == Privacy::HasUsername),
anim::type::instant);
};
const auto refreshVisibilities = [&] {
// Now first we need to hide that was shown.
// Otherwise box will change own Y position.
if (value == Privacy::Public) {
if (value == Privacy::HasUsername) {
refreshCreateInviteLink();
refreshEditInviteLink();
toggleEditUsername();
@@ -372,12 +383,12 @@ void Controller::privacyChanged(Privacy value) {
refreshEditInviteLink();
}
};
if (value == Privacy::Public) {
if (value == Privacy::HasUsername) {
if (_usernameState == UsernameState::TooMany) {
askUsernameRevoke();
return;
} else if (_usernameState == UsernameState::NotAvailable) {
_controls.privacy->setValue(Privacy::Private);
_controls.privacy->setValue(Privacy::NoUsername);
return;
}
refreshVisibilities();
@@ -394,7 +405,7 @@ void Controller::checkUsernameAvailability() {
if (!_controls.usernameInput) {
return;
}
const auto initial = (_controls.privacy->value() != Privacy::Public);
const auto initial = (_controls.privacy->value() != Privacy::HasUsername);
const auto checking = initial
? qsl(".bad.")
: getUsernameInput();
@@ -425,14 +436,14 @@ void Controller::checkUsernameAvailability() {
_usernameState = UsernameState::Normal;
if (type == qstr("CHANNEL_PUBLIC_GROUP_NA")) {
_usernameState = UsernameState::NotAvailable;
_controls.privacy->setValue(Privacy::Private);
_controls.privacy->setValue(Privacy::NoUsername);
} else if (type == qstr("CHANNELS_ADMIN_PUBLIC_TOO_MUCH")) {
_usernameState = UsernameState::TooMany;
if (_controls.privacy->value() == Privacy::Public) {
if (_controls.privacy->value() == Privacy::HasUsername) {
askUsernameRevoke();
}
} else if (initial) {
if (_controls.privacy->value() == Privacy::Public) {
if (_controls.privacy->value() == Privacy::HasUsername) {
_controls.usernameResult = nullptr;
setFocusUsername();
}
@@ -446,10 +457,10 @@ void Controller::checkUsernameAvailability() {
}
void Controller::askUsernameRevoke() {
_controls.privacy->setValue(Privacy::Private);
_controls.privacy->setValue(Privacy::NoUsername);
const auto revokeCallback = crl::guard(this, [this] {
_usernameState = UsernameState::Normal;
_controls.privacy->setValue(Privacy::Public);
_controls.privacy->setValue(Privacy::HasUsername);
checkUsernameAvailability();
});
Ui::show(
@@ -683,20 +694,26 @@ void Controller::refreshCreateInviteLink() {
bool Controller::inviteLinkShown() {
return !_controls.privacy
|| (_controls.privacy->value() == Privacy::Private)
|| (_controls.privacy->value() == Privacy::NoUsername)
|| _isInviteLink;
}
} // namespace
EditPeerTypeBox::EditPeerTypeBox(QWidget*, not_null<PeerData*> peer)
: EditPeerTypeBox(nullptr, peer, false, {}, {}, {}, {}) {
}
EditPeerTypeBox::EditPeerTypeBox(
QWidget*,
not_null<PeerData*> peer,
bool useLocationPhrases,
std::optional<FnMut<void(Privacy, QString)>> savedCallback,
std::optional<Privacy> privacySaved,
std::optional<QString> usernameSaved,
std::optional<rpl::producer<QString>> usernameError)
: _peer(peer)
, _useLocationPhrases(useLocationPhrases)
, _savedCallback(std::move(savedCallback))
, _privacySavedValue(privacySaved)
, _usernameSavedValue(usernameSaved)
@@ -716,6 +733,7 @@ void EditPeerTypeBox::prepare() {
this,
content,
_peer,
_useLocationPhrases,
_privacySavedValue,
_usernameSavedValue);
_focusRequests.events(
@@ -735,14 +753,14 @@ void EditPeerTypeBox::prepare() {
if (!controller->isInviteLink() && _savedCallback.has_value()) {
addButton(tr::lng_settings_save(), [=] {
const auto v = controller->getPrivacy();
if (!controller->isAllowSave() && (v == Privacy::Public)) {
if (!controller->isAllowSave() && (v == Privacy::HasUsername)) {
controller->setFocusUsername();
return;
}
auto local = std::move(*_savedCallback);
local(v,
(v == Privacy::Public)
(v == Privacy::HasUsername)
? controller->getUsernameInput()
: QString()); // We dont need username with private type.
closeBox();

View File

@@ -25,8 +25,8 @@ class Button;
} // namespace Info
enum class Privacy {
Public,
Private,
HasUsername,
NoUsername,
};
enum class UsernameState {
@@ -37,12 +37,16 @@ enum class UsernameState {
class EditPeerTypeBox : public BoxContent {
public:
// Edit just the invite link.
EditPeerTypeBox(QWidget*, not_null<PeerData*> peer);
EditPeerTypeBox(
QWidget*,
not_null<PeerData*> p,
std::optional<FnMut<void(Privacy, QString)>> savedCallback = {},
std::optional<Privacy> privacySaved = {},
std::optional<QString> usernameSaved = {},
not_null<PeerData*> peer,
bool useLocationPhrases,
std::optional<FnMut<void(Privacy, QString)>> savedCallback,
std::optional<Privacy> privacySaved,
std::optional<QString> usernameSaved,
std::optional<rpl::producer<QString>> usernameError = {});
protected:
@@ -51,6 +55,7 @@ protected:
private:
not_null<PeerData*> _peer;
bool _useLocationPhrases = false;
std::optional<FnMut<void(Privacy, QString)>> _savedCallback;
std::optional<Privacy> _privacySavedValue;