From c554372ba42493e64a57aed3c47477fc3c9c3832 Mon Sep 17 00:00:00 2001 From: AlexeyZavar Date: Wed, 19 Nov 2025 00:14:15 +0300 Subject: [PATCH] fix: random crashes & rewrite worker --- Telegram/SourceFiles/api/api_updates.cpp | 2 + Telegram/SourceFiles/ayu/ayu_worker.cpp | 29 ++++---- .../ayu/features/forward/ayu_sync.cpp | 29 ++++---- .../features/translator/ayu_translator.cpp | 34 +++++---- .../ayu/ui/components/saved_music.cpp | 69 +++++++++---------- .../SourceFiles/ayu/utils/telegram_helpers.h | 3 + .../SourceFiles/core/crash_report_window.cpp | 3 + .../info/profile/info_profile_cover.cpp | 8 ++- 8 files changed, 97 insertions(+), 80 deletions(-) diff --git a/Telegram/SourceFiles/api/api_updates.cpp b/Telegram/SourceFiles/api/api_updates.cpp index 47ce15fcc9..3906d748fd 100644 --- a/Telegram/SourceFiles/api/api_updates.cpp +++ b/Telegram/SourceFiles/api/api_updates.cpp @@ -68,6 +68,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL // AyuGram includes #include "ayu/ayu_settings.h" +#include "ayu/ayu_worker.h" namespace Api { @@ -2039,6 +2040,7 @@ void Updates::feedUpdate(const MTPUpdate &update) { } else if (d.vstatus().type() == mtpc_userStatusOnline) { cSetOtherOnline( d.vstatus().c_userStatusOnline().vexpires().v); + AyuWorker::markAsOnline(_session); } } } break; diff --git a/Telegram/SourceFiles/ayu/ayu_worker.cpp b/Telegram/SourceFiles/ayu/ayu_worker.cpp index 5cfc3faadc..1bc92c6cdb 100644 --- a/Telegram/SourceFiles/ayu/ayu_worker.cpp +++ b/Telegram/SourceFiles/ayu/ayu_worker.cpp @@ -8,6 +8,7 @@ #include "apiwrap.h" #include "ayu_settings.h" +#include "base/timer.h" #include "base/unixtime.h" #include "core/application.h" #include "data/data_user.h" @@ -18,10 +19,21 @@ namespace AyuWorker { +void runOnce(); + std::unordered_map state; +base::Timer &workerTimer() { + static base::Timer timer([] { + runOnce(); + }); + return timer; +} + void markAsOnline(not_null session) { state[session->userId().bare] = true; + workerTimer().cancel(); + workerTimer().callEach(3000); } void lateInit() { @@ -48,39 +60,30 @@ void runOnce() { } const auto t = base::unixtime::now(); - const auto invalidateAll = cOtherOnline() >= t; for (const auto &[index, account] : Core::App().domain().accounts()) { if (account) { if (const auto session = account->maybeSession()) { const auto id = session->userId().bare; if (!state.contains(id)) { - state[id] = true; // newly added account, I suppose + state[id] = true; } - if (invalidateAll || state[id] || session->user()->lastseen().isOnline(t)) { + if (state[id] || session->user()->lastseen().isOnline(t)) { session->api().request(MTPaccount_UpdateStatus( MTP_bool(true) )).send(); state[id] = false; - DEBUG_LOG(("[AyuGram] Sent offline for account with uid %1, invalidate %2").arg(id).arg(invalidateAll)); + DEBUG_LOG(("[AyuGram] Sent offline for account with id %1").arg(id)); } } } } } -[[noreturn]] void loop() { - while (true) { - runOnce(); - std::this_thread::sleep_for(std::chrono::seconds(3)); - } -} - void initialize() { - std::thread t(loop); - t.detach(); + workerTimer().callEach(3000); } } diff --git a/Telegram/SourceFiles/ayu/features/forward/ayu_sync.cpp b/Telegram/SourceFiles/ayu/features/forward/ayu_sync.cpp index 9ce8b778e5..268ba701d3 100644 --- a/Telegram/SourceFiles/ayu/features/forward/ayu_sync.cpp +++ b/Telegram/SourceFiles/ayu/features/forward/ayu_sync.cpp @@ -115,32 +115,29 @@ void loadDocumentSync(not_null session, DocumentData *data, not_ if (path.isEmpty()) { return; } - crl::on_main([&] + crl::on_main([=] { data->save(Data::FileOriginMessage(item->fullId()), path); - - session->downloaderTaskFinished() | rpl::filter([&] + session->downloaderTaskFinished() | rpl::filter([=] { - return data->status == FileDownloadFailed || fileSize(item) == data->size; - }) | rpl::start_with_next([&]() mutable + return !data || data->status == FileDownloadFailed || fileSize(item) == data->size; + }) | rpl::start_with_next([=]() mutable { latch->countDown(); }, *lifetime); }); - constexpr auto overall = std::chrono::minutes(15); const auto startTime = std::chrono::steady_clock::now(); - while (std::chrono::steady_clock::now() - startTime < overall) { if (latch->await(std::chrono::minutes(5))) { break; } - if (!data->loading()) { + if (!data || !data->loading()) { break; } } @@ -154,11 +151,11 @@ void forwardMessagesSync(not_null session, Data::ForwardOptions options) { auto latch = std::make_shared(1); - crl::on_main([=, &latch] + crl::on_main([=] { session->api().forwardMessages(Data::ResolvedForwardDraft(items, options), action, - [&] + [=] { latch->countDown(); }); @@ -211,12 +208,12 @@ void loadPhotoSync(not_null session, const std::pairdownloaderTaskFinished() | rpl::filter([&] + session->downloaderTaskFinished() | rpl::filter([=] { return finalCheck(); - }) | rpl::start_with_next([&]() mutable + }) | rpl::start_with_next([=]() mutable { saveToFiles(); latch->countDown(); @@ -246,13 +243,13 @@ void waitForMsgSync(not_null session, const Api::SendAction &act auto latch = std::make_shared(1); auto lifetime = std::make_shared(); - crl::on_main([&] + crl::on_main([=] { session->data().itemIdChanged() - | rpl::filter([&](const Data::Session::IdChange &update) + | rpl::filter([=](const Data::Session::IdChange &update) { return action.history->peer->id == update.newId.peer; - }) | rpl::start_with_next([&] + }) | rpl::start_with_next([=] { latch->countDown(); }, diff --git a/Telegram/SourceFiles/ayu/features/translator/ayu_translator.cpp b/Telegram/SourceFiles/ayu/features/translator/ayu_translator.cpp index 2465ee4dda..7bfc60fe4d 100644 --- a/Telegram/SourceFiles/ayu/features/translator/ayu_translator.cpp +++ b/Telegram/SourceFiles/ayu/features/translator/ayu_translator.cpp @@ -85,12 +85,14 @@ TranslateManager::Builder TranslateManager::request( mtpRequestId TranslateManager::performTranslation(Builder &req) { const auto id = _nextId++; - _pending.emplace(id, - Pending{ - .done = std::move(req._done), - .fail = std::move(req._fail), - .cancel = nullptr, - }); + _pending.emplace( + id, + Pending{ + .done = std::move(req._done), + .fail = std::move(req._fail), + .cancel = nullptr, + } + ); req._id = id; std::vector texts; @@ -171,7 +173,7 @@ mtpRequestId TranslateManager::performTranslation(Builder &req) { CallbackSuccess onSuccess = [this, id, resultTexts = std::move(resultTexts), cacheKeys = std::move(cacheKeys), uncachedIndices = std::move(uncachedIndices), texts = std::move(texts), - fromLang, toLang, &req](const std::vector &translated) mutable + fromLang, toLang, session = req.session()](const std::vector &translated) mutable { for (size_t i = 0; i < translated.size() && i < uncachedIndices.size(); ++i) { const auto index = uncachedIndices[i]; @@ -179,13 +181,15 @@ mtpRequestId TranslateManager::performTranslation(Builder &req) { const auto &key = cacheKeys[index]; if (!key.isEmpty()) { - insertToCache(key, - CacheEntry{ - .originalText = texts[index], - .translatedText = translated[i], - .fromLang = fromLang, - .toLang = toLang - }); + insertToCache( + key, + CacheEntry{ + .originalText = texts[index], + .translatedText = translated[i], + .fromLang = fromLang, + .toLang = toLang + } + ); } } @@ -193,7 +197,7 @@ mtpRequestId TranslateManager::performTranslation(Builder &req) { for (const auto &translatedText : resultTexts) { vec.push_back(MTP_textWithEntities( MTP_string(translatedText.text), - Api::EntitiesToMTP(req.session(), translatedText.entities))); + Api::EntitiesToMTP(session, translatedText.entities))); } const auto result = MTP_messages_translateResult(MTP_vector(vec)); triggerDone(id, result); diff --git a/Telegram/SourceFiles/ayu/ui/components/saved_music.cpp b/Telegram/SourceFiles/ayu/ui/components/saved_music.cpp index 89f2023fb9..d5a2f33d08 100644 --- a/Telegram/SourceFiles/ayu/ui/components/saved_music.cpp +++ b/Telegram/SourceFiles/ayu/ui/components/saved_music.cpp @@ -131,7 +131,7 @@ Cover GetCurrentCover( }; } -QRgb ExtractColorFromCover(const QPixmap &cover) { +std::optional ExtractColorFromCover(const QPixmap &cover) { const auto palette = Ayu::Ui::Palette::from(cover).generate(); const auto *swatch = palette.darkVibrantSwatch(); @@ -146,7 +146,7 @@ QRgb ExtractColorFromCover(const QPixmap &cover) { } if (!swatch) { - return GetNoCoverBgColor().rgb(); + return std::nullopt; } const auto extractedColor = swatch->rgb(); @@ -237,7 +237,7 @@ void AyuMusicButton::downloadAndMakeCover(FullMsgId msgId) { void AyuMusicButton::makeCover() { const auto weak = base::make_weak(this); - crl::async([=, mediaView = _mediaView] + crl::async([=, mediaView = _mediaView, performerText = _performerText, titleText = _titleText]() { const auto &settings = AyuSettings::getInstance(); const auto &font = st::infoMusicButtonTitle.style.font; @@ -247,7 +247,7 @@ void AyuMusicButton::makeCover() { auto cover = GetCurrentCover(mediaView, QSize(size, size)); if (cover.noCover) { - const auto pix = Ayu::Ui::Itunes::FetchCover(_performerText, _titleText, size); + const auto pix = Ayu::Ui::Itunes::FetchCover(performerText, titleText, size); if (!pix.isNull()) { const auto img = Image(pix.toImage()); const auto args = Images::PrepareArgs{ @@ -264,32 +264,42 @@ void AyuMusicButton::makeCover() { if (cover.noCover || !settings.adaptiveCoverColor) { bgColor = GetNoCoverBgColor(); } else { - bgColor = QColor::fromRgb(ExtractColorFromCover(cover.pixToBg)); + if (const auto extractedColor = ExtractColorFromCover(cover.pixToBg)) { + bgColor = QColor::fromRgb(*extractedColor); + } else { // example: fully black image + cover.noCover = true; + bgColor = GetNoCoverBgColor(); + } } - const auto strong = weak.get(); - if (!strong) { - return; - } - - strong->_currentCover = { - .pix = cover.pixToDraw, - .bg = bgColor, - .noCover = cover.noCover - }; - - crl::on_main([=] - { - const auto strong2 = weak.get(); - if (!strong2) { + crl::on_main([weak, cover = std::move(cover), bgColor]() mutable { + const auto strong = weak.get(); + if (!strong) { return; } - strong2->repaint(); - strong2->_title->repaint(); - strong2->_performer->repaint(); + strong->_currentCover = { + .pix = cover.pixToDraw, + .bg = bgColor, + .noCover = cover.noCover, + }; - strong2->_onReady.fire({}); + const auto &settings2 = AyuSettings::getInstance(); + const auto &cover2 = *strong->_currentCover; + + if (!cover2.noCover && settings2.adaptiveCoverColor && !cover2.pix.isNull()) { + strong->_title->setTextColorOverride(Qt::white); + strong->_performer->setTextColorOverride(performerColor); + } else { + strong->_title->setTextColorOverride(std::nullopt); + strong->_performer->setTextColorOverride(std::nullopt); + } + + strong->repaint(); + strong->_title->repaint(); + strong->_performer->repaint(); + + strong->_onReady.fire({}); }); }); } @@ -318,20 +328,9 @@ void AyuMusicButton::paintEvent(QPaintEvent *e) { } if (!cover.pix.isNull()) { - if (!cover.noCover && settings.adaptiveCoverColor) { - _title->setTextColorOverride(Qt::white); - _performer->setTextColorOverride(performerColor); - } else { - _title->setTextColorOverride(std::nullopt); - _performer->setTextColorOverride(std::nullopt); - } - auto hq = PainterHighQualityEnabler(p); const auto coverRect = QRect(st::infoMusicButtonPadding.left(), st::infoMusicButtonPadding.top(), size, size); p.drawPixmap(coverRect, cover.pix); - } else { - _title->setTextColorOverride(std::nullopt); - _performer->setTextColorOverride(std::nullopt); } } diff --git a/Telegram/SourceFiles/ayu/utils/telegram_helpers.h b/Telegram/SourceFiles/ayu/utils/telegram_helpers.h index 3c9bfece73..c3c237b792 100644 --- a/Telegram/SourceFiles/ayu/utils/telegram_helpers.h +++ b/Telegram/SourceFiles/ayu/utils/telegram_helpers.h @@ -23,6 +23,9 @@ public: : count_(count) { } + TimedCountDownLatch(const TimedCountDownLatch &) = delete; + TimedCountDownLatch &operator=(const TimedCountDownLatch &) = delete; + void countDown() { std::unique_lock lock(mutex_); if (count_ > 0) { diff --git a/Telegram/SourceFiles/core/crash_report_window.cpp b/Telegram/SourceFiles/core/crash_report_window.cpp index 8b9627eae0..e453549cad 100644 --- a/Telegram/SourceFiles/core/crash_report_window.cpp +++ b/Telegram/SourceFiles/core/crash_report_window.cpp @@ -433,6 +433,9 @@ LastCrashedWindow::LastCrashedWindow( _yourReportName.setTextInteractionFlags(Qt::TextSelectableByMouse); _includeUsername.setText(u"Include username @%1 as your contact info"_q.arg(_reportUsername)); + _includeUsername.setCheckState(Qt::Unchecked); + _includeUsername.setDisabled(true); + _includeUsername.setVisible(false); _report.setPlainText(_reportTextNoUsername); diff --git a/Telegram/SourceFiles/info/profile/info_profile_cover.cpp b/Telegram/SourceFiles/info/profile/info_profile_cover.cpp index 240459daf8..d1fdda1d1d 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_cover.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_cover.cpp @@ -925,7 +925,13 @@ void Cover::setupSavedMusic() { AyuSettings::set_adaptiveCoverColor(!settings.adaptiveCoverColor); AyuSettings::save(); - _musicButton->entity()->updateData(DocumentMusicButtonData(document, item)); + const auto mediaRefreshed = item ? item->media() : nullptr; + const auto documentRefreshed = mediaRefreshed ? mediaRefreshed->document() : nullptr; + + if (!documentRefreshed) { + return; + } + _musicButton->entity()->updateData(DocumentMusicButtonData(documentRefreshed, item)); }, &st::menuIconPalette);