mirror of https://github.com/procxx/kepka.git
Add revoking of full history.
This commit is contained in:
parent
33069739ee
commit
eb1825defd
|
@ -2446,6 +2446,30 @@ void ApiWrap::applyAffectedMessages(
|
||||||
App::main()->ptsUpdateAndApply(data.vpts.v, data.vpts_count.v);
|
App::main()->ptsUpdateAndApply(data.vpts.v, data.vpts_count.v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApiWrap::deleteMessages(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
const QVector<MTPint> &ids,
|
||||||
|
bool revoke) {
|
||||||
|
const auto done = [=](const MTPmessages_AffectedMessages & result) {
|
||||||
|
applyAffectedMessages(peer, result);
|
||||||
|
if (const auto history = peer->owner().historyLoaded(peer)) {
|
||||||
|
history->requestChatListMessage();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (const auto channel = peer->asChannel()) {
|
||||||
|
request(MTPchannels_DeleteMessages(
|
||||||
|
channel->inputChannel,
|
||||||
|
MTP_vector<MTPint>(ids)
|
||||||
|
)).done(done).send();
|
||||||
|
} else {
|
||||||
|
using Flag = MTPmessages_DeleteMessages::Flag;
|
||||||
|
request(MTPmessages_DeleteMessages(
|
||||||
|
MTP_flags(revoke ? Flag::f_revoke : Flag(0)),
|
||||||
|
MTP_vector<MTPint>(ids)
|
||||||
|
)).done(done).send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ApiWrap::saveDraftsToCloud() {
|
void ApiWrap::saveDraftsToCloud() {
|
||||||
for (auto i = _draftsSaveRequestIds.begin(), e = _draftsSaveRequestIds.end(); i != e; ++i) {
|
for (auto i = _draftsSaveRequestIds.begin(), e = _draftsSaveRequestIds.end(); i != e; ++i) {
|
||||||
if (i->second) continue; // sent already
|
if (i->second) continue; // sent already
|
||||||
|
|
|
@ -213,6 +213,10 @@ public:
|
||||||
|
|
||||||
void clearHistory(not_null<PeerData*> peer, bool revoke);
|
void clearHistory(not_null<PeerData*> peer, bool revoke);
|
||||||
void deleteConversation(not_null<PeerData*> peer, bool revoke);
|
void deleteConversation(not_null<PeerData*> peer, bool revoke);
|
||||||
|
void deleteMessages(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
const QVector<MTPint> &ids,
|
||||||
|
bool revoke);
|
||||||
|
|
||||||
base::Observable<PeerData*> &fullPeerUpdated() {
|
base::Observable<PeerData*> &fullPeerUpdated() {
|
||||||
return _fullPeerUpdated;
|
return _fullPeerUpdated;
|
||||||
|
|
|
@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/empty_userpic.h"
|
#include "ui/empty_userpic.h"
|
||||||
#include "core/click_handler_types.h"
|
#include "core/click_handler_types.h"
|
||||||
|
#include "window/window_controller.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
|
@ -473,13 +474,52 @@ DeleteMessagesBox::DeleteMessagesBox(
|
||||||
Expects(!_ids.empty());
|
Expects(!_ids.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeleteMessagesBox::DeleteMessagesBox(
|
||||||
|
QWidget*,
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
bool justClear)
|
||||||
|
: _wipeHistoryPeer(peer)
|
||||||
|
, _wipeHistoryJustClear(justClear) {
|
||||||
|
}
|
||||||
|
|
||||||
void DeleteMessagesBox::prepare() {
|
void DeleteMessagesBox::prepare() {
|
||||||
auto details = TextWithEntities();
|
auto details = TextWithEntities();
|
||||||
const auto appendDetails = [&](TextWithEntities &&text) {
|
const auto appendDetails = [&](TextWithEntities &&text) {
|
||||||
TextUtilities::Append(details, { "\n\n" });
|
TextUtilities::Append(details, { "\n\n" });
|
||||||
TextUtilities::Append(details, std::move(text));
|
TextUtilities::Append(details, std::move(text));
|
||||||
};
|
};
|
||||||
if (_moderateFrom) {
|
auto deleteKey = lng_box_delete;
|
||||||
|
auto deleteStyle = &st::defaultBoxButton;
|
||||||
|
if (const auto peer = _wipeHistoryPeer) {
|
||||||
|
if (_wipeHistoryJustClear) {
|
||||||
|
details.text = peer->isSelf()
|
||||||
|
? lang(lng_sure_delete_saved_messages)
|
||||||
|
: peer->isUser()
|
||||||
|
? lng_sure_delete_history(lt_contact, peer->name)
|
||||||
|
: lng_sure_delete_group_history(lt_group, peer->name);
|
||||||
|
deleteStyle = &st::attentionBoxButton;
|
||||||
|
} else {
|
||||||
|
details.text = peer->isSelf()
|
||||||
|
? lang(lng_sure_delete_saved_messages)
|
||||||
|
: peer->isUser()
|
||||||
|
? lng_sure_delete_history(lt_contact, peer->name)
|
||||||
|
: peer->isChat()
|
||||||
|
? lng_sure_delete_and_exit(lt_group, peer->name)
|
||||||
|
: lang(peer->isMegagroup()
|
||||||
|
? lng_sure_leave_group
|
||||||
|
: lng_sure_leave_channel);
|
||||||
|
deleteKey = _wipeHistoryPeer->isUser()
|
||||||
|
? lng_box_delete
|
||||||
|
: lng_box_leave;
|
||||||
|
deleteStyle = &(peer->isChannel()
|
||||||
|
? st::defaultBoxButton
|
||||||
|
: st::attentionBoxButton);
|
||||||
|
}
|
||||||
|
if (auto revoke = revokeText(peer)) {
|
||||||
|
_revoke.create(this, revoke->checkbox, false, st::defaultBoxCheckbox);
|
||||||
|
appendDetails(std::move(revoke->description));
|
||||||
|
}
|
||||||
|
} else if (_moderateFrom) {
|
||||||
Assert(_moderateInChannel != nullptr);
|
Assert(_moderateInChannel != nullptr);
|
||||||
details.text = lang(lng_selected_delete_sure_this);
|
details.text = lang(lng_selected_delete_sure_this);
|
||||||
if (_moderateBan) {
|
if (_moderateBan) {
|
||||||
|
@ -511,8 +551,11 @@ void DeleteMessagesBox::prepare() {
|
||||||
}
|
}
|
||||||
_text.create(this, rpl::single(std::move(details)), st::boxLabel);
|
_text.create(this, rpl::single(std::move(details)), st::boxLabel);
|
||||||
|
|
||||||
addButton(langFactory(lng_box_delete), [this] { deleteAndClear(); });
|
addButton(
|
||||||
addButton(langFactory(lng_cancel), [this] { closeBox(); });
|
langFactory(deleteKey),
|
||||||
|
[=] { deleteAndClear(); },
|
||||||
|
*deleteStyle);
|
||||||
|
addButton(langFactory(lng_cancel), [=] { closeBox(); });
|
||||||
|
|
||||||
auto fullHeight = st::boxPadding.top() + _text->height() + st::boxPadding.bottom();
|
auto fullHeight = st::boxPadding.top() + _text->height() + st::boxPadding.bottom();
|
||||||
if (_moderateFrom) {
|
if (_moderateFrom) {
|
||||||
|
@ -547,6 +590,20 @@ PeerData *DeleteMessagesBox::checkFromSinglePeer() const {
|
||||||
|
|
||||||
auto DeleteMessagesBox::revokeText(not_null<PeerData*> peer) const
|
auto DeleteMessagesBox::revokeText(not_null<PeerData*> peer) const
|
||||||
-> std::optional<RevokeConfig> {
|
-> std::optional<RevokeConfig> {
|
||||||
|
auto result = RevokeConfig();
|
||||||
|
if (peer == _wipeHistoryPeer) {
|
||||||
|
if (!peer->canRevokeFullHistory()) {
|
||||||
|
return std::nullopt;
|
||||||
|
} else if (const auto user = peer->asUser()) {
|
||||||
|
result.checkbox = lng_delete_for_other_check(
|
||||||
|
lt_user,
|
||||||
|
user->firstName);
|
||||||
|
} else {
|
||||||
|
result.checkbox = lang(lng_delete_for_everyone_check);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
const auto items = ranges::view::all(
|
const auto items = ranges::view::all(
|
||||||
_ids
|
_ids
|
||||||
) | ranges::view::transform([](FullMsgId id) {
|
) | ranges::view::transform([](FullMsgId id) {
|
||||||
|
@ -554,6 +611,7 @@ auto DeleteMessagesBox::revokeText(not_null<PeerData*> peer) const
|
||||||
}) | ranges::view::filter([](HistoryItem *item) {
|
}) | ranges::view::filter([](HistoryItem *item) {
|
||||||
return (item != nullptr);
|
return (item != nullptr);
|
||||||
}) | ranges::to_vector;
|
}) | ranges::to_vector;
|
||||||
|
|
||||||
if (items.size() != _ids.size()) {
|
if (items.size() != _ids.size()) {
|
||||||
// We don't have information about all messages.
|
// We don't have information about all messages.
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
@ -575,13 +633,14 @@ auto DeleteMessagesBox::revokeText(not_null<PeerData*> peer) const
|
||||||
? -1
|
? -1
|
||||||
: ranges::count_if(outgoing, canRevoke);
|
: ranges::count_if(outgoing, canRevoke);
|
||||||
|
|
||||||
auto result = RevokeConfig();
|
|
||||||
if (canRevokeAll) {
|
if (canRevokeAll) {
|
||||||
result.checkbox = peer->isUser()
|
if (const auto user = peer->asUser()) {
|
||||||
? lng_delete_for_other_check(
|
result.checkbox = lng_delete_for_other_check(
|
||||||
lt_user,
|
lt_user,
|
||||||
peer->asUser()->firstName)
|
user->firstName);
|
||||||
: lang(lng_delete_for_everyone_check);
|
} else {
|
||||||
|
result.checkbox = lang(lng_delete_for_everyone_check);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
} else if (canRevokeOutgoingCount > 0) {
|
} else if (canRevokeOutgoingCount > 0) {
|
||||||
result.checkbox = lang(lng_delete_for_other_my);
|
result.checkbox = lang(lng_delete_for_other_my);
|
||||||
|
@ -645,6 +704,28 @@ void DeleteMessagesBox::keyPressEvent(QKeyEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteMessagesBox::deleteAndClear() {
|
void DeleteMessagesBox::deleteAndClear() {
|
||||||
|
const auto revoke = _revoke ? _revoke->checked() : false;
|
||||||
|
if (const auto peer = _wipeHistoryPeer) {
|
||||||
|
const auto justClear = _wipeHistoryJustClear;
|
||||||
|
closeBox();
|
||||||
|
|
||||||
|
if (justClear) {
|
||||||
|
peer->session().api().clearHistory(peer, revoke);
|
||||||
|
} else {
|
||||||
|
const auto controller = App::wnd()->controller();
|
||||||
|
if (controller->activeChatCurrent().peer() == peer) {
|
||||||
|
Ui::showChatsList();
|
||||||
|
}
|
||||||
|
// Don't delete old history by default,
|
||||||
|
// because Android app doesn't.
|
||||||
|
//
|
||||||
|
//if (const auto from = peer->migrateFrom()) {
|
||||||
|
// peer->session().api().deleteConversation(from, false);
|
||||||
|
//}
|
||||||
|
peer->session().api().deleteConversation(peer, revoke);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (_moderateFrom) {
|
if (_moderateFrom) {
|
||||||
if (_banUser && _banUser->checked()) {
|
if (_banUser && _banUser->checked()) {
|
||||||
_moderateInChannel->session().api().kickParticipant(
|
_moderateInChannel->session().api().kickParticipant(
|
||||||
|
@ -688,9 +769,8 @@ void DeleteMessagesBox::deleteAndClear() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto revoke = _revoke ? _revoke->checked() : false;
|
|
||||||
for (const auto &[peer, ids] : idsByPeer) {
|
for (const auto &[peer, ids] : idsByPeer) {
|
||||||
App::main()->deleteMessages(peer, ids, revoke);
|
peer->session().api().deleteMessages(peer, ids, revoke);
|
||||||
}
|
}
|
||||||
Ui::hideLayer();
|
Ui::hideLayer();
|
||||||
Auth().data().sendHistoryChangeNotifications();
|
Auth().data().sendHistoryChangeNotifications();
|
||||||
|
|
|
@ -151,7 +151,7 @@ public:
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
bool suggestModerateActions);
|
bool suggestModerateActions);
|
||||||
DeleteMessagesBox(QWidget*, MessageIdsList &&selected);
|
DeleteMessagesBox(QWidget*, MessageIdsList &&selected);
|
||||||
DeleteMessagesBox(QWidget*, not_null<PeerData*> peer, bool deleteChat);
|
DeleteMessagesBox(QWidget*, not_null<PeerData*> peer, bool justClear);
|
||||||
|
|
||||||
void setDeleteConfirmedCallback(Fn<void()> callback) {
|
void setDeleteConfirmedCallback(Fn<void()> callback) {
|
||||||
_deleteConfirmedCallback = std::move(callback);
|
_deleteConfirmedCallback = std::move(callback);
|
||||||
|
@ -172,6 +172,8 @@ private:
|
||||||
PeerData *checkFromSinglePeer() const;
|
PeerData *checkFromSinglePeer() const;
|
||||||
std::optional<RevokeConfig> revokeText(not_null<PeerData*> peer) const;
|
std::optional<RevokeConfig> revokeText(not_null<PeerData*> peer) const;
|
||||||
|
|
||||||
|
PeerData * const _wipeHistoryPeer = nullptr;
|
||||||
|
const bool _wipeHistoryJustClear = false;
|
||||||
const MessageIdsList _ids;
|
const MessageIdsList _ids;
|
||||||
UserData *_moderateFrom = nullptr;
|
UserData *_moderateFrom = nullptr;
|
||||||
ChannelData *_moderateInChannel = nullptr;
|
ChannelData *_moderateInChannel = nullptr;
|
||||||
|
|
|
@ -648,6 +648,12 @@ Data::RestrictionCheckResult PeerData::amRestricted(
|
||||||
return Result::Allowed();
|
return Result::Allowed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PeerData::canRevokeFullHistory() const {
|
||||||
|
return isUser()
|
||||||
|
&& Global::RevokePrivateInbox()
|
||||||
|
&& (Global::RevokePrivateTimeLimit() == 0x7FFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
std::vector<ChatRestrictions> ListOfRestrictions() {
|
std::vector<ChatRestrictions> ListOfRestrictions() {
|
||||||
|
|
|
@ -160,6 +160,7 @@ public:
|
||||||
[[nodiscard]] bool canWrite() const;
|
[[nodiscard]] bool canWrite() const;
|
||||||
[[nodiscard]] Data::RestrictionCheckResult amRestricted(
|
[[nodiscard]] Data::RestrictionCheckResult amRestricted(
|
||||||
ChatRestriction right) const;
|
ChatRestriction right) const;
|
||||||
|
[[nodiscard]] bool canRevokeFullHistory() const;
|
||||||
|
|
||||||
[[nodiscard]] UserData *asUser();
|
[[nodiscard]] UserData *asUser();
|
||||||
[[nodiscard]] const UserData *asUser() const;
|
[[nodiscard]] const UserData *asUser() const;
|
||||||
|
|
|
@ -899,26 +899,6 @@ void MainWidget::dialogsActivate() {
|
||||||
_dialogs->activate();
|
_dialogs->activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::deleteMessages(
|
|
||||||
not_null<PeerData*> peer,
|
|
||||||
const QVector<MTPint> &ids,
|
|
||||||
bool revoke) {
|
|
||||||
if (const auto channel = peer->asChannel()) {
|
|
||||||
MTP::send(
|
|
||||||
MTPchannels_DeleteMessages(
|
|
||||||
channel->inputChannel,
|
|
||||||
MTP_vector<MTPint>(ids)),
|
|
||||||
rpcDone(&MainWidget::messagesAffected, peer));
|
|
||||||
} else {
|
|
||||||
using Flag = MTPmessages_DeleteMessages::Flag;
|
|
||||||
MTP::send(
|
|
||||||
MTPmessages_DeleteMessages(
|
|
||||||
MTP_flags(revoke ? Flag::f_revoke : Flag(0)),
|
|
||||||
MTP_vector<MTPint>(ids)),
|
|
||||||
rpcDone(&MainWidget::messagesAffected, peer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWidget::removeDialog(Dialogs::Key key) {
|
void MainWidget::removeDialog(Dialogs::Key key) {
|
||||||
_dialogs->removeDialog(key);
|
_dialogs->removeDialog(key);
|
||||||
}
|
}
|
||||||
|
@ -1055,21 +1035,6 @@ void MainWidget::checkLastUpdate(bool afterSleep) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::messagesAffected(
|
|
||||||
not_null<PeerData*> peer,
|
|
||||||
const MTPmessages_AffectedMessages &result) {
|
|
||||||
const auto &data = result.c_messages_affectedMessages();
|
|
||||||
if (const auto channel = peer->asChannel()) {
|
|
||||||
channel->ptsUpdateAndApply(data.vpts.v, data.vpts_count.v);
|
|
||||||
} else {
|
|
||||||
ptsUpdateAndApply(data.vpts.v, data.vpts_count.v);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto history = session().data().historyLoaded(peer)) {
|
|
||||||
history->requestChatListMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWidget::handleAudioUpdate(const Media::Player::TrackState &state) {
|
void MainWidget::handleAudioUpdate(const Media::Player::TrackState &state) {
|
||||||
using State = Media::Player::State;
|
using State = Media::Player::State;
|
||||||
const auto document = state.id.audio();
|
const auto document = state.id.audio();
|
||||||
|
|
|
@ -195,11 +195,6 @@ public:
|
||||||
|
|
||||||
void deletePhotoLayer(PhotoData *photo);
|
void deletePhotoLayer(PhotoData *photo);
|
||||||
|
|
||||||
void deleteMessages(
|
|
||||||
not_null<PeerData*> peer,
|
|
||||||
const QVector<MTPint> &ids,
|
|
||||||
bool revoke);
|
|
||||||
|
|
||||||
bool sendMessageFail(const RPCError &error);
|
bool sendMessageFail(const RPCError &error);
|
||||||
|
|
||||||
Dialogs::IndexedList *contactsList();
|
Dialogs::IndexedList *contactsList();
|
||||||
|
@ -371,10 +366,6 @@ private:
|
||||||
void destroyExportTopBar();
|
void destroyExportTopBar();
|
||||||
void exportTopBarHeightUpdated();
|
void exportTopBarHeightUpdated();
|
||||||
|
|
||||||
void messagesAffected(
|
|
||||||
not_null<PeerData*> peer,
|
|
||||||
const MTPmessages_AffectedMessages &result);
|
|
||||||
|
|
||||||
Window::SectionSlideParams prepareShowAnimation(
|
Window::SectionSlideParams prepareShowAnimation(
|
||||||
bool willHaveTopBarShadow);
|
bool willHaveTopBarShadow);
|
||||||
void showNewSection(
|
void showNewSection(
|
||||||
|
|
|
@ -788,69 +788,13 @@ void PeerMenuAddMuteAction(
|
||||||
|
|
||||||
Fn<void()> ClearHistoryHandler(not_null<PeerData*> peer) {
|
Fn<void()> ClearHistoryHandler(not_null<PeerData*> peer) {
|
||||||
return [=] {
|
return [=] {
|
||||||
const auto weak = std::make_shared<QPointer<BoxContent>>();
|
Ui::show(Box<DeleteMessagesBox>(peer, true), LayerOption::KeepOther);
|
||||||
const auto text = peer->isSelf()
|
|
||||||
? lang(lng_sure_delete_saved_messages)
|
|
||||||
: peer->isUser()
|
|
||||||
? lng_sure_delete_history(lt_contact, peer->name)
|
|
||||||
: lng_sure_delete_group_history(lt_group, peer->name);
|
|
||||||
const auto callback = [=] {
|
|
||||||
if (const auto strong = *weak) {
|
|
||||||
strong->closeBox();
|
|
||||||
}
|
|
||||||
peer->session().api().clearHistory(peer, false);
|
|
||||||
};
|
|
||||||
*weak = Ui::show(
|
|
||||||
Box<ConfirmBox>(
|
|
||||||
text,
|
|
||||||
lang(lng_box_delete),
|
|
||||||
st::attentionBoxButton,
|
|
||||||
callback),
|
|
||||||
LayerOption::KeepOther);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Fn<void()> DeleteAndLeaveHandler(not_null<PeerData*> peer) {
|
Fn<void()> DeleteAndLeaveHandler(not_null<PeerData*> peer) {
|
||||||
return [=] {
|
return [=] {
|
||||||
const auto weak = std::make_shared<QPointer<BoxContent>>();
|
Ui::show(Box<DeleteMessagesBox>(peer, false), LayerOption::KeepOther);
|
||||||
const auto text = peer->isSelf()
|
|
||||||
? lang(lng_sure_delete_saved_messages)
|
|
||||||
: peer->isUser()
|
|
||||||
? lng_sure_delete_history(lt_contact, peer->name)
|
|
||||||
: peer->isChat()
|
|
||||||
? lng_sure_delete_and_exit(lt_group, peer->name)
|
|
||||||
: lang(peer->isMegagroup()
|
|
||||||
? lng_sure_leave_group
|
|
||||||
: lng_sure_leave_channel);
|
|
||||||
const auto confirm = lang(peer->isUser()
|
|
||||||
? lng_box_delete
|
|
||||||
: lng_box_leave);
|
|
||||||
const auto &confirmStyle = peer->isChannel()
|
|
||||||
? st::defaultBoxButton
|
|
||||||
: st::attentionBoxButton;
|
|
||||||
const auto callback = [=] {
|
|
||||||
if (const auto strong = *weak) {
|
|
||||||
strong->closeBox();
|
|
||||||
}
|
|
||||||
const auto controller = App::wnd()->controller();
|
|
||||||
if (controller->activeChatCurrent().peer() == peer) {
|
|
||||||
Ui::showChatsList();
|
|
||||||
}
|
|
||||||
// Don't delete old history by default,
|
|
||||||
// because Android app doesn't.
|
|
||||||
//
|
|
||||||
//if (const auto from = peer->migrateFrom()) {
|
|
||||||
// peer->session().api().deleteConversation(from, false);
|
|
||||||
//}
|
|
||||||
peer->session().api().deleteConversation(peer, false);
|
|
||||||
};
|
|
||||||
*weak = Ui::show(
|
|
||||||
Box<ConfirmBox>(
|
|
||||||
text,
|
|
||||||
confirm,
|
|
||||||
confirmStyle,
|
|
||||||
callback),
|
|
||||||
LayerOption::KeepOther);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue