mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-05 14:47:39 +00:00
Call finish takeout. Handle errors.
This commit is contained in:
parent
fcda883878
commit
36fb6dac89
@ -1697,6 +1697,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_export_total_files" = "Total files: {count}.";
|
||||
"lng_export_total_size" = "Total size: {size}.";
|
||||
"lng_export_folder" = "Choose export folder";
|
||||
"lng_export_invalid" = "Sorry, you have started a new data export, so this data export is now cancelled.";
|
||||
"lng_export_delay" = "Sorry, for security reasons this data export will be available for you:\n\n{date}\n\nAt this time please try again.";
|
||||
|
||||
// Wnd specific
|
||||
|
||||
|
@ -1023,6 +1023,7 @@ invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector<long> query:!X = X;
|
||||
initConnection#785188b8 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy query:!X = X;
|
||||
invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
|
||||
invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X;
|
||||
invokeWithMessagesRange#365275f2 {X:Type} range:MessageRange query:!X = X;
|
||||
invokeWithTakeout#aca9fd2e {X:Type} takeout_id:long query:!X = X;
|
||||
|
||||
auth.sendCode#86aef0ec flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool api_id:int api_hash:string = auth.SentCode;
|
||||
@ -1082,6 +1083,7 @@ account.verifyPhone#4dd3a7f6 phone_number:string phone_code_hash:string phone_co
|
||||
account.sendVerifyEmailCode#7011509f email:string = account.SentEmailCode;
|
||||
account.verifyEmail#ecba39db email:string code:string = Bool;
|
||||
account.initTakeoutSession#f05b4804 flags:# contacts:flags.0?true message_users:flags.1?true message_chats:flags.2?true message_megagroups:flags.3?true message_channels:flags.4?true files:flags.5?true file_max_size:flags.5?int = account.Takeout;
|
||||
account.finishTakeoutSession#1d2652ee flags:# success:flags.0?true = Bool;
|
||||
|
||||
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
||||
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
|
||||
@ -1200,6 +1202,7 @@ messages.getRecentLocations#bbc45b09 peer:InputPeer limit:int hash:int = message
|
||||
messages.sendMultiMedia#2095512f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> = Updates;
|
||||
messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile;
|
||||
messages.searchStickerSets#c2b7d08b flags:# exclude_featured:flags.0?true q:string hash:int = messages.FoundStickerSets;
|
||||
messages.getSplitRanges#1cff7e08 = Vector<MessageRange>;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||
|
@ -77,7 +77,7 @@ void Session::startExport() {
|
||||
|
||||
_exportViewChanges.fire(_exportPanel.get());
|
||||
|
||||
_exportPanel->closed(
|
||||
_exportPanel->stopRequests(
|
||||
) | rpl::start_with_next([=] {
|
||||
stopExport();
|
||||
}, _export->lifetime());
|
||||
|
@ -707,6 +707,23 @@ void ApiWrap::requestMessages(
|
||||
});
|
||||
}
|
||||
|
||||
void ApiWrap::finishExport(FnMut<void()> done) {
|
||||
const auto guard = gsl::finally([&] { _takeoutId = base::none; });
|
||||
|
||||
mainRequest(MTPaccount_FinishTakeoutSession(
|
||||
MTP_flags(MTPaccount_FinishTakeoutSession::Flag::f_success)
|
||||
)).done(std::move(done)).send();
|
||||
}
|
||||
|
||||
void ApiWrap::cancelExportFast() {
|
||||
if (_takeoutId.has_value()) {
|
||||
const auto requestId = mainRequest(MTPaccount_FinishTakeoutSession(
|
||||
MTP_flags(0)
|
||||
)).send();
|
||||
_mtp.request(requestId).detach();
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::requestDialogsSlice() {
|
||||
Expects(_dialogsProcess != nullptr);
|
||||
|
||||
|
@ -81,6 +81,9 @@ public:
|
||||
Fn<bool(Data::MessagesSlice&&)> slice,
|
||||
FnMut<void()> done);
|
||||
|
||||
void finishExport(FnMut<void()> done);
|
||||
void cancelExportFast();
|
||||
|
||||
~ApiWrap();
|
||||
|
||||
private:
|
||||
|
@ -33,6 +33,7 @@ public:
|
||||
|
||||
// Processing step.
|
||||
void startExport(const Settings &settings);
|
||||
void cancelExportFast();
|
||||
|
||||
private:
|
||||
using Step = ProcessingState::Step;
|
||||
@ -153,6 +154,9 @@ rpl::producer<State> Controller::state() const {
|
||||
}
|
||||
|
||||
void Controller::setState(State &&state) {
|
||||
if (_state.is<CancelledState>()) {
|
||||
return;
|
||||
}
|
||||
_state = std::move(state);
|
||||
_stateChanges.fire_copy(_state);
|
||||
}
|
||||
@ -326,6 +330,11 @@ void Controller::fillSubstepsInSteps(const ApiWrap::StartInfo &info) {
|
||||
_substepsTotal = ranges::accumulate(_substepsInStep, 0);
|
||||
}
|
||||
|
||||
void Controller::cancelExportFast() {
|
||||
_api.cancelExportFast();
|
||||
setState(CancelledState());
|
||||
}
|
||||
|
||||
void Controller::exportNext() {
|
||||
if (!++_stepIndex) {
|
||||
if (ioCatchError(_writer->start(_settings, &_stats))) {
|
||||
@ -336,9 +345,12 @@ void Controller::exportNext() {
|
||||
if (ioCatchError(_writer->finish())) {
|
||||
return;
|
||||
}
|
||||
setFinishedState();
|
||||
_api.finishExport([=] {
|
||||
setFinishedState();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const auto step = _steps[_stepIndex];
|
||||
switch (step) {
|
||||
case Step::Initializing: return initialize();
|
||||
@ -713,6 +725,14 @@ void ControllerWrap::startExport(const Settings &settings) {
|
||||
});
|
||||
}
|
||||
|
||||
void ControllerWrap::cancelExportFast() {
|
||||
LOG(("Export Info: Cancelled export."));
|
||||
|
||||
_wrapped.with([=](Controller &controller) {
|
||||
controller.cancelExportFast();
|
||||
});
|
||||
}
|
||||
|
||||
rpl::lifetime &ControllerWrap::lifetime() {
|
||||
return _lifetime;
|
||||
}
|
||||
|
@ -74,6 +74,9 @@ struct OutputErrorState {
|
||||
QString path;
|
||||
};
|
||||
|
||||
struct CancelledState {
|
||||
};
|
||||
|
||||
struct FinishedState {
|
||||
QString path;
|
||||
int filesCount = 0;
|
||||
@ -85,6 +88,7 @@ using State = base::optional_variant<
|
||||
ProcessingState,
|
||||
ApiErrorState,
|
||||
OutputErrorState,
|
||||
CancelledState,
|
||||
FinishedState>;
|
||||
|
||||
//struct PasswordUpdate {
|
||||
@ -113,6 +117,7 @@ public:
|
||||
|
||||
// Processing step.
|
||||
void startExport(const Settings &settings);
|
||||
void cancelExportFast();
|
||||
|
||||
rpl::lifetime &lifetime();
|
||||
|
||||
|
@ -20,6 +20,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
namespace Export {
|
||||
namespace View {
|
||||
namespace {
|
||||
|
||||
constexpr auto kAddDelay = TimeId(60);
|
||||
|
||||
} // namespace
|
||||
|
||||
PanelController::PanelController(not_null<ControllerWrap*> process)
|
||||
: _process(process) {
|
||||
@ -64,17 +69,27 @@ void PanelController::showSettings() {
|
||||
}
|
||||
|
||||
void PanelController::showError(const ApiErrorState &error) {
|
||||
showError("API Error happened :(\n"
|
||||
+ QString::number(error.data.code()) + ": " + error.data.type()
|
||||
+ "\n" + error.data.description());
|
||||
if (error.data.type() == qstr("TAKEOUT_INVALID")) {
|
||||
showError(lang(lng_export_invalid));
|
||||
} else if (error.data.type().startsWith(qstr("TAKEOUT_INIT_DELAY_"))) {
|
||||
const auto seconds = std::max(error.data.type().mid(
|
||||
qstr("TAKEOUT_INIT_DELAY_").size()).toInt(), 0) + kAddDelay;
|
||||
const auto now = QDateTime::currentDateTime();
|
||||
const auto when = now.addSecs(seconds);
|
||||
showError(lng_export_delay(lt_date, langDateTimeFull(when)));
|
||||
} else {
|
||||
showCriticalError("API Error happened :(\n"
|
||||
+ QString::number(error.data.code()) + ": " + error.data.type()
|
||||
+ "\n" + error.data.description());
|
||||
}
|
||||
}
|
||||
|
||||
void PanelController::showError(const OutputErrorState &error) {
|
||||
showError("Disk Error happened :(\n"
|
||||
showCriticalError("Disk Error happened :(\n"
|
||||
"Could not write path:\n" + error.path);
|
||||
}
|
||||
|
||||
void PanelController::showError(const QString &text) {
|
||||
void PanelController::showCriticalError(const QString &text) {
|
||||
auto container = base::make_unique_q<Ui::PaddingWrap<Ui::FlatLabel>>(
|
||||
_panel.get(),
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
@ -92,6 +107,26 @@ void PanelController::showError(const QString &text) {
|
||||
_panel->setHideOnDeactivate(false);
|
||||
}
|
||||
|
||||
void PanelController::showError(const QString &text) {
|
||||
auto box = Box<InformBox>(text);
|
||||
const auto weak = make_weak(box.data());
|
||||
const auto hidden = _panel->isHidden();
|
||||
_panel->showBox(
|
||||
std::move(box),
|
||||
LayerOption::CloseOther,
|
||||
hidden ? anim::type::instant : anim::type::normal);
|
||||
weak->setCloseByEscape(false);
|
||||
weak->setCloseByOutsideClick(false);
|
||||
weak->boxClosing(
|
||||
) | rpl::start_with_next([=] {
|
||||
_panel->hideGetDuration();
|
||||
}, weak->lifetime());
|
||||
if (hidden) {
|
||||
_panel->showAndActivate();
|
||||
}
|
||||
_panel->setHideOnDeactivate(false);
|
||||
}
|
||||
|
||||
void PanelController::showProgress() {
|
||||
_panel->setTitle(Lang::Viewer(lng_export_progress_title));
|
||||
|
||||
@ -125,10 +160,11 @@ void PanelController::stopWithConfirmation(FnMut<void()> callback) {
|
||||
return;
|
||||
}
|
||||
auto stop = [=, callback = std::move(callback)]() mutable {
|
||||
auto saved = std::move(callback);
|
||||
stopExport();
|
||||
if (saved) {
|
||||
if (auto saved = std::move(callback)) {
|
||||
stopExport();
|
||||
saved();
|
||||
} else {
|
||||
_process->cancelExportFast();
|
||||
}
|
||||
};
|
||||
const auto hidden = _panel->isHidden();
|
||||
@ -157,7 +193,7 @@ void PanelController::stopExport() {
|
||||
_panel->hideGetDuration();
|
||||
}
|
||||
|
||||
rpl::producer<> PanelController::closed() const {
|
||||
rpl::producer<> PanelController::stopRequests() const {
|
||||
return _panelCloseEvents.events(
|
||||
) | rpl::flatten_latest(
|
||||
) | rpl::filter([=] {
|
||||
@ -174,9 +210,11 @@ void PanelController::updateState(State &&state) {
|
||||
showError(*apiError);
|
||||
} else if (const auto error = base::get_if<OutputErrorState>(&_state)) {
|
||||
showError(*error);
|
||||
} else if (const auto finished = base::get_if<FinishedState>(&_state)) {
|
||||
} else if (_state.is<FinishedState>()) {
|
||||
_panel->setTitle(Lang::Viewer(lng_export_title));
|
||||
_panel->setHideOnDeactivate(false);
|
||||
} else if (_state.is<CancelledState>()) {
|
||||
stopExport();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
void activatePanel();
|
||||
void stopWithConfirmation(FnMut<void()> callback = nullptr);
|
||||
|
||||
rpl::producer<> closed() const;
|
||||
rpl::producer<> stopRequests() const;
|
||||
|
||||
rpl::lifetime &lifetime() {
|
||||
return _lifetime;
|
||||
@ -50,6 +50,7 @@ private:
|
||||
void showError(const ApiErrorState &error);
|
||||
void showError(const OutputErrorState &error);
|
||||
void showError(const QString &text);
|
||||
void showCriticalError(const QString &text);
|
||||
|
||||
not_null<ControllerWrap*> _process;
|
||||
|
||||
|
@ -198,7 +198,7 @@ void ConcurrentSender::senderRequestFail(
|
||||
}
|
||||
|
||||
void ConcurrentSender::senderRequestCancel(mtpRequestId requestId) {
|
||||
_requests.erase(requestId);
|
||||
senderRequestDetach(requestId);
|
||||
with_instance([=](not_null<Instance*> instance) {
|
||||
instance->cancel(requestId);
|
||||
});
|
||||
@ -216,4 +216,8 @@ void ConcurrentSender::senderRequestCancelAll() {
|
||||
});
|
||||
}
|
||||
|
||||
void ConcurrentSender::senderRequestDetach(mtpRequestId requestId) {
|
||||
_requests.erase(requestId);
|
||||
}
|
||||
|
||||
} // namespace MTP
|
||||
|
@ -148,6 +148,7 @@ public:
|
||||
class SentRequestWrap {
|
||||
public:
|
||||
void cancel();
|
||||
void detach();
|
||||
|
||||
private:
|
||||
friend class ConcurrentSender;
|
||||
@ -190,6 +191,7 @@ private:
|
||||
RPCError &&error);
|
||||
void senderRequestCancel(mtpRequestId requestId);
|
||||
void senderRequestCancelAll();
|
||||
void senderRequestDetach(mtpRequestId requestId);
|
||||
|
||||
const Fn<void(FnMut<void()>)> _runner;
|
||||
base::flat_map<mtpRequestId, Handlers> _requests;
|
||||
@ -446,6 +448,10 @@ inline void ConcurrentSender::SentRequestWrap::cancel() {
|
||||
_sender->senderRequestCancel(_requestId);
|
||||
}
|
||||
|
||||
inline void ConcurrentSender::SentRequestWrap::detach() {
|
||||
_sender->senderRequestDetach(_requestId);
|
||||
}
|
||||
|
||||
inline ConcurrentSender::SentRequestWrap::SentRequestWrap(
|
||||
not_null<ConcurrentSender*> sender,
|
||||
mtpRequestId requestId
|
||||
|
Loading…
Reference in New Issue
Block a user