From b2c84d675c89fddda793d7e3513b9a381db20d87 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 21 Jan 2021 19:57:12 +0400 Subject: [PATCH] Allow clearing calls log. --- Telegram/Resources/langs/lang.strings | 3 + Telegram/SourceFiles/apiwrap.cpp | 4 +- Telegram/SourceFiles/apiwrap.h | 2 +- .../calls/calls_box_controller.cpp | 83 ++++++++++++++++-- .../SourceFiles/calls/calls_box_controller.h | 9 ++ Telegram/SourceFiles/core/core_settings.cpp | 4 + Telegram/SourceFiles/core/core_settings.h | 4 +- .../SourceFiles/data/data_media_types.cpp | 5 ++ Telegram/SourceFiles/data/data_media_types.h | 1 + Telegram/SourceFiles/data/data_session.cpp | 14 +++ Telegram/SourceFiles/data/data_session.h | 5 ++ .../SourceFiles/settings/settings_calls.cpp | 86 +++++++++---------- .../SourceFiles/window/window_main_menu.cpp | 44 +++++++--- 13 files changed, 200 insertions(+), 64 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index ba3f25c76a..f84486dca4 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1830,6 +1830,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_call_box_status_yesterday" = "Yesterday at {time}"; "lng_call_box_status_date" = "{date} at {time}"; "lng_call_box_status_group" = "({amount}) {status}"; +"lng_call_box_clear_all" = "Clear All"; +"lng_call_box_clear_sure" = "Are you sure you want to completely clear your calls log?"; +"lng_call_box_clear_button" = "Clear"; "lng_call_outgoing" = "Outgoing call"; "lng_call_video_outgoing" = "Outgoing video call"; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 23c5e89940..c459ffcf58 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -2386,10 +2386,10 @@ void ApiWrap::applyUpdates( } int ApiWrap::applyAffectedHistory( - not_null peer, + PeerData *peer, const MTPmessages_AffectedHistory &result) { const auto &data = result.c_messages_affectedHistory(); - if (const auto channel = peer->asChannel()) { + if (const auto channel = peer ? peer->asChannel() : nullptr) { channel->ptsUpdateAndApply(data.vpts().v, data.vpts_count().v); } else { updates().updateAndApply(data.vpts().v, data.vpts_count().v); diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index 47697939ff..69ac68f7b4 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -154,7 +154,7 @@ public: const MTPUpdates &updates, uint64 sentMessageRandomId = 0); int applyAffectedHistory( - not_null peer, + PeerData *peer, // May be nullptr, like for deletePhoneCallHistory. const MTPmessages_AffectedHistory &result); void registerModifyRequest(const QString &key, mtpRequestId requestId); diff --git a/Telegram/SourceFiles/calls/calls_box_controller.cpp b/Telegram/SourceFiles/calls/calls_box_controller.cpp index f671469aa7..1f52f24381 100644 --- a/Telegram/SourceFiles/calls/calls_box_controller.cpp +++ b/Telegram/SourceFiles/calls/calls_box_controller.cpp @@ -7,10 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "calls/calls_box_controller.h" -#include "styles/style_calls.h" -#include "styles/style_boxes.h" #include "lang/lang_keys.h" #include "ui/effects/ripple_animation.h" +#include "ui/widgets/labels.h" +#include "ui/widgets/checkbox.h" +#include "ui/widgets/popup_menu.h" #include "core/application.h" #include "calls/calls_instance.h" #include "history/history.h" @@ -22,7 +23,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_changes.h" #include "data/data_media_types.h" #include "data/data_user.h" +#include "boxes/confirm_box.h" #include "app.h" +#include "apiwrap.h" +#include "styles/style_layers.h" // st::boxLabel. +#include "styles/style_calls.h" +#include "styles/style_boxes.h" namespace Calls { namespace { @@ -49,6 +55,7 @@ public: bool canAddItem(not_null item) const { return (ComputeType(item) == _type) + && (!hasItems() || _items.front()->history() == item->history()) && (ItemDateTime(item).date() == _date); } void addItem(not_null item) { @@ -66,20 +73,26 @@ public: refreshStatus(); } } - bool hasItems() const { + [[nodiscard]] bool hasItems() const { return !_items.empty(); } - MsgId minItemId() const { + [[nodiscard]] MsgId minItemId() const { Expects(hasItems()); + return _items.back()->id; } - MsgId maxItemId() const { + [[nodiscard]] MsgId maxItemId() const { Expects(hasItems()); + return _items.front()->id; } + [[nodiscard]] const std::vector> &items() const { + return _items; + } + void paintStatusText( Painter &p, const style::PeerListItem &st, @@ -333,6 +346,20 @@ void BoxController::loadMoreRows() { }).send(); } +base::unique_qptr BoxController::rowContextMenu( + QWidget *parent, + not_null row) { + const auto &items = static_cast(row.get())->items(); + const auto session = &this->session(); + const auto ids = session->data().itemsToIds(items); + + auto result = base::make_unique_q(parent); + result->addAction(tr::lng_context_delete_selected(tr::now), [=] { + Ui::show(Box(session, base::duplicate(ids))); + }); + return result; +} + void BoxController::refreshAbout() { setDescriptionText(delegate()->peerListFullRowsCount() ? QString() : tr::lng_call_box_about(tr::now)); } @@ -448,4 +475,50 @@ std::unique_ptr BoxController::createRow( return std::make_unique(item); } +void ClearCallsBox( + not_null box, + not_null window) { + const auto weak = Ui::MakeWeak(box); + box->addRow( + object_ptr( + box, + tr::lng_call_box_clear_sure(), + st::boxLabel), + st::boxPadding); + const auto revokeCheckbox = box->addRow( + object_ptr( + box, + tr::lng_delete_for_everyone_check(tr::now), + false, + st::defaultBoxCheckbox), + style::margins( + st::boxPadding.left(), + st::boxPadding.bottom(), + st::boxPadding.right(), + st::boxPadding.bottom())); + + const auto api = &window->session().api(); + const auto sendRequest = [=](bool revoke, auto self) -> void { + using Flag = MTPmessages_DeletePhoneCallHistory::Flag; + api->request(MTPmessages_DeletePhoneCallHistory( + MTP_flags(revoke ? Flag::f_revoke : Flag(0)) + )).done([=](const MTPmessages_AffectedHistory &result) { + const auto offset = api->applyAffectedHistory(nullptr, result); + if (offset > 0) { + self(revoke, self); + } else { + api->session().data().destroyAllCallItems(); + if (const auto strong = weak.data()) { + strong->closeBox(); + } + } + }).send(); + }; + + box->addButton(tr::lng_call_box_clear_button(), [=] { + sendRequest(revokeCheckbox->checked(), sendRequest); + }); + box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); +} + } // namespace Calls diff --git a/Telegram/SourceFiles/calls/calls_box_controller.h b/Telegram/SourceFiles/calls/calls_box_controller.h index ae5894df47..a4bd41804f 100644 --- a/Telegram/SourceFiles/calls/calls_box_controller.h +++ b/Telegram/SourceFiles/calls/calls_box_controller.h @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "boxes/peer_list_box.h" +#include "ui/layers/generic_box.h" namespace Window { class SessionController; @@ -25,6 +26,10 @@ public: void rowActionClicked(not_null row) override; void loadMoreRows() override; + base::unique_qptr rowContextMenu( + QWidget *parent, + not_null row) override; + private: void receivedCalls(const QVector &result); void refreshAbout(); @@ -49,4 +54,8 @@ private: }; +void ClearCallsBox( + not_null box, + not_null window); + } // namespace Calls diff --git a/Telegram/SourceFiles/core/core_settings.cpp b/Telegram/SourceFiles/core/core_settings.cpp index ca70b71c67..8940fdf6e1 100644 --- a/Telegram/SourceFiles/core/core_settings.cpp +++ b/Telegram/SourceFiles/core/core_settings.cpp @@ -436,6 +436,10 @@ void Settings::setTabbedReplacedWithInfo(bool enabled) { } } +Webrtc::Backend Settings::callAudioBackend() const { + return Webrtc::Backend::OpenAL; +} + void Settings::setDialogsWidthRatio(float64 ratio) { _dialogsWidthRatio = ratio; } diff --git a/Telegram/SourceFiles/core/core_settings.h b/Telegram/SourceFiles/core/core_settings.h index a476dde4b1..33a0927706 100644 --- a/Telegram/SourceFiles/core/core_settings.h +++ b/Telegram/SourceFiles/core/core_settings.h @@ -221,9 +221,7 @@ public: void setCallAudioDuckingEnabled(bool value) { _callAudioDuckingEnabled = value; } - [[nodiscard]] Webrtc::Backend callAudioBackend() const { - return _callAudioBackend; - } + [[nodiscard]] Webrtc::Backend callAudioBackend() const; void setCallAudioBackend(Webrtc::Backend backend) { _callAudioBackend = backend; } diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index d32e043cba..e1df3afb9a 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -892,6 +892,11 @@ MediaCall::MediaCall( const MTPDmessageActionPhoneCall &call) : Media(parent) , _call(ComputeCallData(call)) { + parent->history()->owner().registerCallItem(parent); +} + +MediaCall::~MediaCall() { + parent()->history()->owner().unregisterCallItem(parent()); } std::unique_ptr MediaCall::clone(not_null parent) { diff --git a/Telegram/SourceFiles/data/data_media_types.h b/Telegram/SourceFiles/data/data_media_types.h index ed139bbcf2..b99cdd065d 100644 --- a/Telegram/SourceFiles/data/data_media_types.h +++ b/Telegram/SourceFiles/data/data_media_types.h @@ -274,6 +274,7 @@ public: MediaCall( not_null parent, const MTPDmessageActionPhoneCall &call); + ~MediaCall(); std::unique_ptr clone(not_null parent) override; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index beee6604c0..3c3be4212f 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -3412,6 +3412,20 @@ void Session::unregisterContactItem( } } +void Session::registerCallItem(not_null item) { + _callItems.emplace(item); +} + +void Session::unregisterCallItem(not_null item) { + _callItems.erase(item); +} + +void Session::destroyAllCallItems() { + while (!_callItems.empty()) { + (*_callItems.begin())->destroy(); + } +} + void Session::documentMessageRemoved(not_null document) { if (_documentItems.find(document) != _documentItems.end()) { return; diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index ef33088200..4192aff983 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -358,6 +358,8 @@ public: not_null dependent, not_null dependency); + void destroyAllCallItems(); + void registerMessageRandomId(uint64 randomId, FullMsgId itemId); void unregisterMessageRandomId(uint64 randomId); [[nodiscard]] FullMsgId messageIdByRandomId(uint64 randomId) const; @@ -570,6 +572,8 @@ public: void unregisterContactItem( UserId contactId, not_null item); + void registerCallItem(not_null item); + void unregisterCallItem(not_null item); void documentMessageRemoved(not_null document); @@ -908,6 +912,7 @@ private: std::unordered_map< UserId, base::flat_set>> _contactViews; + std::unordered_set> _callItems; base::flat_set> _webpagesUpdated; base::flat_set> _gamesUpdated; diff --git a/Telegram/SourceFiles/settings/settings_calls.cpp b/Telegram/SourceFiles/settings/settings_calls.cpp index bbc0676b8e..abcb8b49b1 100644 --- a/Telegram/SourceFiles/settings/settings_calls.cpp +++ b/Telegram/SourceFiles/settings/settings_calls.cpp @@ -259,22 +259,22 @@ void Calls::setupContent() { // }, content->lifetime()); //#endif // Q_OS_MAC && !OS_MAC_STORE - const auto backend = [&]() -> QString { - using namespace Webrtc; - switch (settings.callAudioBackend()) { - case Backend::OpenAL: return "OpenAL"; - case Backend::ADM: return "WebRTC ADM"; - case Backend::ADM2: return "WebRTC ADM2"; - } - Unexpected("Value in backend."); - }(); - AddButton( - content, - rpl::single("Call audio backend: " + backend), - st::settingsButton - )->addClickHandler([] { - Ui::show(ChooseAudioBackendBox()); - }); + //const auto backend = [&]() -> QString { + // using namespace Webrtc; + // switch (settings.callAudioBackend()) { + // case Backend::OpenAL: return "OpenAL"; + // case Backend::ADM: return "WebRTC ADM"; + // case Backend::ADM2: return "WebRTC ADM2"; + // } + // Unexpected("Value in backend."); + //}(); + //AddButton( + // content, + // rpl::single("Call audio backend: " + backend), + // st::settingsButton + //)->addClickHandler([] { + // Ui::show(ChooseAudioBackendBox()); + //}); AddButton( content, tr::lng_settings_call_open_system_prefs(), @@ -418,33 +418,33 @@ object_ptr ChooseAudioInputBox( radioSt); } -object_ptr ChooseAudioBackendBox( - const style::Checkbox *st, - const style::Radio *radioSt) { - const auto &settings = Core::App().settings(); - const auto list = GetAudioInputList(settings.callAudioBackend()); - const auto options = std::vector{ - "OpenAL", - "Webrtc ADM", -#ifdef Q_OS_WIN - "Webrtc ADM2", -#endif // Q_OS_WIN - }; - const auto currentOption = static_cast(settings.callAudioBackend()); - const auto save = [=](int option) { - Core::App().settings().setCallAudioBackend( - static_cast(option)); - Core::App().saveSettings(); - App::restart(); - }; - return Box( - rpl::single("Calls audio backend"), - options, - currentOption, - save, - st, - radioSt); -} +//object_ptr ChooseAudioBackendBox( +// const style::Checkbox *st, +// const style::Radio *radioSt) { +// const auto &settings = Core::App().settings(); +// const auto list = GetAudioInputList(settings.callAudioBackend()); +// const auto options = std::vector{ +// "OpenAL", +// "Webrtc ADM", +//#ifdef Q_OS_WIN +// "Webrtc ADM2", +//#endif // Q_OS_WIN +// }; +// const auto currentOption = static_cast(settings.callAudioBackend()); +// const auto save = [=](int option) { +// Core::App().settings().setCallAudioBackend( +// static_cast(option)); +// Core::App().saveSettings(); +// App::restart(); +// }; +// return Box( +// rpl::single("Calls audio backend"), +// options, +// currentOption, +// save, +// st, +// radioSt); +//} } // namespace Settings diff --git a/Telegram/SourceFiles/window/window_main_menu.cpp b/Telegram/SourceFiles/window/window_main_menu.cpp index 14faab386f..655ba17068 100644 --- a/Telegram/SourceFiles/window/window_main_menu.cpp +++ b/Telegram/SourceFiles/window/window_main_menu.cpp @@ -56,6 +56,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_dialogs.h" #include "styles/style_settings.h" #include "styles/style_boxes.h" +#include "styles/style_info.h" // infoTopBarMenu #include "styles/style_layers.h" #include @@ -96,6 +97,38 @@ constexpr auto kMinDiffIntensity = 0.25; return (modifiers & Qt::ShiftModifier) && (modifiers & Qt::AltModifier); } +void ShowCallsBox(not_null window) { + auto controller = std::make_unique(window); + const auto initBox = [=](not_null box) { + box->addButton(tr::lng_close(), [=] { + box->closeBox(); + }); + using MenuPointer = base::unique_qptr; + const auto menu = std::make_shared(); + const auto menuButton = box->addTopButton(st::infoTopBarMenu); + menuButton->setClickedCallback([=] { + *menu = base::make_unique_q(menuButton); + const auto showSettings = [=] { + window->showSettings( + Settings::Type::Calls, + Window::SectionShow(anim::type::instant)); + }; + const auto clearAll = crl::guard(box, [=] { + box->getDelegate()->show(Box(Calls::ClearCallsBox, window)); + }); + (*menu)->addAction( + tr::lng_settings_section_call_settings(tr::now), + showSettings); + (*menu)->addAction( + tr::lng_call_box_clear_all(tr::now), + clearAll); + (*menu)->popup(QCursor::pos()); + return true; + }); + }; + Ui::show(Box(std::move(controller), initBox)); +} + } // namespace namespace Window { @@ -869,16 +902,7 @@ void MainMenu::refreshMenu() { }, &st::mainMenuContacts, &st::mainMenuContactsOver); if (_controller->session().serverConfig().phoneCallsEnabled.current()) { _menu->addAction(tr::lng_menu_calls(tr::now), [=] { - Ui::show(Box(std::make_unique(controller), [=](not_null box) { - box->addButton(tr::lng_close(), [=] { - box->closeBox(); - }); - box->addTopButton(st::callSettingsButton, [=] { - controller->showSettings( - Settings::Type::Calls, - Window::SectionShow(anim::type::instant)); - }); - })); + ShowCallsBox(controller); }, &st::mainMenuCalls, &st::mainMenuCallsOver); } } else {