Allow clearing calls log.

This commit is contained in:
John Preston 2021-01-21 19:57:12 +04:00
parent ff9bf23461
commit b2c84d675c
13 changed files with 200 additions and 64 deletions

View File

@ -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";

View File

@ -2386,10 +2386,10 @@ void ApiWrap::applyUpdates(
}
int ApiWrap::applyAffectedHistory(
not_null<PeerData*> 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);

View File

@ -154,7 +154,7 @@ public:
const MTPUpdates &updates,
uint64 sentMessageRandomId = 0);
int applyAffectedHistory(
not_null<PeerData*> peer,
PeerData *peer, // May be nullptr, like for deletePhoneCallHistory.
const MTPmessages_AffectedHistory &result);
void registerModifyRequest(const QString &key, mtpRequestId requestId);

View File

@ -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<const HistoryItem*> item) const {
return (ComputeType(item) == _type)
&& (!hasItems() || _items.front()->history() == item->history())
&& (ItemDateTime(item).date() == _date);
}
void addItem(not_null<HistoryItem*> 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<not_null<HistoryItem*>> &items() const {
return _items;
}
void paintStatusText(
Painter &p,
const style::PeerListItem &st,
@ -333,6 +346,20 @@ void BoxController::loadMoreRows() {
}).send();
}
base::unique_qptr<Ui::PopupMenu> BoxController::rowContextMenu(
QWidget *parent,
not_null<PeerListRow*> row) {
const auto &items = static_cast<Row*>(row.get())->items();
const auto session = &this->session();
const auto ids = session->data().itemsToIds(items);
auto result = base::make_unique_q<Ui::PopupMenu>(parent);
result->addAction(tr::lng_context_delete_selected(tr::now), [=] {
Ui::show(Box<DeleteMessagesBox>(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<PeerListRow> BoxController::createRow(
return std::make_unique<Row>(item);
}
void ClearCallsBox(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> window) {
const auto weak = Ui::MakeWeak(box);
box->addRow(
object_ptr<Ui::FlatLabel>(
box,
tr::lng_call_box_clear_sure(),
st::boxLabel),
st::boxPadding);
const auto revokeCheckbox = box->addRow(
object_ptr<Ui::Checkbox>(
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

View File

@ -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<PeerListRow*> row) override;
void loadMoreRows() override;
base::unique_qptr<Ui::PopupMenu> rowContextMenu(
QWidget *parent,
not_null<PeerListRow*> row) override;
private:
void receivedCalls(const QVector<MTPMessage> &result);
void refreshAbout();
@ -49,4 +54,8 @@ private:
};
void ClearCallsBox(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> window);
} // namespace Calls

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<Media> MediaCall::clone(not_null<HistoryItem*> parent) {

View File

@ -274,6 +274,7 @@ public:
MediaCall(
not_null<HistoryItem*> parent,
const MTPDmessageActionPhoneCall &call);
~MediaCall();
std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override;

View File

@ -3412,6 +3412,20 @@ void Session::unregisterContactItem(
}
}
void Session::registerCallItem(not_null<HistoryItem*> item) {
_callItems.emplace(item);
}
void Session::unregisterCallItem(not_null<HistoryItem*> item) {
_callItems.erase(item);
}
void Session::destroyAllCallItems() {
while (!_callItems.empty()) {
(*_callItems.begin())->destroy();
}
}
void Session::documentMessageRemoved(not_null<DocumentData*> document) {
if (_documentItems.find(document) != _documentItems.end()) {
return;

View File

@ -358,6 +358,8 @@ public:
not_null<HistoryItem*> dependent,
not_null<HistoryItem*> 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<HistoryItem*> item);
void registerCallItem(not_null<HistoryItem*> item);
void unregisterCallItem(not_null<HistoryItem*> item);
void documentMessageRemoved(not_null<DocumentData*> document);
@ -908,6 +912,7 @@ private:
std::unordered_map<
UserId,
base::flat_set<not_null<ViewElement*>>> _contactViews;
std::unordered_set<not_null<HistoryItem*>> _callItems;
base::flat_set<not_null<WebPageData*>> _webpagesUpdated;
base::flat_set<not_null<GameData*>> _gamesUpdated;

View File

@ -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<SingleChoiceBox> ChooseAudioInputBox(
radioSt);
}
object_ptr<SingleChoiceBox> 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<QString>{
"OpenAL",
"Webrtc ADM",
#ifdef Q_OS_WIN
"Webrtc ADM2",
#endif // Q_OS_WIN
};
const auto currentOption = static_cast<int>(settings.callAudioBackend());
const auto save = [=](int option) {
Core::App().settings().setCallAudioBackend(
static_cast<Webrtc::Backend>(option));
Core::App().saveSettings();
App::restart();
};
return Box<SingleChoiceBox>(
rpl::single<QString>("Calls audio backend"),
options,
currentOption,
save,
st,
radioSt);
}
//object_ptr<SingleChoiceBox> 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<QString>{
// "OpenAL",
// "Webrtc ADM",
//#ifdef Q_OS_WIN
// "Webrtc ADM2",
//#endif // Q_OS_WIN
// };
// const auto currentOption = static_cast<int>(settings.callAudioBackend());
// const auto save = [=](int option) {
// Core::App().settings().setCallAudioBackend(
// static_cast<Webrtc::Backend>(option));
// Core::App().saveSettings();
// App::restart();
// };
// return Box<SingleChoiceBox>(
// rpl::single<QString>("Calls audio backend"),
// options,
// currentOption,
// save,
// st,
// radioSt);
//}
} // namespace Settings

View File

@ -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 <QtGui/QWindow>
@ -96,6 +97,38 @@ constexpr auto kMinDiffIntensity = 0.25;
return (modifiers & Qt::ShiftModifier) && (modifiers & Qt::AltModifier);
}
void ShowCallsBox(not_null<Window::SessionController*> window) {
auto controller = std::make_unique<Calls::BoxController>(window);
const auto initBox = [=](not_null<PeerListBox*> box) {
box->addButton(tr::lng_close(), [=] {
box->closeBox();
});
using MenuPointer = base::unique_qptr<Ui::PopupMenu>;
const auto menu = std::make_shared<MenuPointer>();
const auto menuButton = box->addTopButton(st::infoTopBarMenu);
menuButton->setClickedCallback([=] {
*menu = base::make_unique_q<Ui::PopupMenu>(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<PeerListBox>(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<PeerListBox>(std::make_unique<Calls::BoxController>(controller), [=](not_null<PeerListBox*> 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 {