mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-20 23:27:23 +00:00
Show transfer community button, set 2sv password.
This commit is contained in:
parent
ca7c50fbcd
commit
0dddb7694f
@ -1651,6 +1651,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_rights_chat_banned_custom" = "Custom";
|
||||
"lng_rights_chat_banned_custom_date" = "Until {date}";
|
||||
|
||||
"lng_rights_transfer_group" = "Transfer group ownership";
|
||||
"lng_rights_transfer_channel" = "Transfer channel ownership";
|
||||
"lng_rights_transfer_check" = "Security check";
|
||||
"lng_rights_transfer_check_about" = "You can transfer this group to {user} only if you have:";
|
||||
"lng_rights_transfer_check_password" = "• Enabled **2-Step Verification** more than **7 days** ago.";
|
||||
"lng_rights_transfer_check_session" = "• Logged in on this device more than **24 hours** ago.";
|
||||
"lng_rights_transfer_check_later" = "Please come back later.";
|
||||
"lng_rights_transfer_set_password" = "Set password";
|
||||
"lng_rights_transfer_about" = "This will transfer the full **owner rights** for {group} to {user}.";
|
||||
"lng_rights_transfer_sure" = "Change owner";
|
||||
"lng_rights_transfer_password" = "Please enter your password to complete the transfer.";
|
||||
"lng_rights_transfer_done_group" = "{user} is now the owner of the group.";
|
||||
"lng_rights_transfer_done_channel" = "{user} is now the owner of the channel.";
|
||||
|
||||
"lng_restricted_send_message" = "The admins of this group restricted you from writing here.";
|
||||
"lng_restricted_send_media" = "The admins of this group restricted you from posting media content here.";
|
||||
"lng_restricted_send_stickers" = "The admins of this group restricted you from posting stickers here.";
|
||||
|
@ -985,3 +985,5 @@ addContactWarningMargin: margins(19px, 10px, 19px, 5px);
|
||||
blockUserConfirmation: FlatLabel(boxLabel) {
|
||||
minWidth: 240px;
|
||||
}
|
||||
|
||||
transferCheckWidth: 300px;
|
||||
|
@ -226,10 +226,17 @@ void PasscodeBox::setInnerFocus() {
|
||||
}
|
||||
|
||||
void PasscodeBox::setPasswordDone(const QByteArray &newPasswordBytes) {
|
||||
if (_replacedBy) {
|
||||
_replacedBy->closeBox();
|
||||
}
|
||||
_setRequest = 0;
|
||||
_newPasswordSet.fire_copy(newPasswordBytes);
|
||||
auto text = lang(_reenterPasscode->isHidden() ? lng_cloud_password_removed : (_oldPasscode->isHidden() ? lng_cloud_password_was_set : lng_cloud_password_updated));
|
||||
getDelegate()->show(Box<InformBox>(text), LayerOption::CloseOther);
|
||||
const auto weak = make_weak(this);
|
||||
const auto text = lang(_reenterPasscode->isHidden() ? lng_cloud_password_removed : (_oldPasscode->isHidden() ? lng_cloud_password_was_set : lng_cloud_password_updated));
|
||||
getDelegate()->show(Box<InformBox>(text));
|
||||
if (weak) {
|
||||
closeBox();
|
||||
}
|
||||
}
|
||||
|
||||
void PasscodeBox::closeReplacedBy() {
|
||||
@ -353,8 +360,7 @@ void PasscodeBox::validateEmail(
|
||||
submit,
|
||||
resend,
|
||||
errors->events(),
|
||||
resent->events()),
|
||||
LayerOption::KeepOther);
|
||||
resent->events()));
|
||||
|
||||
box->setCloseByOutsideClick(false);
|
||||
box->setCloseByEscape(false);
|
||||
@ -441,9 +447,12 @@ void PasscodeBox::save(bool force) {
|
||||
}
|
||||
if (!_recoverEmail->isHidden() && email.isEmpty() && !force) {
|
||||
_skipEmailWarning = true;
|
||||
_replacedBy = getDelegate()->show(Box<ConfirmBox>(lang(lng_cloud_password_about_recover), lang(lng_cloud_password_skip_email), st::attentionBoxButton, crl::guard(this, [this] {
|
||||
save(true);
|
||||
})));
|
||||
_replacedBy = getDelegate()->show(
|
||||
Box<ConfirmBox>(
|
||||
lang(lng_cloud_password_about_recover),
|
||||
lang(lng_cloud_password_skip_email),
|
||||
st::attentionBoxButton,
|
||||
crl::guard(this, [this] { save(true); })));
|
||||
} else if (_newPasscode->isHidden()) {
|
||||
clearCloudPassword(old);
|
||||
} else if (_oldPasscode->isHidden()) {
|
||||
@ -452,6 +461,7 @@ void PasscodeBox::save(bool force) {
|
||||
changeCloudPassword(old, pwd);
|
||||
}
|
||||
} else {
|
||||
closeReplacedBy();
|
||||
const auto weak = make_weak(this);
|
||||
cSetPasscodeBadTries(0);
|
||||
Local::setPasscode(pwd.toUtf8());
|
||||
|
@ -163,7 +163,7 @@ void Controller::choose(not_null<ChatData*> chat) {
|
||||
}
|
||||
text.append("\n\n" + lang(lng_manage_discussion_group_private));
|
||||
text.append("\n\n");
|
||||
text.append(lng_manage_discussion_group_warning__generic(
|
||||
text.append(lng_manage_discussion_group_warning__rich(
|
||||
lt_visible,
|
||||
Ui::Text::Bold(lang(lng_manage_discussion_group_visible))));
|
||||
const auto box = std::make_shared<QPointer<BoxContent>>();
|
||||
|
@ -10,18 +10,28 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "ui/wrap/padding_wrap.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/text_options.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "info/profile/info_profile_button.h"
|
||||
#include "settings/settings_privacy_security.h"
|
||||
#include "boxes/calendar_box.h"
|
||||
#include "boxes/generic_box.h"
|
||||
#include "boxes/peers/edit_peer_permissions_box.h"
|
||||
#include "boxes/peers/edit_peer_info_box.h"
|
||||
#include "data/data_peer_values.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_chat.h"
|
||||
#include "data/data_user.h"
|
||||
#include "core/core_cloud_password.h"
|
||||
#include "apiwrap.h"
|
||||
#include "auth_session.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_info.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -29,6 +39,64 @@ constexpr auto kMaxRestrictDelayDays = 366;
|
||||
constexpr auto kSecondsInDay = 24 * 60 * 60;
|
||||
constexpr auto kSecondsInWeek = 7 * kSecondsInDay;
|
||||
|
||||
enum class PasswordErrorType {
|
||||
None,
|
||||
NoPassword,
|
||||
Later,
|
||||
};
|
||||
|
||||
void SetCloudPassword(not_null<GenericBox*> box, not_null<UserData*> user) {
|
||||
user->session().api().reloadPasswordState();
|
||||
user->session().api().passwordState(
|
||||
) | rpl::start_with_next([=] {
|
||||
using namespace Settings;
|
||||
const auto weak = make_weak(box);
|
||||
if (CheckEditCloudPassword()) {
|
||||
box->getDelegate()->show(
|
||||
EditCloudPasswordBox(&user->session()));
|
||||
} else {
|
||||
box->getDelegate()->show(CloudPasswordAppOutdatedBox());
|
||||
}
|
||||
if (weak) {
|
||||
weak->closeBox();
|
||||
}
|
||||
}, box->lifetime());
|
||||
}
|
||||
|
||||
void TransferPasswordError(
|
||||
not_null<GenericBox*> box,
|
||||
not_null<UserData*> user,
|
||||
PasswordErrorType error) {
|
||||
box->setTitle(langFactory(lng_rights_transfer_check));
|
||||
box->setWidth(st::transferCheckWidth);
|
||||
|
||||
auto text = lng_rights_transfer_check_about__rich(
|
||||
lt_user,
|
||||
Ui::Text::Bold(user->shortName())
|
||||
).append('\n').append('\n').append(
|
||||
Ui::Text::RichLangValue(lang(lng_rights_transfer_check_password))
|
||||
).append('\n').append('\n').append(
|
||||
Ui::Text::RichLangValue(lang(lng_rights_transfer_check_session))
|
||||
);
|
||||
if (error == PasswordErrorType::Later) {
|
||||
text.append('\n').append('\n').append(
|
||||
Ui::Text::RichLangValue(lang(lng_rights_transfer_check_later))
|
||||
);
|
||||
}
|
||||
box->addRow(object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
rpl::single(text),
|
||||
st::boxLabel));
|
||||
if (error == PasswordErrorType::Later) {
|
||||
box->addButton(langFactory(lng_box_ok), [=] { box->closeBox(); });
|
||||
} else {
|
||||
box->addButton(langFactory(lng_rights_transfer_set_password), [=] {
|
||||
SetCloudPassword(box, user);
|
||||
});
|
||||
box->addButton(langFactory(lng_cancel), [=] { box->closeBox(); });
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class EditParticipantBox::Inner : public Ui::RpWidget {
|
||||
@ -244,6 +312,7 @@ void EditAdminBox::prepare() {
|
||||
return result;
|
||||
}();
|
||||
|
||||
const auto isGroup = chat || channel->isMegagroup();
|
||||
const auto anyoneCanAddMembers = chat
|
||||
? chat->anyoneCanAddMembers()
|
||||
: channel->anyoneCanAddMembers();
|
||||
@ -252,18 +321,31 @@ void EditAdminBox::prepare() {
|
||||
lng_rights_edit_admin_header,
|
||||
prepareFlags,
|
||||
disabledMessages,
|
||||
peer()->isChat() || peer()->isMegagroup(),
|
||||
isGroup,
|
||||
anyoneCanAddMembers);
|
||||
addControl(std::move(checkboxes), QMargins());
|
||||
|
||||
_aboutAddAdmins = addControl(
|
||||
object_ptr<Ui::FlatLabel>(this, st::boxLabel),
|
||||
st::rightsAboutMargin);
|
||||
rpl::single(
|
||||
auto selectedFlags = rpl::single(
|
||||
getChecked()
|
||||
) | rpl::then(std::move(
|
||||
changes
|
||||
)) | rpl::map(
|
||||
));
|
||||
if (canTransferOwnership()) {
|
||||
const auto allFlags = FullAdminRights(isGroup);
|
||||
setupTransferButton(
|
||||
isGroup
|
||||
)->toggleOn(rpl::duplicate(
|
||||
selectedFlags
|
||||
) | rpl::map(
|
||||
((_1 & allFlags) == allFlags)
|
||||
))->setDuration(0);
|
||||
}
|
||||
_aboutAddAdmins = addControl(
|
||||
object_ptr<Ui::FlatLabel>(this, st::boxLabel),
|
||||
st::rightsAboutMargin);
|
||||
std::move(
|
||||
selectedFlags
|
||||
) | rpl::map(
|
||||
(_1 & Flag::f_add_admins) != 0
|
||||
) | rpl::distinct_until_changed(
|
||||
) | rpl::start_with_next([=](bool checked) {
|
||||
@ -289,6 +371,88 @@ void EditAdminBox::prepare() {
|
||||
}
|
||||
}
|
||||
|
||||
bool EditAdminBox::canTransferOwnership() const {
|
||||
if (user()->isInaccessible() || user()->isBot()) {
|
||||
return false;
|
||||
} else if (const auto chat = peer()->asChat()) {
|
||||
return chat->amCreator();
|
||||
} else if (const auto channel = peer()->asChannel()) {
|
||||
return channel->amCreator();
|
||||
}
|
||||
Unexpected("Chat type in EditAdminBox::canTransferOwnership.");
|
||||
}
|
||||
|
||||
not_null<Ui::SlideWrap<Ui::RpWidget>*> EditAdminBox::setupTransferButton(
|
||||
bool isGroup) {
|
||||
const auto wrap = addControl(
|
||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||
this,
|
||||
object_ptr<Ui::VerticalLayout>(this)));
|
||||
|
||||
const auto container = wrap->entity();
|
||||
const auto addDivider = [&] {
|
||||
container->add(
|
||||
object_ptr<BoxContentDivider>(container),
|
||||
{ 0, st::infoProfileSkip, 0, st::infoProfileSkip });
|
||||
};
|
||||
|
||||
addDivider();
|
||||
container->add(EditPeerInfoBox::CreateButton(
|
||||
this,
|
||||
Lang::Viewer(isGroup
|
||||
? lng_rights_transfer_group
|
||||
: lng_rights_transfer_channel),
|
||||
rpl::single(QString()),
|
||||
[=] { transferOwnership(); },
|
||||
st::peerPermissionsButton));
|
||||
addDivider();
|
||||
|
||||
return wrap;
|
||||
}
|
||||
|
||||
void EditAdminBox::transferOwnership() {
|
||||
if (_checkTransferRequestId) {
|
||||
return;
|
||||
}
|
||||
const auto channel = peer()->isChannel()
|
||||
? peer()->asChannel()->inputChannel
|
||||
: MTP_inputChannelEmpty();
|
||||
const auto api = &peer()->session().api();
|
||||
_checkTransferRequestId = api->request(MTPchannels_EditCreator(
|
||||
channel,
|
||||
MTP_inputUserEmpty(),
|
||||
MTP_inputCheckPasswordEmpty()
|
||||
)).fail([=](const RPCError &error) {
|
||||
_checkTransferRequestId = 0;
|
||||
if (!handleTransferPasswordError(error)) {
|
||||
requestTransferPassword();
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
|
||||
bool EditAdminBox::handleTransferPasswordError(const RPCError &error) {
|
||||
const auto type = [&] {
|
||||
const auto &type = error.type();
|
||||
if (type == qstr("PASSWORD_MISSING")) {
|
||||
return PasswordErrorType::NoPassword;
|
||||
} else if (type.startsWith(qstr("PASSWORD_TOO_FRESH_"))
|
||||
|| type.startsWith(qstr("SESSION_TOO_FRESH_"))) {
|
||||
return PasswordErrorType::Later;
|
||||
}
|
||||
return PasswordErrorType::None;
|
||||
}();
|
||||
if (type == PasswordErrorType::None) {
|
||||
return false;
|
||||
}
|
||||
|
||||
getDelegate()->show(Box(TransferPasswordError, user(), type));
|
||||
return true;
|
||||
}
|
||||
|
||||
void EditAdminBox::requestTransferPassword() {
|
||||
|
||||
}
|
||||
|
||||
void EditAdminBox::refreshAboutAddAdminsText(bool canAddAdmins) {
|
||||
_aboutAddAdmins->setText([&] {
|
||||
if (!canSave()) {
|
||||
|
@ -16,6 +16,8 @@ class LinkButton;
|
||||
class Checkbox;
|
||||
class Radiobutton;
|
||||
class RadiobuttonGroup;
|
||||
template <typename Widget>
|
||||
class SlideWrap;
|
||||
} // namespace Ui
|
||||
|
||||
class CalendarBox;
|
||||
@ -77,15 +79,21 @@ private:
|
||||
|
||||
static MTPChatAdminRights Defaults(not_null<PeerData*> peer);
|
||||
|
||||
void transferOwnership();
|
||||
bool handleTransferPasswordError(const RPCError &error);
|
||||
void requestTransferPassword();
|
||||
bool canSave() const {
|
||||
return !!_saveCallback;
|
||||
}
|
||||
void refreshAboutAddAdminsText(bool canAddAdmins);
|
||||
bool canTransferOwnership() const;
|
||||
not_null<Ui::SlideWrap<Ui::RpWidget>*> setupTransferButton(bool isGroup);
|
||||
|
||||
const MTPChatAdminRights _oldRights;
|
||||
Fn<void(MTPChatAdminRights, MTPChatAdminRights)> _saveCallback;
|
||||
|
||||
QPointer<Ui::FlatLabel> _aboutAddAdmins;
|
||||
mtpRequestId _checkTransferRequestId = 0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -95,7 +95,7 @@ std::vector<std::pair<ChatRestrictions, LangKey>> RestrictionLabels() {
|
||||
const auto restrictions = Data::ListOfRestrictions();
|
||||
auto i = 0;
|
||||
for (const auto key : langKeys) {
|
||||
vector.push_back({restrictions[i++], key});
|
||||
vector.emplace_back(restrictions[i++], key);
|
||||
}
|
||||
return vector;
|
||||
}
|
||||
@ -276,6 +276,14 @@ ChatRestrictions FixDependentRestrictions(ChatRestrictions restrictions) {
|
||||
return restrictions;
|
||||
}
|
||||
|
||||
ChatAdminRights FullAdminRights(bool isGroup) {
|
||||
auto result = ChatAdminRights();
|
||||
for (const auto &[flag, label] : AdminRightLabels(isGroup, true)) {
|
||||
result |= flag;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
EditPeerPermissionsBox::EditPeerPermissionsBox(
|
||||
QWidget*,
|
||||
not_null<PeerData*> peer)
|
||||
|
@ -58,3 +58,4 @@ EditFlagsControl<MTPDchatAdminRights::Flags> CreateEditAdminRights(
|
||||
|
||||
ChatAdminRights DisabledByDefaultRestrictions(not_null<PeerData*> peer);
|
||||
ChatRestrictions FixDependentRestrictions(ChatRestrictions restrictions);
|
||||
ChatAdminRights FullAdminRights(bool isGroup);
|
||||
|
@ -133,7 +133,7 @@ TextWithEntities GenerateAdminChangeText(
|
||||
|
||||
auto newFlags = newRights ? newRights->c_chatAdminRights().vflags.v : MTPDchatAdminRights::Flags(0);
|
||||
auto prevFlags = prevRights ? prevRights->c_chatAdminRights().vflags.v : MTPDchatAdminRights::Flags(0);
|
||||
auto result = lng_admin_log_promoted__generic(lt_user, user);
|
||||
auto result = lng_admin_log_promoted__rich(lt_user, user);
|
||||
|
||||
auto useInviteLinkPhrase = channel->isMegagroup() && channel->anyoneCanAddMembers();
|
||||
auto invitePhrase = (useInviteLinkPhrase ? lng_admin_log_admin_invite_link : lng_admin_log_admin_invite_users);
|
||||
@ -201,14 +201,14 @@ TextWithEntities GenerateBannedChangeText(
|
||||
auto newUntil = newRights ? newRights->c_chatBannedRights().vuntil_date.v : TimeId(0);
|
||||
auto indefinitely = ChannelData::IsRestrictedForever(newUntil);
|
||||
if (newFlags & Flag::f_view_messages) {
|
||||
return lng_admin_log_banned__generic(lt_user, user);
|
||||
return lng_admin_log_banned__rich(lt_user, user);
|
||||
}
|
||||
auto untilText = indefinitely
|
||||
? lang(lng_admin_log_restricted_forever)
|
||||
: lng_admin_log_restricted_until(
|
||||
lt_date,
|
||||
langDateTime(ParseDateTime(newUntil)));
|
||||
auto result = lng_admin_log_restricted__generic(
|
||||
auto result = lng_admin_log_restricted__rich(
|
||||
lt_user,
|
||||
user,
|
||||
lt_until,
|
||||
@ -241,7 +241,7 @@ auto GenerateUserString(MTPint userId) {
|
||||
EntityType::Mention,
|
||||
0,
|
||||
mention.text.size() });
|
||||
return lng_admin_log_user_with_username__generic(lt_name, name, lt_mention, mention);
|
||||
return lng_admin_log_user_with_username__rich(lt_name, name, lt_mention, mention);
|
||||
}
|
||||
|
||||
auto GenerateParticipantChangeTextInner(
|
||||
@ -251,7 +251,7 @@ auto GenerateParticipantChangeTextInner(
|
||||
const auto oldType = oldParticipant ? oldParticipant->type() : 0;
|
||||
return participant.match([&](const MTPDchannelParticipantCreator &data) {
|
||||
// No valid string here :(
|
||||
return lng_admin_log_invited__generic(
|
||||
return lng_admin_log_invited__rich(
|
||||
lt_user,
|
||||
GenerateUserString(data.vuser_id));
|
||||
}, [&](const MTPDchannelParticipantAdmin &data) {
|
||||
@ -285,7 +285,7 @@ auto GenerateParticipantChangeTextInner(
|
||||
nullptr,
|
||||
&oldParticipant->c_channelParticipantBanned().vbanned_rights);
|
||||
}
|
||||
return lng_admin_log_invited__generic(lt_user, user);
|
||||
return lng_admin_log_invited__rich(lt_user, user);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "ui/wrap/padding_wrap.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "lang/lang_file_parser.h"
|
||||
#include "core/file_utilities.h"
|
||||
#include "core/click_handler_types.h"
|
||||
@ -72,42 +73,23 @@ ConfirmSwitchBox::ConfirmSwitchBox(
|
||||
void ConfirmSwitchBox::prepare() {
|
||||
setTitle(langFactory(lng_language_switch_title));
|
||||
|
||||
auto link = TextWithEntities{ lang(lng_language_switch_link) };
|
||||
link.entities.push_back({
|
||||
EntityType::CustomUrl,
|
||||
0,
|
||||
link.text.size(),
|
||||
QString("internal:go_to_translations") });
|
||||
auto name = TextWithEntities{ _name };
|
||||
name.entities.push_back({
|
||||
EntityType::Bold,
|
||||
0,
|
||||
name.text.size() });
|
||||
auto percent = TextWithEntities{ QString::number(_percent) };
|
||||
percent.entities.push_back({
|
||||
EntityType::Bold,
|
||||
0,
|
||||
percent.text.size() });
|
||||
const auto text = (_official
|
||||
? lng_language_switch_about_official__rich
|
||||
: lng_language_switch_about_unofficial__rich)(
|
||||
lt_lang_name,
|
||||
name,
|
||||
Ui::Text::Bold(_name),
|
||||
lt_percent,
|
||||
percent,
|
||||
Ui::Text::Bold(QString::number(_percent)),
|
||||
lt_link,
|
||||
link);
|
||||
auto content = Ui::CreateChild<Ui::PaddingWrap<Ui::FlatLabel>>(
|
||||
Ui::Text::Link(lang(lng_language_switch_link), _editLink));
|
||||
const auto content = Ui::CreateChild<Ui::PaddingWrap<Ui::FlatLabel>>(
|
||||
this,
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
this,
|
||||
rpl::single(text),
|
||||
st::boxLabel),
|
||||
QMargins{ st::boxPadding.left(), 0, st::boxPadding.right(), 0 });
|
||||
content->entity()->setClickHandlerFilter([=](auto&&...) {
|
||||
UrlClickHandler::Open(_editLink);
|
||||
return false;
|
||||
});
|
||||
content->entity()->setLinksTrusted();
|
||||
|
||||
addButton(langFactory(lng_language_switch_apply), [=] {
|
||||
const auto apply = _apply;
|
||||
@ -133,29 +115,19 @@ NotReadyBox::NotReadyBox(
|
||||
void NotReadyBox::prepare() {
|
||||
setTitle(langFactory(lng_language_not_ready_title));
|
||||
|
||||
auto link = TextWithEntities{ lang(lng_language_not_ready_link) };
|
||||
link.entities.push_back({
|
||||
EntityType::CustomUrl,
|
||||
0,
|
||||
link.text.size(),
|
||||
QString("internal:go_to_translations") });
|
||||
auto name = TextWithEntities{ _name };
|
||||
const auto text = lng_language_not_ready_about__generic(
|
||||
const auto text = lng_language_not_ready_about__rich(
|
||||
lt_lang_name,
|
||||
name,
|
||||
TextWithEntities{ _name },
|
||||
lt_link,
|
||||
link);
|
||||
auto content = Ui::CreateChild<Ui::PaddingWrap<Ui::FlatLabel>>(
|
||||
Ui::Text::Link(lang(lng_language_not_ready_link), _editLink));
|
||||
const auto content = Ui::CreateChild<Ui::PaddingWrap<Ui::FlatLabel>>(
|
||||
this,
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
this,
|
||||
rpl::single(text),
|
||||
st::boxLabel),
|
||||
QMargins{ st::boxPadding.left(), 0, st::boxPadding.right(), 0 });
|
||||
content->entity()->setClickHandlerFilter([=](auto&&...) {
|
||||
UrlClickHandler::Open(_editLink);
|
||||
return false;
|
||||
});
|
||||
content->entity()->setLinksTrusted();
|
||||
|
||||
addButton(langFactory(lng_box_ok), [=] { closeBox(); });
|
||||
|
||||
|
@ -238,82 +238,6 @@ void SetupLocalPasscode(not_null<Ui::VerticalLayout*> container) {
|
||||
AddSkip(container);
|
||||
}
|
||||
|
||||
bool CheckEditCloudPassword() {
|
||||
const auto current = Auth().api().passwordStateCurrent();
|
||||
Assert(current.has_value());
|
||||
if (!current->unknownAlgorithm
|
||||
&& current->newPassword
|
||||
&& current->newSecureSecret) {
|
||||
return true;
|
||||
}
|
||||
auto box = std::make_shared<QPointer<BoxContent>>();
|
||||
const auto callback = [=] {
|
||||
Core::UpdateApplication();
|
||||
if (*box) (*box)->closeBox();
|
||||
};
|
||||
*box = Ui::show(Box<ConfirmBox>(
|
||||
lang(lng_passport_app_out_of_date),
|
||||
lang(lng_menu_update),
|
||||
callback));
|
||||
return false;
|
||||
}
|
||||
|
||||
void EditCloudPassword() {
|
||||
const auto current = Auth().api().passwordStateCurrent();
|
||||
Assert(current.has_value());
|
||||
|
||||
const auto box = Ui::show(Box<PasscodeBox>(
|
||||
current->request,
|
||||
current->newPassword,
|
||||
current->hasRecovery,
|
||||
current->notEmptyPassport,
|
||||
current->hint,
|
||||
current->newSecureSecret));
|
||||
|
||||
rpl::merge(
|
||||
box->newPasswordSet() | rpl::map([] { return rpl::empty_value(); }),
|
||||
box->passwordReloadNeeded()
|
||||
) | rpl::start_with_next([=] {
|
||||
Auth().api().reloadPasswordState();
|
||||
}, box->lifetime());
|
||||
|
||||
box->clearUnconfirmedPassword(
|
||||
) | rpl::start_with_next([=] {
|
||||
Auth().api().clearUnconfirmedPassword();
|
||||
}, box->lifetime());
|
||||
}
|
||||
|
||||
void RemoveCloudPassword() {
|
||||
const auto current = Auth().api().passwordStateCurrent();
|
||||
Assert(current.has_value());
|
||||
|
||||
if (!current->request) {
|
||||
Auth().api().clearUnconfirmedPassword();
|
||||
return;
|
||||
}
|
||||
const auto box = Ui::show(Box<PasscodeBox>(
|
||||
current->request,
|
||||
current->newPassword,
|
||||
current->hasRecovery,
|
||||
current->notEmptyPassport,
|
||||
current->hint,
|
||||
current->newSecureSecret,
|
||||
true));
|
||||
|
||||
rpl::merge(
|
||||
box->newPasswordSet(
|
||||
) | rpl::map([] { return rpl::empty_value(); }),
|
||||
box->passwordReloadNeeded()
|
||||
) | rpl::start_with_next([=] {
|
||||
Auth().api().reloadPasswordState();
|
||||
}, box->lifetime());
|
||||
|
||||
box->clearUnconfirmedPassword(
|
||||
) | rpl::start_with_next([=] {
|
||||
Auth().api().clearUnconfirmedPassword();
|
||||
}, box->lifetime());
|
||||
}
|
||||
|
||||
void SetupCloudPassword(not_null<Ui::VerticalLayout*> container) {
|
||||
using namespace rpl::mappers;
|
||||
using State = Core::CloudPasswordState;
|
||||
@ -396,7 +320,9 @@ void SetupCloudPassword(not_null<Ui::VerticalLayout*> container) {
|
||||
))->setDuration(0);
|
||||
change->entity()->addClickHandler([] {
|
||||
if (CheckEditCloudPassword()) {
|
||||
EditCloudPassword();
|
||||
Ui::show(EditCloudPasswordBox(&Auth()));
|
||||
} else {
|
||||
Ui::show(CloudPasswordAppOutdatedBox());
|
||||
}
|
||||
});
|
||||
|
||||
@ -437,6 +363,8 @@ void SetupCloudPassword(not_null<Ui::VerticalLayout*> container) {
|
||||
const auto remove = [] {
|
||||
if (CheckEditCloudPassword()) {
|
||||
RemoveCloudPassword();
|
||||
} else {
|
||||
Ui::show(CloudPasswordAppOutdatedBox());
|
||||
}
|
||||
};
|
||||
const auto disable = container->add(
|
||||
@ -537,6 +465,91 @@ int ExceptionUsersCount(const std::vector<not_null<PeerData*>> &exceptions) {
|
||||
return ranges::accumulate(exceptions, 0, add);
|
||||
}
|
||||
|
||||
bool CheckEditCloudPassword() {
|
||||
const auto current = Auth().api().passwordStateCurrent();
|
||||
Assert(current.has_value());
|
||||
|
||||
if (!current->unknownAlgorithm
|
||||
&& current->newPassword
|
||||
&& current->newSecureSecret) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
object_ptr<BoxContent> EditCloudPasswordBox(not_null<AuthSession*> session) {
|
||||
const auto current = session->api().passwordStateCurrent();
|
||||
Assert(current.has_value());
|
||||
|
||||
auto result = Box<PasscodeBox>(
|
||||
current->request,
|
||||
current->newPassword,
|
||||
current->hasRecovery,
|
||||
current->notEmptyPassport,
|
||||
current->hint,
|
||||
current->newSecureSecret);
|
||||
const auto box = result.data();
|
||||
|
||||
rpl::merge(
|
||||
box->newPasswordSet() | rpl::map([] { return rpl::empty_value(); }),
|
||||
box->passwordReloadNeeded()
|
||||
) | rpl::start_with_next([=] {
|
||||
session->api().reloadPasswordState();
|
||||
}, box->lifetime());
|
||||
|
||||
box->clearUnconfirmedPassword(
|
||||
) | rpl::start_with_next([=] {
|
||||
session->api().clearUnconfirmedPassword();
|
||||
}, box->lifetime());
|
||||
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
void RemoveCloudPassword() {
|
||||
const auto current = Auth().api().passwordStateCurrent();
|
||||
Assert(current.has_value());
|
||||
|
||||
if (!current->request) {
|
||||
Auth().api().clearUnconfirmedPassword();
|
||||
return;
|
||||
}
|
||||
const auto box = Ui::show(Box<PasscodeBox>(
|
||||
current->request,
|
||||
current->newPassword,
|
||||
current->hasRecovery,
|
||||
current->notEmptyPassport,
|
||||
current->hint,
|
||||
current->newSecureSecret,
|
||||
true));
|
||||
|
||||
rpl::merge(
|
||||
box->newPasswordSet(
|
||||
) | rpl::map([] { return rpl::empty_value(); }),
|
||||
box->passwordReloadNeeded()
|
||||
) | rpl::start_with_next([=] {
|
||||
Auth().api().reloadPasswordState();
|
||||
}, box->lifetime());
|
||||
|
||||
box->clearUnconfirmedPassword(
|
||||
) | rpl::start_with_next([=] {
|
||||
Auth().api().clearUnconfirmedPassword();
|
||||
}, box->lifetime());
|
||||
}
|
||||
|
||||
object_ptr<BoxContent> CloudPasswordAppOutdatedBox() {
|
||||
auto box = std::make_shared<QPointer<BoxContent>>();
|
||||
const auto callback = [=] {
|
||||
Core::UpdateApplication();
|
||||
if (*box) (*box)->closeBox();
|
||||
};
|
||||
auto result = Box<ConfirmBox>(
|
||||
lang(lng_passport_app_out_of_date),
|
||||
lang(lng_menu_update),
|
||||
callback);
|
||||
*box = result.data();
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
void AddPrivacyButton(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
LangKey label,
|
||||
|
@ -16,6 +16,11 @@ namespace Settings {
|
||||
|
||||
int ExceptionUsersCount(const std::vector<not_null<PeerData*>> &exceptions);
|
||||
|
||||
bool CheckEditCloudPassword();
|
||||
object_ptr<BoxContent> EditCloudPasswordBox(not_null<AuthSession*> session);
|
||||
void RemoveCloudPassword();
|
||||
object_ptr<BoxContent> CloudPasswordAppOutdatedBox();
|
||||
|
||||
void AddPrivacyButton(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
LangKey label,
|
||||
|
@ -552,8 +552,6 @@ void LayerStackWidget::startAnimation(
|
||||
ClearOld clearOldWidgets,
|
||||
Action action,
|
||||
anim::type animated) {
|
||||
if (App::quitting()) return;
|
||||
|
||||
if (animated == anim::type::instant) {
|
||||
setupNewWidgets();
|
||||
clearOldWidgets();
|
||||
@ -845,7 +843,13 @@ void LayerStackWidget::sendFakeMouseEvent() {
|
||||
sendSynteticMouseEvent(this, QEvent::MouseMove, Qt::NoButton);
|
||||
}
|
||||
|
||||
LayerStackWidget::~LayerStackWidget() = default;
|
||||
LayerStackWidget::~LayerStackWidget() {
|
||||
// Some layer destructors call back into LayerStackWidget.
|
||||
while (!_layers.empty() || !_closingLayers.empty()) {
|
||||
hideAll(anim::type::instant);
|
||||
clearClosingLayers();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Window
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user