mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 15:17:07 +02:00
Add upload cancel confirmation on Quit and Log Out.
This commit is contained in:
parent
8c349c0515
commit
6a3ad52aef
13 changed files with 195 additions and 48 deletions
Telegram
Resources/langs
SourceFiles
|
@ -1922,6 +1922,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_box_delete" = "Delete";
|
||||
"lng_box_leave" = "Leave";
|
||||
|
||||
"lng_upload_sure_stop" = "Are you sure you want to stop uploading your files?\n\nIf you do, you'll need to start over.";
|
||||
"lng_upload_show_file" = "Show file";
|
||||
|
||||
"lng_about_version" = "version {version}";
|
||||
"lng_about_text1" = "Official free messaging app based on {api_link}\nfor speed and security.";
|
||||
"lng_about_text1_api" = "Telegram API";
|
||||
|
|
|
@ -82,7 +82,7 @@ namespace App {
|
|||
if (quitting()) {
|
||||
return;
|
||||
} else if (Core::IsAppLaunched()
|
||||
&& Core::App().exportPreventsQuit()) {
|
||||
&& Core::App().preventsQuit()) {
|
||||
return;
|
||||
}
|
||||
setLaunchState(QuitRequested);
|
||||
|
|
|
@ -639,6 +639,24 @@ void Application::logout(Main::Account *account) {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::logoutWithChecks(Main::Account *account) {
|
||||
const auto weak = base::make_weak(account);
|
||||
const auto retry = [=] {
|
||||
if (const auto account = weak.get()) {
|
||||
logoutWithChecks(account);
|
||||
}
|
||||
};
|
||||
if (!account || !account->sessionExists()) {
|
||||
logout(account);
|
||||
} else if (_exportManager->inProgress(&account->session())) {
|
||||
_exportManager->stopWithConfirmation(retry);
|
||||
} else if (account->session().uploadsInProgress()) {
|
||||
account->session().uploadsStopWithConfirmation(retry);
|
||||
} else {
|
||||
logout(account);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::forceLogOut(
|
||||
not_null<Main::Account*> account,
|
||||
const TextWithEntities &explanation) {
|
||||
|
@ -749,6 +767,33 @@ bool Application::exportPreventsQuit() {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Application::uploadPreventsQuit() {
|
||||
if (!_domain->started()) {
|
||||
return false;
|
||||
}
|
||||
for (const auto &[index, account] : _domain->accounts()) {
|
||||
if (!account->sessionExists()) {
|
||||
continue;
|
||||
}
|
||||
if (account->session().uploadsInProgress()) {
|
||||
account->session().uploadsStopWithConfirmation([=] {
|
||||
for (const auto &[index, account] : _domain->accounts()) {
|
||||
if (account->sessionExists()) {
|
||||
account->session().uploadsStop();
|
||||
}
|
||||
}
|
||||
App::quit();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Application::preventsQuit() {
|
||||
return exportPreventsQuit() || uploadPreventsQuit();
|
||||
}
|
||||
|
||||
int Application::unreadBadge() const {
|
||||
return _domain->unreadBadge();
|
||||
}
|
||||
|
|
|
@ -239,9 +239,11 @@ public:
|
|||
}
|
||||
|
||||
void logout(Main::Account *account = nullptr);
|
||||
void logoutWithChecks(Main::Account *account);
|
||||
void forceLogOut(
|
||||
not_null<Main::Account*> account,
|
||||
const TextWithEntities &explanation);
|
||||
[[nodiscard]] bool uploadPreventsQuit();
|
||||
void checkLocalTime();
|
||||
void lockByPasscode();
|
||||
void unlockPasscode();
|
||||
|
@ -253,6 +255,8 @@ public:
|
|||
void checkAutoLockIn(crl::time time);
|
||||
void localPasscodeChanged();
|
||||
|
||||
[[nodiscard]] bool preventsQuit();
|
||||
|
||||
[[nodiscard]] crl::time lastNonIdleTime() const;
|
||||
void updateNonIdle();
|
||||
|
||||
|
|
|
@ -70,16 +70,11 @@ constexpr int kAttachMessageToPreviousSecondsDelta = 900;
|
|||
const ClickHandlerContext &context,
|
||||
not_null<Main::Session*> session) {
|
||||
if (const auto controller = context.sessionWindow.get()) {
|
||||
return controller;
|
||||
}
|
||||
const auto &windows = session->windows();
|
||||
if (windows.empty()) {
|
||||
session->domain().activate(&session->account());
|
||||
if (windows.empty()) {
|
||||
return nullptr;
|
||||
if (&controller->session() == session) {
|
||||
return controller;
|
||||
}
|
||||
}
|
||||
return windows.front();
|
||||
return session->tryResolveWindow();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -29,11 +29,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_user.h"
|
||||
#include "data/stickers/data_stickers.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "window/window_lock_widgets.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "calls/calls_instance.h"
|
||||
#include "support/support_helper.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "core/application.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "styles/style_layers.h"
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_SPELLCHECK
|
||||
#include "chat_helpers/spellchecker_common.h"
|
||||
|
@ -347,9 +352,66 @@ void Session::addWindow(not_null<Window::SessionController*> controller) {
|
|||
}) | rpl::distinct_until_changed());
|
||||
}
|
||||
|
||||
bool Session::uploadsInProgress() const {
|
||||
return !!_uploader->currentUploadId();
|
||||
}
|
||||
|
||||
void Session::uploadsStopWithConfirmation(Fn<void()> done) {
|
||||
const auto window = Core::App().primaryWindow();
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
const auto id = _uploader->currentUploadId();
|
||||
const auto exists = !!data().message(id);
|
||||
auto box = Box([=](not_null<Ui::GenericBox*> box) {
|
||||
const auto label = box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box.get(),
|
||||
tr::lng_upload_sure_stop(),
|
||||
st::boxLabel),
|
||||
st::boxPadding + QMargins(0, 0, 0, st::boxPadding.bottom()));
|
||||
box->setStyle(st::defaultBox);
|
||||
box->addButton(tr::lng_selected_upload_stop(), [=] {
|
||||
box->closeBox();
|
||||
|
||||
uploadsStop();
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
}, st::attentionBoxButton);
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
if (exists) {
|
||||
box->addLeftButton(tr::lng_upload_show_file(), [=] {
|
||||
box->closeBox();
|
||||
|
||||
if (const auto item = data().message(id)) {
|
||||
if (const auto window = tryResolveWindow()) {
|
||||
window->showPeerHistoryAtItem(item);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
window->show(std::move(box));
|
||||
}
|
||||
|
||||
void Session::uploadsStop() {
|
||||
_uploader->cancelAll();
|
||||
}
|
||||
|
||||
auto Session::windows() const
|
||||
-> const base::flat_set<not_null<Window::SessionController*>> & {
|
||||
return _windows;
|
||||
}
|
||||
|
||||
Window::SessionController *Session::tryResolveWindow() const {
|
||||
if (_windows.empty()) {
|
||||
domain().activate(_account);
|
||||
if (_windows.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return _windows.front();
|
||||
}
|
||||
|
||||
} // namespace Main
|
||||
|
|
|
@ -125,6 +125,7 @@ public:
|
|||
void addWindow(not_null<Window::SessionController*> controller);
|
||||
[[nodiscard]] auto windows() const
|
||||
-> const base::flat_set<not_null<Window::SessionController*>> &;
|
||||
[[nodiscard]] Window::SessionController *tryResolveWindow() const;
|
||||
|
||||
// Shortcuts.
|
||||
void notifyDownloaderTaskFinished();
|
||||
|
@ -157,6 +158,11 @@ public:
|
|||
// Can be called only right before ~Session.
|
||||
void finishLogout();
|
||||
|
||||
// Uploads cancel with confirmation.
|
||||
[[nodiscard]] bool uploadsInProgress() const;
|
||||
void uploadsStopWithConfirmation(Fn<void()> done);
|
||||
void uploadsStop();
|
||||
|
||||
[[nodiscard]] rpl::lifetime &lifetime() {
|
||||
return _lifetime;
|
||||
}
|
||||
|
|
|
@ -358,26 +358,12 @@ void Uploader::upload(
|
|||
void Uploader::currentFailed() {
|
||||
auto j = queue.find(uploadingId);
|
||||
if (j != queue.end()) {
|
||||
if (j->second.type() == SendMediaType::Photo) {
|
||||
_photoFailed.fire_copy(j->first);
|
||||
} else if (j->second.type() == SendMediaType::File
|
||||
|| j->second.type() == SendMediaType::ThemeFile
|
||||
|| j->second.type() == SendMediaType::Audio) {
|
||||
const auto document = session().data().document(j->second.id());
|
||||
if (document->uploading()) {
|
||||
document->status = FileUploadFailed;
|
||||
}
|
||||
_documentFailed.fire_copy(j->first);
|
||||
} else if (j->second.type() == SendMediaType::Secure) {
|
||||
_secureFailed.fire_copy(j->first);
|
||||
} else {
|
||||
Unexpected("Type in Uploader::currentFailed.");
|
||||
}
|
||||
const auto [msgId, file] = std::move(*j);
|
||||
queue.erase(j);
|
||||
notifyFailed(msgId, file);
|
||||
}
|
||||
|
||||
requestsSent.clear();
|
||||
docRequestsSent.clear();
|
||||
cancelRequests();
|
||||
dcMap.clear();
|
||||
uploadingId = FullMsgId();
|
||||
sentSize = 0;
|
||||
|
@ -388,6 +374,25 @@ void Uploader::currentFailed() {
|
|||
sendNext();
|
||||
}
|
||||
|
||||
void Uploader::notifyFailed(FullMsgId id, const File &file) {
|
||||
const auto type = file.type();
|
||||
if (type == SendMediaType::Photo) {
|
||||
_photoFailed.fire_copy(id);
|
||||
} else if (type == SendMediaType::File
|
||||
|| type == SendMediaType::ThemeFile
|
||||
|| type == SendMediaType::Audio) {
|
||||
const auto document = session().data().document(file.id());
|
||||
if (document->uploading()) {
|
||||
document->status = FileUploadFailed;
|
||||
}
|
||||
_documentFailed.fire_copy(id);
|
||||
} else if (type == SendMediaType::Secure) {
|
||||
_secureFailed.fire_copy(id);
|
||||
} else {
|
||||
Unexpected("Type in Uploader::currentFailed.");
|
||||
}
|
||||
}
|
||||
|
||||
void Uploader::stopSessions() {
|
||||
for (int i = 0; i < MTP::kUploadSessionsCount; ++i) {
|
||||
_api->instance().stopSession(MTP::uploadDcId(i));
|
||||
|
@ -617,7 +622,6 @@ void Uploader::sendNext() {
|
|||
}
|
||||
|
||||
void Uploader::cancel(const FullMsgId &msgId) {
|
||||
uploaded.erase(msgId);
|
||||
if (uploadingId == msgId) {
|
||||
currentFailed();
|
||||
} else {
|
||||
|
@ -625,6 +629,24 @@ void Uploader::cancel(const FullMsgId &msgId) {
|
|||
}
|
||||
}
|
||||
|
||||
void Uploader::cancelAll() {
|
||||
const auto single = queue.empty() ? uploadingId : queue.begin()->first;
|
||||
if (!single) {
|
||||
return;
|
||||
}
|
||||
_pausedId = single;
|
||||
if (uploadingId) {
|
||||
currentFailed();
|
||||
}
|
||||
while (!queue.empty()) {
|
||||
const auto [msgId, file] = std::move(*queue.begin());
|
||||
queue.erase(queue.begin());
|
||||
notifyFailed(msgId, file);
|
||||
}
|
||||
clear();
|
||||
unpause();
|
||||
}
|
||||
|
||||
void Uploader::pause(const FullMsgId &msgId) {
|
||||
_pausedId = msgId;
|
||||
}
|
||||
|
@ -637,9 +659,7 @@ void Uploader::unpause() {
|
|||
void Uploader::confirm(const FullMsgId &msgId) {
|
||||
}
|
||||
|
||||
void Uploader::clear() {
|
||||
uploaded.clear();
|
||||
queue.clear();
|
||||
void Uploader::cancelRequests() {
|
||||
for (const auto &requestData : requestsSent) {
|
||||
_api->request(requestData.first).cancel();
|
||||
}
|
||||
|
@ -648,6 +668,11 @@ void Uploader::clear() {
|
|||
_api->request(requestData.first).cancel();
|
||||
}
|
||||
docRequestsSent.clear();
|
||||
}
|
||||
|
||||
void Uploader::clear() {
|
||||
queue.clear();
|
||||
cancelRequests();
|
||||
dcMap.clear();
|
||||
sentSize = 0;
|
||||
for (int i = 0; i < MTP::kUploadSessionsCount; ++i) {
|
||||
|
|
|
@ -54,6 +54,10 @@ public:
|
|||
|
||||
[[nodiscard]] Main::Session &session() const;
|
||||
|
||||
[[nodiscard]] FullMsgId currentUploadId() const {
|
||||
return uploadingId;
|
||||
}
|
||||
|
||||
void uploadMedia(const FullMsgId &msgId, const SendMediaReady &image);
|
||||
void upload(
|
||||
const FullMsgId &msgId,
|
||||
|
@ -63,6 +67,7 @@ public:
|
|||
void pause(const FullMsgId &msgId);
|
||||
void confirm(const FullMsgId &msgId);
|
||||
|
||||
void cancelAll();
|
||||
void clear();
|
||||
|
||||
rpl::producer<UploadedMedia> photoReady() const {
|
||||
|
@ -108,7 +113,9 @@ private:
|
|||
void processDocumentProgress(const FullMsgId &msgId);
|
||||
void processDocumentFailed(const FullMsgId &msgId);
|
||||
|
||||
void notifyFailed(FullMsgId id, const File &file);
|
||||
void currentFailed();
|
||||
void cancelRequests();
|
||||
|
||||
void sendProgressUpdate(
|
||||
not_null<HistoryItem*> item,
|
||||
|
@ -125,7 +132,6 @@ private:
|
|||
FullMsgId uploadingId;
|
||||
FullMsgId _pausedId;
|
||||
std::map<FullMsgId, File> queue;
|
||||
std::map<FullMsgId, File> uploaded;
|
||||
base::Timer _nextTimer, _stopSessionsTimer;
|
||||
|
||||
rpl::event_stream<UploadedMedia> _photoReady;
|
||||
|
|
|
@ -395,19 +395,12 @@ void Controller::showLogoutConfirmation() {
|
|||
? &sessionController()->session().account()
|
||||
: nullptr;
|
||||
const auto weak = base::make_weak(account);
|
||||
const auto callback = [=] {
|
||||
if (account && !weak) {
|
||||
return;
|
||||
const auto callback = [=](Fn<void()> close) {
|
||||
if (!account || weak) {
|
||||
Core::App().logoutWithChecks(account);
|
||||
}
|
||||
if (account
|
||||
&& account->sessionExists()
|
||||
&& Core::App().exportManager().inProgress(&account->session())) {
|
||||
Ui::hideLayer();
|
||||
Core::App().exportManager().stopWithConfirmation([=] {
|
||||
Core::App().logout(account);
|
||||
});
|
||||
} else {
|
||||
Core::App().logout(account);
|
||||
if (close) {
|
||||
close();
|
||||
}
|
||||
};
|
||||
show(Box<Ui::ConfirmBox>(
|
||||
|
|
|
@ -116,6 +116,7 @@ private:
|
|||
MsgId singlePeerShowAtMsgId);
|
||||
void setupSideBar();
|
||||
void sideBarChanged();
|
||||
void logoutWithChecks(Main::Account *account);
|
||||
|
||||
void showBox(
|
||||
object_ptr<Ui::BoxContent> content,
|
||||
|
|
|
@ -350,7 +350,7 @@ void MainMenu::AccountButton::contextMenuEvent(QContextMenuEvent *e) {
|
|||
const auto session = _session;
|
||||
const auto callback = [=](Fn<void()> &&close) {
|
||||
close();
|
||||
Core::App().logout(&session->account());
|
||||
Core::App().logoutWithChecks(&session->account());
|
||||
};
|
||||
Ui::show(Box<Ui::ConfirmBox>(
|
||||
tr::lng_sure_logout(tr::now),
|
||||
|
|
|
@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/history_view_replies_section.h"
|
||||
#include "history/view/history_view_react_button.h"
|
||||
#include "history/view/history_view_reactions.h"
|
||||
#include "history/view/history_view_scheduled_section.h"
|
||||
#include "media/player/media_player_instance.h"
|
||||
#include "media/view/media_view_open_common.h"
|
||||
#include "data/data_document_resolver.h"
|
||||
|
@ -1320,10 +1321,16 @@ void SessionController::showPeerHistoryAtItem(
|
|||
_window->invokeForSessionController(
|
||||
&item->history()->peer->session().account(),
|
||||
[=](not_null<SessionController*> controller) {
|
||||
controller->showPeerHistory(
|
||||
item->history()->peer,
|
||||
SectionShow::Way::ClearStack,
|
||||
item->id);
|
||||
if (item->isScheduled()) {
|
||||
controller->showSection(
|
||||
std::make_shared<HistoryView::ScheduledMemento>(
|
||||
item->history()));
|
||||
} else {
|
||||
controller->showPeerHistory(
|
||||
item->history()->peer,
|
||||
SectionShow::Way::ClearStack,
|
||||
item->id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue