mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-19 07:37:11 +02:00
When reporting peer allow to select messages first.
This commit is contained in:
parent
45dcadfff4
commit
467449ac13
25 changed files with 639 additions and 372 deletions
|
@ -240,8 +240,6 @@ PRIVATE
|
|||
boxes/photo_crop_box.h
|
||||
boxes/rate_call_box.cpp
|
||||
boxes/rate_call_box.h
|
||||
boxes/report_box.cpp
|
||||
boxes/report_box.h
|
||||
boxes/self_destruction_box.cpp
|
||||
boxes/self_destruction_box.h
|
||||
boxes/send_files_box.cpp
|
||||
|
|
|
@ -996,6 +996,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_report_group_title" = "Report group";
|
||||
"lng_report_bot_title" = "Report bot";
|
||||
"lng_report_message_title" = "Report message";
|
||||
"lng_report_select_messages" = "Select messages";
|
||||
"lng_report_messages_none" = "Select Messages";
|
||||
"lng_report_messages_count#one" = "Report {count} Message";
|
||||
"lng_report_messages_count#other" = "Report {count} Messages";
|
||||
"lng_report_details_about" = "Please enter any additional details relevant to your report.";
|
||||
"lng_report_details" = "Additional Details";
|
||||
"lng_report_reason_spam" = "Spam";
|
||||
"lng_report_reason_fake" = "Fake Account";
|
||||
"lng_report_reason_violence" = "Violence";
|
||||
|
|
|
@ -1,229 +0,0 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "boxes/report_box.h"
|
||||
|
||||
#include "lang/lang_keys.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_session.h"
|
||||
#include "main/main_session.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "history/history_item.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "mainwindow.h"
|
||||
#include "core/core_settings.h"
|
||||
#include "core/application.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/window_peer_menu.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_profile.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto kReportReasonLengthMax = 200;
|
||||
|
||||
} // namespace
|
||||
|
||||
ReportBox::ReportBox(QWidget*, not_null<PeerData*> peer)
|
||||
: _peer(peer)
|
||||
, _api(&_peer->session().mtp()) {
|
||||
}
|
||||
|
||||
ReportBox::ReportBox(QWidget*, not_null<PeerData*> peer, MessageIdsList ids)
|
||||
: _peer(peer)
|
||||
, _api(&_peer->session().mtp())
|
||||
, _ids(std::move(ids)) {
|
||||
}
|
||||
|
||||
void ReportBox::prepare() {
|
||||
setTitle([&] {
|
||||
if (_ids) {
|
||||
return tr::lng_report_message_title();
|
||||
} else if (_peer->isUser()) {
|
||||
return tr::lng_report_bot_title();
|
||||
} else if (_peer->isMegagroup()) {
|
||||
return tr::lng_report_group_title();
|
||||
} else {
|
||||
return tr::lng_report_title();
|
||||
}
|
||||
}());
|
||||
|
||||
addButton(tr::lng_report_button(), [=] { report(); });
|
||||
addButton(tr::lng_cancel(), [=] { closeBox(); });
|
||||
|
||||
_reasonGroup = std::make_shared<Ui::RadioenumGroup<Reason>>(
|
||||
Reason::Spam);
|
||||
const auto createButton = [&](
|
||||
object_ptr<Ui::Radioenum<Reason>> &button,
|
||||
Reason reason,
|
||||
const QString &text) {
|
||||
button.create(
|
||||
this,
|
||||
_reasonGroup,
|
||||
reason,
|
||||
text,
|
||||
st::defaultBoxCheckbox);
|
||||
};
|
||||
createButton(_reasonSpam, Reason::Spam, tr::lng_report_reason_spam(tr::now));
|
||||
createButton(_reasonFake, Reason::Fake, tr::lng_report_reason_fake(tr::now));
|
||||
createButton(_reasonViolence, Reason::Violence, tr::lng_report_reason_violence(tr::now));
|
||||
createButton(_reasonChildAbuse, Reason::ChildAbuse, tr::lng_report_reason_child_abuse(tr::now));
|
||||
createButton(_reasonPornography, Reason::Pornography, tr::lng_report_reason_pornography(tr::now));
|
||||
createButton(_reasonOther, Reason::Other, tr::lng_report_reason_other(tr::now));
|
||||
_reasonGroup->setChangedCallback([=](Reason value) {
|
||||
reasonChanged(value);
|
||||
});
|
||||
|
||||
updateMaxHeight();
|
||||
}
|
||||
|
||||
void ReportBox::resizeEvent(QResizeEvent *e) {
|
||||
BoxContent::resizeEvent(e);
|
||||
|
||||
_reasonSpam->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), st::boxOptionListPadding.top() + _reasonSpam->getMargins().top());
|
||||
_reasonFake->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _reasonSpam->bottomNoMargins() + st::boxOptionListSkip);
|
||||
_reasonViolence->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _reasonFake->bottomNoMargins() + st::boxOptionListSkip);
|
||||
_reasonChildAbuse->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _reasonViolence->bottomNoMargins() + st::boxOptionListSkip);
|
||||
_reasonPornography->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _reasonChildAbuse->bottomNoMargins() + st::boxOptionListSkip);
|
||||
_reasonOther->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _reasonPornography->bottomNoMargins() + st::boxOptionListSkip);
|
||||
|
||||
if (_reasonOtherText) {
|
||||
_reasonOtherText->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left() - st::defaultInputField.textMargins.left(), _reasonOther->bottomNoMargins() + st::newGroupDescriptionPadding.top());
|
||||
}
|
||||
}
|
||||
|
||||
void ReportBox::reasonChanged(Reason reason) {
|
||||
if (reason == Reason::Other) {
|
||||
if (!_reasonOtherText) {
|
||||
_reasonOtherText.create(
|
||||
this,
|
||||
st::profileReportReasonOther,
|
||||
Ui::InputField::Mode::MultiLine,
|
||||
tr::lng_report_reason_description());
|
||||
_reasonOtherText->show();
|
||||
_reasonOtherText->setSubmitSettings(Core::App().settings().sendSubmitWay());
|
||||
_reasonOtherText->setMaxLength(kReportReasonLengthMax);
|
||||
_reasonOtherText->resize(width() - (st::boxPadding.left() + st::boxOptionListPadding.left() + st::boxPadding.right()), _reasonOtherText->height());
|
||||
|
||||
updateMaxHeight();
|
||||
connect(_reasonOtherText, &Ui::InputField::resized, [=] { reasonResized(); });
|
||||
connect(_reasonOtherText, &Ui::InputField::submitted, [=] { report(); });
|
||||
connect(_reasonOtherText, &Ui::InputField::cancelled, [=] { closeBox(); });
|
||||
}
|
||||
_reasonOtherText->setFocusFast();
|
||||
} else if (_reasonOtherText) {
|
||||
_reasonOtherText.destroy();
|
||||
updateMaxHeight();
|
||||
}
|
||||
}
|
||||
|
||||
void ReportBox::setInnerFocus() {
|
||||
if (_reasonOtherText) {
|
||||
_reasonOtherText->setFocusFast();
|
||||
} else {
|
||||
setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
void ReportBox::reasonResized() {
|
||||
updateMaxHeight();
|
||||
update();
|
||||
}
|
||||
|
||||
void ReportBox::report() {
|
||||
if (_requestId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto text = _reasonOtherText
|
||||
? _reasonOtherText->getLastText().trimmed()
|
||||
: QString();
|
||||
if (_reasonOtherText && text.isEmpty()) {
|
||||
_reasonOtherText->showError();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto reason = [&] {
|
||||
switch (_reasonGroup->value()) {
|
||||
case Reason::Spam: return MTP_inputReportReasonSpam();
|
||||
case Reason::Fake: return MTP_inputReportReasonFake();
|
||||
case Reason::Violence: return MTP_inputReportReasonViolence();
|
||||
case Reason::ChildAbuse: return MTP_inputReportReasonChildAbuse();
|
||||
case Reason::Pornography: return MTP_inputReportReasonPornography();
|
||||
case Reason::Other: return MTP_inputReportReasonOther();
|
||||
}
|
||||
Unexpected("Bad reason group value.");
|
||||
}();
|
||||
if (_ids) {
|
||||
auto ids = QVector<MTPint>();
|
||||
for (const auto &fullId : *_ids) {
|
||||
ids.push_back(MTP_int(fullId.msg));
|
||||
}
|
||||
_requestId = _api.request(MTPmessages_Report(
|
||||
_peer->input,
|
||||
MTP_vector<MTPint>(ids),
|
||||
reason,
|
||||
MTP_string(text)
|
||||
)).done([=](const MTPBool &result) {
|
||||
reportDone(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
reportFail(error);
|
||||
}).send();
|
||||
} else {
|
||||
_requestId = _api.request(MTPaccount_ReportPeer(
|
||||
_peer->input,
|
||||
reason,
|
||||
MTP_string(text)
|
||||
)).done([=](const MTPBool &result) {
|
||||
reportDone(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
reportFail(error);
|
||||
}).send();
|
||||
}
|
||||
}
|
||||
|
||||
void ReportBox::reportDone(const MTPBool &result) {
|
||||
_requestId = 0;
|
||||
Ui::Toast::Show(tr::lng_report_thanks(tr::now));
|
||||
closeBox();
|
||||
}
|
||||
|
||||
void ReportBox::reportFail(const RPCError &error) {
|
||||
_requestId = 0;
|
||||
if (_reasonOtherText) {
|
||||
_reasonOtherText->showError();
|
||||
}
|
||||
}
|
||||
|
||||
void ReportBox::updateMaxHeight() {
|
||||
const auto buttonsCount = 6;
|
||||
auto newHeight = st::boxOptionListPadding.top() + _reasonSpam->getMargins().top() + buttonsCount * _reasonSpam->heightNoMargins() + (buttonsCount - 1) * st::boxOptionListSkip + _reasonSpam->getMargins().bottom() + st::boxOptionListPadding.bottom();
|
||||
|
||||
if (_reasonOtherText) {
|
||||
newHeight += st::newGroupDescriptionPadding.top() + _reasonOtherText->height() + st::newGroupDescriptionPadding.bottom();
|
||||
}
|
||||
setDimensions(st::boxWidth, newHeight);
|
||||
}
|
||||
|
||||
void BlockSenderFromRepliesBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<Window::SessionController*> controller,
|
||||
FullMsgId id) {
|
||||
const auto item = controller->session().data().message(id);
|
||||
Assert(item != nullptr);
|
||||
|
||||
PeerMenuBlockUserBox(
|
||||
box,
|
||||
&controller->window(),
|
||||
item->senderOriginal(),
|
||||
true,
|
||||
Window::ClearReply{ id });
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "boxes/abstract_box.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "mtproto/sender.h"
|
||||
|
||||
namespace Window {
|
||||
class SessionController;
|
||||
} // namespace Window
|
||||
|
||||
namespace Ui {
|
||||
template <typename Enum>
|
||||
class RadioenumGroup;
|
||||
template <typename Enum>
|
||||
class Radioenum;
|
||||
class InputField;
|
||||
} // namespace Ui
|
||||
|
||||
class ReportBox final : public Ui::BoxContent {
|
||||
public:
|
||||
ReportBox(QWidget*, not_null<PeerData*> peer);
|
||||
ReportBox(QWidget*, not_null<PeerData*> peer, MessageIdsList ids);
|
||||
|
||||
protected:
|
||||
void prepare() override;
|
||||
void setInnerFocus() override;
|
||||
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
||||
private:
|
||||
enum class Reason {
|
||||
Spam,
|
||||
Fake,
|
||||
Violence,
|
||||
ChildAbuse,
|
||||
Pornography,
|
||||
Other,
|
||||
};
|
||||
void reasonChanged(Reason reason);
|
||||
void reasonResized();
|
||||
void updateMaxHeight();
|
||||
void report();
|
||||
|
||||
void reportDone(const MTPBool &result);
|
||||
void reportFail(const RPCError &error);
|
||||
|
||||
const not_null<PeerData*> _peer;
|
||||
MTP::Sender _api;
|
||||
std::optional<MessageIdsList> _ids;
|
||||
|
||||
std::shared_ptr<Ui::RadioenumGroup<Reason>> _reasonGroup;
|
||||
object_ptr<Ui::Radioenum<Reason>> _reasonSpam = { nullptr };
|
||||
object_ptr<Ui::Radioenum<Reason>> _reasonFake = { nullptr };
|
||||
object_ptr<Ui::Radioenum<Reason>> _reasonViolence = { nullptr };
|
||||
object_ptr<Ui::Radioenum<Reason>> _reasonChildAbuse = { nullptr };
|
||||
object_ptr<Ui::Radioenum<Reason>> _reasonPornography = { nullptr };
|
||||
object_ptr<Ui::Radioenum<Reason>> _reasonOther = { nullptr };
|
||||
object_ptr<Ui::InputField> _reasonOtherText = { nullptr };
|
||||
|
||||
mtpRequestId _requestId = 0;
|
||||
|
||||
};
|
||||
|
||||
void BlockSenderFromRepliesBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<Window::SessionController*> controller,
|
||||
FullMsgId id);
|
|
@ -185,8 +185,9 @@ constexpr auto EndClientMsgId = MsgId(-0x40000000);
|
|||
constexpr auto ShowAtTheEndMsgId = MsgId(-0x40000000);
|
||||
constexpr auto SwitchAtTopMsgId = MsgId(-0x3FFFFFFF);
|
||||
constexpr auto ShowAtProfileMsgId = MsgId(-0x3FFFFFFE);
|
||||
constexpr auto ShowAndStartBotMsgId = MsgId(-0x3FFFFFD);
|
||||
constexpr auto ShowAtGameShareMsgId = MsgId(-0x3FFFFFC);
|
||||
constexpr auto ShowAndStartBotMsgId = MsgId(-0x3FFFFFFD);
|
||||
constexpr auto ShowAtGameShareMsgId = MsgId(-0x3FFFFFFC);
|
||||
constexpr auto ShowForChooseMessagesMsgId = MsgId(-0x3FFFFFFB);
|
||||
constexpr auto ServerMaxMsgId = MsgId(0x3FFFFFFF);
|
||||
constexpr auto ShowAtUnreadMsgId = MsgId(0);
|
||||
constexpr inline bool IsClientMsgId(MsgId id) {
|
||||
|
|
|
@ -26,6 +26,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/image/image.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/text/text_options.h"
|
||||
#include "ui/boxes/report_box.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/controls/delete_message_context_action.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
|
@ -35,7 +37,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/window_controller.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "boxes/report_box.h"
|
||||
#include "boxes/sticker_set_box.h"
|
||||
#include "chat_helpers/message_field.h"
|
||||
#include "history/history_widget.h"
|
||||
|
@ -1058,15 +1059,13 @@ void HistoryInner::mouseActionStart(const QPoint &screenPos, Qt::MouseButton but
|
|||
|
||||
if (ClickHandler::getPressed()) {
|
||||
_mouseAction = MouseAction::PrepareDrag;
|
||||
} else if (!_selected.empty()) {
|
||||
if (_selected.cbegin()->second == FullSelection) {
|
||||
if (_dragStateItem
|
||||
&& _selected.find(_dragStateItem) != _selected.cend()
|
||||
&& App::hoveredItem()) {
|
||||
_mouseAction = MouseAction::PrepareDrag; // start items drag
|
||||
} else if (!_pressWasInactive) {
|
||||
_mouseAction = MouseAction::PrepareSelect; // start items select
|
||||
}
|
||||
} else if (inSelectionMode()) {
|
||||
if (_dragStateItem
|
||||
&& _selected.find(_dragStateItem) != _selected.cend()
|
||||
&& App::hoveredItem()) {
|
||||
_mouseAction = MouseAction::PrepareDrag; // start items drag
|
||||
} else if (!_pressWasInactive) {
|
||||
_mouseAction = MouseAction::PrepareSelect; // start items select
|
||||
}
|
||||
}
|
||||
if (_mouseAction == MouseAction::None && mouseActionView) {
|
||||
|
@ -1319,7 +1318,10 @@ void HistoryInner::mouseActionFinish(
|
|||
} else if (_mouseActionItem) {
|
||||
// if we are in selecting items mode perhaps we want to
|
||||
// toggle selection instead of activating the pressed link
|
||||
if (_mouseAction == MouseAction::PrepareDrag && !_pressWasInactive && !_selected.empty() && _selected.cbegin()->second == FullSelection && button != Qt::RightButton) {
|
||||
if (_mouseAction == MouseAction::PrepareDrag
|
||||
&& !_pressWasInactive
|
||||
&& inSelectionMode()
|
||||
&& button != Qt::RightButton) {
|
||||
if (const auto view = _mouseActionItem->mainView()) {
|
||||
if (const auto media = view->media()) {
|
||||
if (media->toggleSelectionByHandlerClick(activated)) {
|
||||
|
@ -1357,8 +1359,7 @@ void HistoryInner::mouseActionFinish(
|
|||
}
|
||||
if ((_mouseAction == MouseAction::PrepareSelect)
|
||||
&& !_pressWasInactive
|
||||
&& !_selected.empty()
|
||||
&& (_selected.cbegin()->second == FullSelection)) {
|
||||
&& inSelectionMode()) {
|
||||
changeSelectionAsGroup(
|
||||
&_selected,
|
||||
_mouseActionItem,
|
||||
|
@ -1375,8 +1376,7 @@ void HistoryInner::mouseActionFinish(
|
|||
} else if ((i == _selected.cend())
|
||||
&& !_dragStateItem->serviceMsg()
|
||||
&& (_dragStateItem->id > 0)
|
||||
&& !_selected.empty()
|
||||
&& _selected.cbegin()->second == FullSelection) {
|
||||
&& inSelectionMode()) {
|
||||
if (_selected.size() < MaxSelectedItems) {
|
||||
_selected.emplace(_dragStateItem, FullSelection);
|
||||
repaintItem(_mouseActionItem);
|
||||
|
@ -2519,6 +2519,8 @@ bool HistoryInner::inSelectionMode() const {
|
|||
&& _dragSelFrom
|
||||
&& _dragSelTo) {
|
||||
return true;
|
||||
} else if (_chooseForReportReason.has_value()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -2993,6 +2995,14 @@ int HistoryInner::historyDrawTop() const {
|
|||
return (top >= 0) ? (top + _historySkipHeight) : -1;
|
||||
}
|
||||
|
||||
void HistoryInner::setChooseReportReason(Ui::ReportReason reason) {
|
||||
_chooseForReportReason = reason;
|
||||
}
|
||||
|
||||
void HistoryInner::clearChooseReportReason() {
|
||||
_chooseForReportReason = std::nullopt;
|
||||
}
|
||||
|
||||
// -1 if should not be visible, -2 if bad history()
|
||||
int HistoryInner::itemTop(const HistoryItem *item) const {
|
||||
if (!item) {
|
||||
|
@ -3226,25 +3236,24 @@ void HistoryInner::deleteAsGroup(FullMsgId itemId) {
|
|||
}
|
||||
|
||||
void HistoryInner::reportItem(FullMsgId itemId) {
|
||||
Ui::show(Box<ReportBox>(_peer, MessageIdsList(1, itemId)));
|
||||
HistoryView::ShowReportItemsBox(_peer, { 1, itemId });
|
||||
}
|
||||
|
||||
void HistoryInner::reportAsGroup(FullMsgId itemId) {
|
||||
if (const auto item = session().data().message(itemId)) {
|
||||
const auto group = session().data().groups().find(item);
|
||||
if (!group) {
|
||||
return reportItem(itemId);
|
||||
}
|
||||
Ui::show(Box<ReportBox>(
|
||||
HistoryView::ShowReportItemsBox(
|
||||
_peer,
|
||||
session().data().itemsToIds(group->items)));
|
||||
(group
|
||||
? session().data().itemsToIds(group->items)
|
||||
: MessageIdsList{ 1, itemId }));
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryInner::blockSenderItem(FullMsgId itemId) {
|
||||
if (const auto item = session().data().message(itemId)) {
|
||||
Ui::show(Box(
|
||||
BlockSenderFromRepliesBox,
|
||||
Window::BlockSenderFromRepliesBox,
|
||||
_controller,
|
||||
itemId));
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ class SessionController;
|
|||
|
||||
namespace Ui {
|
||||
class PopupMenu;
|
||||
enum class ReportReason;
|
||||
} // namespace Ui
|
||||
|
||||
class HistoryWidget;
|
||||
|
@ -111,6 +112,9 @@ public:
|
|||
int historyTop() const;
|
||||
int historyDrawTop() const;
|
||||
|
||||
void setChooseReportReason(Ui::ReportReason reason);
|
||||
void clearChooseReportReason();
|
||||
|
||||
// -1 if should not be visible, -2 if bad history()
|
||||
int itemTop(const HistoryItem *item) const;
|
||||
int itemTop(const Element *view) const;
|
||||
|
@ -312,6 +316,7 @@ private:
|
|||
void deleteAsGroup(FullMsgId itemId);
|
||||
void reportItem(FullMsgId itemId);
|
||||
void reportAsGroup(FullMsgId itemId);
|
||||
void reportItems(MessageIdsList ids);
|
||||
void blockSenderItem(FullMsgId itemId);
|
||||
void blockSenderAsGroup(FullMsgId itemId);
|
||||
void copySelectedText();
|
||||
|
@ -350,6 +355,7 @@ private:
|
|||
|
||||
style::cursor _cursor = style::cur_default;
|
||||
SelectedItems _selected;
|
||||
std::optional<Ui::ReportReason> _chooseForReportReason;
|
||||
|
||||
base::flat_set<not_null<const HistoryItem*>> _animatedStickersPlayed;
|
||||
base::flat_map<
|
||||
|
|
|
@ -73,6 +73,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/history_view_webpage_preview.h"
|
||||
#include "history/view/history_view_top_bar_widget.h"
|
||||
#include "history/view/history_view_contact_status.h"
|
||||
#include "history/view/history_view_context_menu.h"
|
||||
#include "history/view/history_view_pinned_tracker.h"
|
||||
#include "history/view/history_view_pinned_section.h"
|
||||
#include "history/view/history_view_pinned_bar.h"
|
||||
|
@ -102,6 +103,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "core/application.h"
|
||||
#include "apiwrap.h"
|
||||
#include "base/qthelp_regex.h"
|
||||
#include "ui/boxes/report_box.h"
|
||||
#include "ui/chat/pinned_bar.h"
|
||||
#include "ui/chat/group_call_bar.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
|
@ -111,6 +113,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "main/main_session_settings.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/window_slide_animation.h"
|
||||
#include "window/window_peer_menu.h"
|
||||
|
@ -196,6 +199,7 @@ HistoryWidget::HistoryWidget(
|
|||
this,
|
||||
tr::lng_channel_mute(tr::now).toUpper(),
|
||||
st::historyComposeButton)
|
||||
, _reportMessages(this, QString(), st::historyComposeButton)
|
||||
, _attachToggle(this, st::historyAttach)
|
||||
, _tabbedSelectorToggle(this, st::historyAttachEmoji)
|
||||
, _botKeyboardShow(this, st::historyBotKeyboardShow)
|
||||
|
@ -242,6 +246,7 @@ HistoryWidget::HistoryWidget(
|
|||
_botStart->addClickHandler([=] { sendBotStartCommand(); });
|
||||
_joinChannel->addClickHandler([=] { joinChannel(); });
|
||||
_muteUnmute->addClickHandler([=] { toggleMuteUnmute(); });
|
||||
_reportMessages->addClickHandler([=] { reportSelectedMessages(); });
|
||||
connect(
|
||||
_field,
|
||||
&Ui::InputField::submitted,
|
||||
|
@ -373,6 +378,7 @@ HistoryWidget::HistoryWidget(
|
|||
_botStart->hide();
|
||||
_joinChannel->hide();
|
||||
_muteUnmute->hide();
|
||||
_reportMessages->hide();
|
||||
|
||||
initVoiceRecordBar();
|
||||
|
||||
|
@ -687,6 +693,10 @@ HistoryWidget::HistoryWidget(
|
|||
) | rpl::start_with_next([=] {
|
||||
clearSelected();
|
||||
}, _topBar->lifetime());
|
||||
_topBar->cancelChooseForReportRequest(
|
||||
) | rpl::start_with_next([=] {
|
||||
setChooseReportMessagesDetails({}, nullptr);
|
||||
}, _topBar->lifetime());
|
||||
|
||||
session().api().sendActions(
|
||||
) | rpl::filter([=](const Api::SendAction &action) {
|
||||
|
@ -1743,6 +1753,9 @@ void HistoryWidget::showHistory(
|
|||
if (startBot) {
|
||||
showAtMsgId = ShowAtTheEndMsgId;
|
||||
}
|
||||
if (showAtMsgId != ShowForChooseMessagesMsgId) {
|
||||
_chooseForReport = nullptr;
|
||||
}
|
||||
|
||||
clearHighlightMessages();
|
||||
hideInfoTooltip(anim::type::instant);
|
||||
|
@ -1753,7 +1766,17 @@ void HistoryWidget::showHistory(
|
|||
if (showAtMsgId == ShowAtUnreadMsgId
|
||||
&& insideJumpToEndInsteadOfToUnread()) {
|
||||
showAtMsgId = ShowAtTheEndMsgId;
|
||||
} else if (showAtMsgId == ShowForChooseMessagesMsgId) {
|
||||
if (_chooseForReport) {
|
||||
_chooseForReport->active = true;
|
||||
_list->setChooseReportReason(_chooseForReport->reason);
|
||||
updateControlsVisibility();
|
||||
updateControlsGeometry();
|
||||
updateTopBarChooseForReport();
|
||||
}
|
||||
return;
|
||||
}
|
||||
_list->clearChooseReportReason();
|
||||
if (!IsServerMsgId(showAtMsgId)
|
||||
&& !IsServerMsgId(-showAtMsgId)) {
|
||||
// To end or to unread.
|
||||
|
@ -1918,6 +1941,12 @@ void HistoryWidget::showHistory(
|
|||
|
||||
refreshTopBarActiveChat();
|
||||
updateTopBarSelection();
|
||||
if (showAtMsgId == ShowForChooseMessagesMsgId) {
|
||||
showAtMsgId = ShowAtUnreadMsgId;
|
||||
if (_chooseForReport) {
|
||||
_chooseForReport->active = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (_channel) {
|
||||
updateNotifyControls();
|
||||
|
@ -1944,6 +1973,11 @@ void HistoryWidget::showHistory(
|
|||
object_ptr<HistoryInner>(this, _scroll, controller(), _history));
|
||||
_list->show();
|
||||
|
||||
if (_chooseForReport && _chooseForReport->active) {
|
||||
_list->setChooseReportReason(_chooseForReport->reason);
|
||||
}
|
||||
updateTopBarChooseForReport();
|
||||
|
||||
_updateHistoryItems.cancel();
|
||||
|
||||
setupPinnedTracker();
|
||||
|
@ -2168,8 +2202,18 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
if (_contactStatus) {
|
||||
_contactStatus->show();
|
||||
}
|
||||
if (!editingMessage() && (isBlocked() || isJoinChannel() || isMuteUnmute() || isBotStart())) {
|
||||
if (isBlocked()) {
|
||||
if (!editingMessage() && (isBlocked() || isJoinChannel() || isMuteUnmute() || isBotStart() || isReportMessages())) {
|
||||
if (isReportMessages()) {
|
||||
_unblock->hide();
|
||||
_joinChannel->hide();
|
||||
_muteUnmute->hide();
|
||||
_botStart->hide();
|
||||
if (_reportMessages->isHidden()) {
|
||||
_reportMessages->clearState();
|
||||
_reportMessages->show();
|
||||
}
|
||||
} else if (isBlocked()) {
|
||||
_reportMessages->hide();
|
||||
_joinChannel->hide();
|
||||
_muteUnmute->hide();
|
||||
_botStart->hide();
|
||||
|
@ -2178,6 +2222,7 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
_unblock->show();
|
||||
}
|
||||
} else if (isJoinChannel()) {
|
||||
_reportMessages->hide();
|
||||
_unblock->hide();
|
||||
_muteUnmute->hide();
|
||||
_botStart->hide();
|
||||
|
@ -2186,6 +2231,7 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
_joinChannel->show();
|
||||
}
|
||||
} else if (isMuteUnmute()) {
|
||||
_reportMessages->hide();
|
||||
_unblock->hide();
|
||||
_joinChannel->hide();
|
||||
_botStart->hide();
|
||||
|
@ -2194,6 +2240,7 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
_muteUnmute->show();
|
||||
}
|
||||
} else if (isBotStart()) {
|
||||
_reportMessages->hide();
|
||||
_unblock->hide();
|
||||
_joinChannel->hide();
|
||||
_muteUnmute->hide();
|
||||
|
@ -2244,6 +2291,7 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
_botStart->hide();
|
||||
_joinChannel->hide();
|
||||
_muteUnmute->hide();
|
||||
_reportMessages->hide();
|
||||
_send->show();
|
||||
updateSendButtonType();
|
||||
|
||||
|
@ -2303,6 +2351,7 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
_botStart->hide();
|
||||
_joinChannel->hide();
|
||||
_muteUnmute->hide();
|
||||
_reportMessages->hide();
|
||||
_attachToggle->hide();
|
||||
if (_silent) {
|
||||
_silent->hide();
|
||||
|
@ -3268,6 +3317,24 @@ void HistoryWidget::toggleMuteUnmute() {
|
|||
session().data().updateNotifySettings(_peer, muteForSeconds);
|
||||
}
|
||||
|
||||
void HistoryWidget::reportSelectedMessages() {
|
||||
if (!_list || !_chooseForReport || !_list->getSelectionState().count) {
|
||||
return;
|
||||
}
|
||||
const auto ids = _list->getSelectedItems();
|
||||
const auto peer = _peer;
|
||||
const auto reason = _chooseForReport->reason;
|
||||
const auto box = std::make_shared<QPointer<Ui::GenericBox>>();
|
||||
const auto send = [=](const QString &text) {
|
||||
HistoryView::SendReport(peer, reason, text, ids);
|
||||
controller()->clearChooseReportMessages();
|
||||
if (*box) {
|
||||
(*box)->closeBox();
|
||||
}
|
||||
};
|
||||
*box = controller()->window().show(Box(Ui::ReportDetailsBox, send));
|
||||
}
|
||||
|
||||
History *HistoryWidget::history() const {
|
||||
return _history;
|
||||
}
|
||||
|
@ -3706,6 +3773,10 @@ bool HistoryWidget::isBotStart() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool HistoryWidget::isReportMessages() const {
|
||||
return _peer && _chooseForReport && _chooseForReport->active;
|
||||
}
|
||||
|
||||
bool HistoryWidget::isBlocked() const {
|
||||
return _peer && _peer->isUser() && _peer->asUser()->isBlocked();
|
||||
}
|
||||
|
@ -3993,7 +4064,7 @@ void HistoryWidget::moveFieldControls() {
|
|||
|
||||
// _attachToggle --------- _inlineResults -------------------------------------- _tabbedPanel --------- _fieldBarCancel
|
||||
// (_attachDocument|_attachPhoto) _field (_ttlInfo) (_scheduled) (_silent|_cmdStart|_kbShow) (_kbHide|_tabbedSelectorToggle) _send
|
||||
// (_botStart|_unblock|_joinChannel|_muteUnmute)
|
||||
// (_botStart|_unblock|_joinChannel|_muteUnmute|_reportMessages)
|
||||
|
||||
auto buttonsBottom = bottom - _attachToggle->height();
|
||||
auto left = st::historySendRight;
|
||||
|
@ -4037,8 +4108,8 @@ void HistoryWidget::moveFieldControls() {
|
|||
_botStart->setGeometry(fullWidthButtonRect);
|
||||
_unblock->setGeometry(fullWidthButtonRect);
|
||||
_joinChannel->setGeometry(fullWidthButtonRect);
|
||||
|
||||
_muteUnmute->setGeometry(fullWidthButtonRect);
|
||||
_reportMessages->setGeometry(fullWidthButtonRect);
|
||||
}
|
||||
|
||||
void HistoryWidget::updateFieldSize() {
|
||||
|
@ -4406,13 +4477,19 @@ void HistoryWidget::handleHistoryChange(not_null<const History*> history) {
|
|||
const auto botStart = isBotStart();
|
||||
const auto joinChannel = isJoinChannel();
|
||||
const auto muteUnmute = isMuteUnmute();
|
||||
const auto reportMessages = isReportMessages();
|
||||
const auto update = false
|
||||
|| (_unblock->isHidden() == unblock)
|
||||
|| (!unblock && _botStart->isHidden() == botStart)
|
||||
|| (!unblock
|
||||
|| (_reportMessages->isHidden() == reportMessages)
|
||||
|| (!reportMessages && _unblock->isHidden() == unblock)
|
||||
|| (!reportMessages
|
||||
&& !unblock
|
||||
&& _botStart->isHidden() == botStart)
|
||||
|| (!reportMessages
|
||||
&& !unblock
|
||||
&& !botStart
|
||||
&& _joinChannel->isHidden() == joinChannel)
|
||||
|| (!unblock
|
||||
|| (!reportMessages
|
||||
&& !unblock
|
||||
&& !botStart
|
||||
&& !joinChannel
|
||||
&& _muteUnmute->isHidden() == muteUnmute);
|
||||
|
@ -4667,7 +4744,7 @@ void HistoryWidget::updateHistoryGeometry(
|
|||
if (_contactStatus) {
|
||||
newScrollHeight -= _contactStatus->height();
|
||||
}
|
||||
if (!editingMessage() && (isBlocked() || isBotStart() || isJoinChannel() || isMuteUnmute())) {
|
||||
if (!editingMessage() && (isBlocked() || isBotStart() || isJoinChannel() || isMuteUnmute() || isReportMessages())) {
|
||||
newScrollHeight -= _unblock->height();
|
||||
} else {
|
||||
if (editingMessage() || _canSendMessages) {
|
||||
|
@ -5427,6 +5504,28 @@ void HistoryWidget::checkMessagesTTL() {
|
|||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::setChooseReportMessagesDetails(
|
||||
Ui::ReportReason reason,
|
||||
Fn<void(MessageIdsList)> callback) {
|
||||
if (!callback) {
|
||||
const auto refresh = _chooseForReport && _chooseForReport->active;
|
||||
_chooseForReport = nullptr;
|
||||
if (_list) {
|
||||
_list->clearChooseReportReason();
|
||||
}
|
||||
if (refresh) {
|
||||
updateControlsVisibility();
|
||||
updateControlsGeometry();
|
||||
updateTopBarChooseForReport();
|
||||
}
|
||||
} else {
|
||||
_chooseForReport = std::make_unique<ChooseMessagesForReport>(
|
||||
ChooseMessagesForReport{
|
||||
.reason = reason,
|
||||
.callback = std::move(callback) });
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::refreshPinnedBarButton(bool many) {
|
||||
const auto close = !many;
|
||||
auto button = object_ptr<Ui::IconButton>(
|
||||
|
@ -6209,6 +6308,18 @@ MessageIdsList HistoryWidget::getSelectedItems() const {
|
|||
return _list ? _list->getSelectedItems() : MessageIdsList();
|
||||
}
|
||||
|
||||
void HistoryWidget::updateTopBarChooseForReport() {
|
||||
if (_chooseForReport && _chooseForReport->active) {
|
||||
_topBar->showChooseMessagesForReport(
|
||||
_chooseForReport->reason);
|
||||
} else {
|
||||
_topBar->clearChooseMessagesForReport();
|
||||
}
|
||||
updateTopBarSelection();
|
||||
updateControlsVisibility();
|
||||
updateControlsGeometry();
|
||||
}
|
||||
|
||||
void HistoryWidget::updateTopBarSelection() {
|
||||
if (!_list) {
|
||||
_topBar->showSelected(HistoryView::TopBarWidget::SelectedState {});
|
||||
|
@ -6216,8 +6327,25 @@ void HistoryWidget::updateTopBarSelection() {
|
|||
}
|
||||
|
||||
auto selectedState = _list->getSelectionState();
|
||||
_nonEmptySelection = (selectedState.count > 0) || selectedState.textSelected;
|
||||
_nonEmptySelection = (selectedState.count > 0)
|
||||
|| selectedState.textSelected;
|
||||
_topBar->showSelected(selectedState);
|
||||
|
||||
const auto transparent = Qt::WA_TransparentForMouseEvents;
|
||||
if (selectedState.count == 0) {
|
||||
_reportMessages->clearState();
|
||||
_reportMessages->setAttribute(transparent);
|
||||
_reportMessages->setColorOverride(st::windowSubTextFg->c);
|
||||
} else if (_reportMessages->testAttribute(transparent)) {
|
||||
_reportMessages->setAttribute(transparent, false);
|
||||
_reportMessages->setColorOverride(std::nullopt);
|
||||
}
|
||||
_reportMessages->setText(Ui::Text::Upper(selectedState.count
|
||||
? tr::lng_report_messages_count(
|
||||
tr::now,
|
||||
lt_count,
|
||||
selectedState.count)
|
||||
: tr::lng_report_messages_none(tr::now)));
|
||||
updateControlsVisibility();
|
||||
updateHistoryGeometry();
|
||||
if (!Ui::isLayerShown() && !Core::App().passcodeLocked()) {
|
||||
|
|
|
@ -68,6 +68,7 @@ class PinnedBar;
|
|||
class GroupCallBar;
|
||||
struct PreparedList;
|
||||
class SendFilesWay;
|
||||
enum class ReportReason;
|
||||
namespace Toast {
|
||||
class Instance;
|
||||
} // namespace Toast
|
||||
|
@ -141,6 +142,7 @@ public:
|
|||
|
||||
bool isItemCompletelyHidden(HistoryItem *item) const;
|
||||
void updateTopBarSelection();
|
||||
void updateTopBarChooseForReport();
|
||||
|
||||
void loadMessages();
|
||||
void loadMessagesDown();
|
||||
|
@ -230,6 +232,9 @@ public:
|
|||
void applyDraft(
|
||||
FieldHistoryAction fieldHistoryAction = FieldHistoryAction::Clear);
|
||||
void showHistory(const PeerId &peer, MsgId showAtMsgId, bool reload = false);
|
||||
void setChooseReportMessagesDetails(
|
||||
Ui::ReportReason reason,
|
||||
Fn<void(MessageIdsList)> callback);
|
||||
void clearAllLoadRequests();
|
||||
void clearDelayedShowAtRequest();
|
||||
void clearDelayedShowAt();
|
||||
|
@ -313,6 +318,11 @@ private:
|
|||
ScrollChangeType type;
|
||||
int value;
|
||||
};
|
||||
struct ChooseMessagesForReport {
|
||||
Ui::ReportReason reason = {};
|
||||
Fn<void(MessageIdsList)> callback;
|
||||
bool active = false;
|
||||
};
|
||||
enum class TextUpdateEvent {
|
||||
SaveDraft = (1 << 0),
|
||||
SendTyping = (1 << 1),
|
||||
|
@ -377,6 +387,7 @@ private:
|
|||
|
||||
[[nodiscard]] int computeMaxFieldHeight() const;
|
||||
void toggleMuteUnmute();
|
||||
void reportSelectedMessages();
|
||||
void toggleKeyboard(bool manual = true);
|
||||
void startBotCommand();
|
||||
void hidePinnedMessage();
|
||||
|
@ -572,6 +583,7 @@ private:
|
|||
bool isBlocked() const;
|
||||
bool isJoinChannel() const;
|
||||
bool isMuteUnmute() const;
|
||||
bool isReportMessages() const;
|
||||
bool updateCmdStartShown();
|
||||
void updateSendButtonType();
|
||||
bool showRecordButton() const;
|
||||
|
@ -687,6 +699,7 @@ private:
|
|||
object_ptr<Ui::FlatButton> _botStart;
|
||||
object_ptr<Ui::FlatButton> _joinChannel;
|
||||
object_ptr<Ui::FlatButton> _muteUnmute;
|
||||
object_ptr<Ui::FlatButton> _reportMessages;
|
||||
object_ptr<Ui::IconButton> _attachToggle;
|
||||
object_ptr<Ui::EmojiButton> _tabbedSelectorToggle;
|
||||
object_ptr<Ui::IconButton> _botKeyboardShow;
|
||||
|
@ -740,6 +753,7 @@ private:
|
|||
base::Timer _saveCloudDraftTimer;
|
||||
|
||||
base::weak_ptr<Ui::Toast::Instance> _topToast;
|
||||
std::unique_ptr<ChooseMessagesForReport> _chooseForReport;
|
||||
|
||||
object_ptr<Ui::PlainShadow> _topShadow;
|
||||
bool _inGrab = false;
|
||||
|
|
|
@ -24,11 +24,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/image/image.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/controls/delete_message_context_action.h"
|
||||
#include "ui/boxes/report_box.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "chat_helpers/send_context_menu.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "boxes/sticker_set_box.h"
|
||||
#include "boxes/report_box.h"
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_photo_media.h"
|
||||
#include "data/data_document.h"
|
||||
|
@ -41,6 +41,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "core/file_utilities.h"
|
||||
#include "base/platform/base_platform_info.h"
|
||||
#include "window/window_peer_menu.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "core/application.h"
|
||||
|
@ -782,13 +783,12 @@ void AddReportAction(
|
|||
const auto itemId = item->fullId();
|
||||
const auto callback = crl::guard(controller, [=] {
|
||||
if (const auto item = owner->message(itemId)) {
|
||||
const auto peer = item->history()->peer;
|
||||
const auto group = owner->groups().find(item);
|
||||
Ui::show(Box<ReportBox>(
|
||||
peer,
|
||||
ShowReportItemsBox(
|
||||
item->history()->peer,
|
||||
(group
|
||||
? owner->itemsToIds(group->items)
|
||||
: MessageIdsList(1, itemId))));
|
||||
: MessageIdsList{ 1, itemId }));
|
||||
}
|
||||
});
|
||||
menu->addAction(tr::lng_context_report_msg(tr::now), callback);
|
||||
|
@ -1051,4 +1051,105 @@ void AddPollActions(
|
|||
}
|
||||
}
|
||||
|
||||
void ShowReportItemsBox(not_null<PeerData*> peer, MessageIdsList ids) {
|
||||
const auto chosen = [=](Ui::ReportReason reason) {
|
||||
Ui::show(Box(Ui::ReportDetailsBox, [=](const QString &text) {
|
||||
SendReport(peer, reason, text, ids);
|
||||
Ui::hideLayer();
|
||||
}));
|
||||
};
|
||||
Ui::show(Box(
|
||||
Ui::ReportReasonBox,
|
||||
Ui::ReportSource::Message,
|
||||
chosen));
|
||||
}
|
||||
|
||||
void ShowReportPeerBox(
|
||||
not_null<Window::SessionController*> window,
|
||||
not_null<PeerData*> peer) {
|
||||
struct State {
|
||||
QPointer<Ui::GenericBox> reasonBox;
|
||||
QPointer<Ui::GenericBox> detailsBox;
|
||||
MessageIdsList ids;
|
||||
};
|
||||
const auto state = std::make_shared<State>();
|
||||
const auto chosen = [=](Ui::ReportReason reason) {
|
||||
const auto send = [=](const QString &text) {
|
||||
window->clearChooseReportMessages();
|
||||
SendReport(peer, reason, text, std::move(state->ids));
|
||||
if (const auto strong = state->reasonBox.data()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
if (const auto strong = state->detailsBox.data()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
};
|
||||
if (reason == Ui::ReportReason::Fake
|
||||
|| reason == Ui::ReportReason::Other) {
|
||||
state->ids = {};
|
||||
state->detailsBox = window->window().show(
|
||||
Box(Ui::ReportDetailsBox, send));
|
||||
return;
|
||||
}
|
||||
window->showChooseReportMessages(peer, reason, [=](
|
||||
MessageIdsList ids) {
|
||||
state->ids = std::move(ids);
|
||||
state->detailsBox = window->window().show(
|
||||
Box(Ui::ReportDetailsBox, send));
|
||||
});
|
||||
};
|
||||
state->reasonBox = window->window().show(Box(
|
||||
Ui::ReportReasonBox,
|
||||
(peer->isBroadcast()
|
||||
? Ui::ReportSource::Channel
|
||||
: peer->isUser()
|
||||
? Ui::ReportSource::Bot
|
||||
: Ui::ReportSource::Group),
|
||||
chosen));
|
||||
}
|
||||
|
||||
void SendReport(
|
||||
not_null<PeerData*> peer,
|
||||
Ui::ReportReason reason,
|
||||
const QString &comment,
|
||||
MessageIdsList ids) {
|
||||
const auto apiReason = [&] {
|
||||
using Reason = Ui::ReportReason;
|
||||
switch (reason) {
|
||||
case Reason::Spam: return MTP_inputReportReasonSpam();
|
||||
case Reason::Fake: return MTP_inputReportReasonFake();
|
||||
case Reason::Violence: return MTP_inputReportReasonViolence();
|
||||
case Reason::ChildAbuse: return MTP_inputReportReasonChildAbuse();
|
||||
case Reason::Pornography: return MTP_inputReportReasonPornography();
|
||||
case Reason::Other: return MTP_inputReportReasonOther();
|
||||
}
|
||||
Unexpected("Bad reason group value.");
|
||||
}();
|
||||
if (ids.empty()) {
|
||||
peer->session().api().request(MTPaccount_ReportPeer(
|
||||
peer->input,
|
||||
apiReason,
|
||||
MTP_string(comment)
|
||||
)).done([=](const MTPBool &result) {
|
||||
Ui::Toast::Show(tr::lng_report_thanks(tr::now));
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).send();
|
||||
} else {
|
||||
auto apiIds = QVector<MTPint>();
|
||||
apiIds.reserve(ids.size());
|
||||
for (const auto &fullId : ids) {
|
||||
apiIds.push_back(MTP_int(fullId.msg));
|
||||
}
|
||||
peer->session().api().request(MTPmessages_Report(
|
||||
peer->input,
|
||||
MTP_vector<MTPint>(apiIds),
|
||||
apiReason,
|
||||
MTP_string(comment)
|
||||
)).done([=](const MTPBool &result) {
|
||||
Ui::Toast::Show(tr::lng_report_thanks(tr::now));
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).send();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
@ -11,10 +11,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace Ui {
|
||||
class PopupMenu;
|
||||
enum class ReportReason;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Window {
|
||||
class SessionNavigation;
|
||||
class SessionController;
|
||||
} // namespace Main
|
||||
|
||||
namespace HistoryView {
|
||||
|
@ -55,4 +57,14 @@ void AddPollActions(
|
|||
not_null<HistoryItem*> item,
|
||||
Context context);
|
||||
|
||||
} // namespace
|
||||
void ShowReportItemsBox(not_null<PeerData*> peer, MessageIdsList ids);
|
||||
void ShowReportPeerBox(
|
||||
not_null<Window::SessionController*> window,
|
||||
not_null<PeerData*> peer);
|
||||
void SendReport(
|
||||
not_null<PeerData*> peer,
|
||||
Ui::ReportReason reason,
|
||||
const QString &comment,
|
||||
MessageIdsList ids = {});
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/dropdown_menu.h"
|
||||
#include "ui/effects/radial_animation.h"
|
||||
#include "ui/toasts/common_toasts.h"
|
||||
#include "ui/boxes/report_box.h" // Ui::ReportReason
|
||||
#include "ui/special_buttons.h"
|
||||
#include "ui/unread_badge.h"
|
||||
#include "ui/ui_utility.h"
|
||||
|
@ -63,6 +64,7 @@ TopBarWidget::TopBarWidget(
|
|||
, _sendNow(this, tr::lng_selected_send_now(), st::defaultActiveButton)
|
||||
, _delete(this, tr::lng_selected_delete(), st::defaultActiveButton)
|
||||
, _back(this, st::historyTopBarBack)
|
||||
, _cancelChoose(this, st::topBarCloseChoose)
|
||||
, _call(this, st::topBarCall)
|
||||
, _groupCall(this, st::topBarGroupCall)
|
||||
, _search(this, st::topBarSearch)
|
||||
|
@ -90,6 +92,8 @@ TopBarWidget::TopBarWidget(
|
|||
_menuToggle->setClickedCallback([=] { showMenu(); });
|
||||
_infoToggle->setClickedCallback([=] { toggleInfoSection(); });
|
||||
_back->addClickHandler([=] { backClicked(); });
|
||||
_cancelChoose->setClickedCallback(
|
||||
[=] { _cancelChooseForReport.fire({}); });
|
||||
|
||||
rpl::combine(
|
||||
_controller->activeChatValue(),
|
||||
|
@ -224,6 +228,34 @@ void TopBarWidget::groupCall() {
|
|||
}
|
||||
}
|
||||
|
||||
void TopBarWidget::showChooseMessagesForReport(Ui::ReportReason reason) {
|
||||
setChooseForReportReason(reason);
|
||||
}
|
||||
|
||||
void TopBarWidget::clearChooseMessagesForReport() {
|
||||
setChooseForReportReason(std::nullopt);
|
||||
}
|
||||
|
||||
void TopBarWidget::setChooseForReportReason(
|
||||
std::optional<Ui::ReportReason> reason) {
|
||||
if (_chooseForReportReason == reason) {
|
||||
return;
|
||||
}
|
||||
const auto wasNoReason = !_chooseForReportReason;
|
||||
_chooseForReportReason = reason;
|
||||
const auto nowNoReason = !_chooseForReportReason;
|
||||
updateControlsVisibility();
|
||||
updateControlsGeometry();
|
||||
update();
|
||||
if (wasNoReason != nowNoReason && _selectedCount > 0) {
|
||||
toggleSelectedControls(false);
|
||||
finishAnimating();
|
||||
}
|
||||
setCursor((nowNoReason && !_selectedCount)
|
||||
? style::cur_pointer
|
||||
: style::cur_default);
|
||||
}
|
||||
|
||||
void TopBarWidget::showMenu() {
|
||||
if (!_activeChat.key || _menu) {
|
||||
return;
|
||||
|
@ -318,8 +350,8 @@ void TopBarWidget::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
Painter p(this);
|
||||
|
||||
auto hasSelected = (_selectedCount > 0);
|
||||
auto selectedButtonsTop = countSelectedButtonsTop(_selectedShown.value(hasSelected ? 1. : 0.));
|
||||
auto selectedButtonsTop = countSelectedButtonsTop(
|
||||
_selectedShown.value(showSelectedActions() ? 1. : 0.));
|
||||
|
||||
p.fillRect(QRect(0, 0, width(), st::topBarHeight), st::topBarBg);
|
||||
if (selectedButtonsTop < 0) {
|
||||
|
@ -337,6 +369,34 @@ void TopBarWidget::paintTopBar(Painter &p) {
|
|||
auto statustop = st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height;
|
||||
auto availableWidth = width() - _rightTaken - nameleft;
|
||||
|
||||
if (_chooseForReportReason) {
|
||||
const auto text = [&] {
|
||||
using Reason = Ui::ReportReason;
|
||||
switch (*_chooseForReportReason) {
|
||||
case Reason::Spam: return tr::lng_report_reason_spam(tr::now);
|
||||
case Reason::Violence:
|
||||
return tr::lng_report_reason_violence(tr::now);
|
||||
case Reason::ChildAbuse:
|
||||
return tr::lng_report_reason_child_abuse(tr::now);
|
||||
case Reason::Pornography:
|
||||
return tr::lng_report_reason_pornography(tr::now);
|
||||
}
|
||||
Unexpected("reason in TopBarWidget::paintTopBar.");
|
||||
}();
|
||||
p.setPen(st::dialogsNameFg);
|
||||
p.setFont(st::semiboldFont);
|
||||
p.drawTextLeft(nameleft, nametop, width(), text);
|
||||
|
||||
p.setFont(st::dialogsTextFont);
|
||||
p.setPen(st::historyStatusFg);
|
||||
p.drawTextLeft(
|
||||
nameleft,
|
||||
statustop,
|
||||
width(),
|
||||
tr::lng_report_select_messages(tr::now));
|
||||
return;
|
||||
}
|
||||
|
||||
const auto history = _activeChat.key.history();
|
||||
const auto folder = _activeChat.key.folder();
|
||||
if (folder
|
||||
|
@ -476,7 +536,8 @@ QRect TopBarWidget::getMembersShowAreaGeometry() const {
|
|||
void TopBarWidget::mousePressEvent(QMouseEvent *e) {
|
||||
auto handleClick = (e->button() == Qt::LeftButton)
|
||||
&& (e->pos().y() < st::topBarHeight)
|
||||
&& (!_selectedCount);
|
||||
&& !_selectedCount
|
||||
&& !_chooseForReportReason;
|
||||
if (handleClick) {
|
||||
if (_animatingMode && _back->rect().contains(e->pos())) {
|
||||
backClicked();
|
||||
|
@ -610,14 +671,16 @@ void TopBarWidget::updateSearchVisibility() {
|
|||
const auto historyMode = (_activeChat.section == Section::History);
|
||||
const auto smallDialogsColumn = _activeChat.key.folder()
|
||||
&& (width() < _back->width() + _search->width());
|
||||
_search->setVisible(historyMode && !smallDialogsColumn);
|
||||
_search->setVisible(historyMode
|
||||
&& !smallDialogsColumn
|
||||
&& !_chooseForReportReason);
|
||||
}
|
||||
|
||||
void TopBarWidget::updateControlsGeometry() {
|
||||
if (!_activeChat.key) {
|
||||
return;
|
||||
}
|
||||
auto hasSelected = (_selectedCount > 0);
|
||||
auto hasSelected = showSelectedActions();
|
||||
auto selectedButtonsTop = countSelectedButtonsTop(_selectedShown.value(hasSelected ? 1. : 0.));
|
||||
auto otherButtonsTop = selectedButtonsTop + st::topBarHeight;
|
||||
auto buttonsLeft = st::topBarActionSkip + (Adaptive::OneColumn() ? 0 : st::lineWidth);
|
||||
|
@ -648,7 +711,11 @@ void TopBarWidget::updateControlsGeometry() {
|
|||
_delete->moveToLeft(buttonsLeft, selectedButtonsTop);
|
||||
_clear->moveToRight(st::topBarActionSkip, selectedButtonsTop);
|
||||
|
||||
if (_back->isHidden()) {
|
||||
if (!_cancelChoose->isHidden()) {
|
||||
_leftTaken = 0;
|
||||
_cancelChoose->moveToLeft(_leftTaken, otherButtonsTop);
|
||||
_leftTaken += _cancelChoose->width();
|
||||
} else if (_back->isHidden()) {
|
||||
_leftTaken = st::topBarArrowPadding.right();
|
||||
} else {
|
||||
const auto smallDialogsColumn = _activeChat.key.folder()
|
||||
|
@ -714,12 +781,13 @@ void TopBarWidget::updateControlsVisibility() {
|
|||
auto backVisible = Adaptive::OneColumn()
|
||||
|| !_controller->content()->stackIsEmpty()
|
||||
|| _activeChat.key.folder();
|
||||
_back->setVisible(backVisible);
|
||||
_back->setVisible(backVisible && !_chooseForReportReason);
|
||||
_cancelChoose->setVisible(_chooseForReportReason.has_value());
|
||||
if (_info) {
|
||||
_info->setVisible(Adaptive::OneColumn());
|
||||
_info->setVisible(Adaptive::OneColumn() && !_chooseForReportReason);
|
||||
}
|
||||
if (_unreadBadge) {
|
||||
_unreadBadge->show();
|
||||
_unreadBadge->setVisible(!_chooseForReportReason);
|
||||
}
|
||||
const auto section = _activeChat.section;
|
||||
const auto historyMode = (section == Section::History);
|
||||
|
@ -730,11 +798,12 @@ void TopBarWidget::updateControlsVisibility() {
|
|||
? hasPollsMenu
|
||||
: historyMode);
|
||||
updateSearchVisibility();
|
||||
_menuToggle->setVisible(hasMenu);
|
||||
_menuToggle->setVisible(hasMenu && !_chooseForReportReason);
|
||||
_infoToggle->setVisible(historyMode
|
||||
&& !_activeChat.key.folder()
|
||||
&& !Adaptive::OneColumn()
|
||||
&& _controller->canShowThirdSection());
|
||||
&& _controller->canShowThirdSection()
|
||||
&& !_chooseForReportReason);
|
||||
const auto callsEnabled = [&] {
|
||||
if (const auto peer = _activeChat.key.peer()) {
|
||||
if (const auto user = peer->asUser()) {
|
||||
|
@ -743,7 +812,9 @@ void TopBarWidget::updateControlsVisibility() {
|
|||
}
|
||||
return false;
|
||||
}();
|
||||
_call->setVisible(historyMode && callsEnabled);
|
||||
_call->setVisible(historyMode
|
||||
&& callsEnabled
|
||||
&& !_chooseForReportReason);
|
||||
const auto groupCallsEnabled = [&] {
|
||||
if (const auto peer = _activeChat.key.peer()) {
|
||||
if (peer->canManageGroupCall()) {
|
||||
|
@ -755,10 +826,12 @@ void TopBarWidget::updateControlsVisibility() {
|
|||
}
|
||||
return false;
|
||||
}();
|
||||
_groupCall->setVisible(historyMode && groupCallsEnabled);
|
||||
_groupCall->setVisible(historyMode
|
||||
&& groupCallsEnabled
|
||||
&& !_chooseForReportReason);
|
||||
|
||||
if (_membersShowArea) {
|
||||
_membersShowArea->show();
|
||||
_membersShowArea->setVisible(!_chooseForReportReason);
|
||||
}
|
||||
updateControlsGeometry();
|
||||
}
|
||||
|
@ -824,21 +897,29 @@ void TopBarWidget::showSelected(SelectedState state) {
|
|||
_canSendNow = canSendNow;
|
||||
updateControlsVisibility();
|
||||
}
|
||||
if (wasSelected != hasSelected) {
|
||||
if (wasSelected != hasSelected && !_chooseForReportReason) {
|
||||
setCursor(hasSelected ? style::cur_default : style::cur_pointer);
|
||||
|
||||
updateMembersShowArea();
|
||||
_selectedShown.start(
|
||||
[this] { selectedShowCallback(); },
|
||||
hasSelected ? 0. : 1.,
|
||||
hasSelected ? 1. : 0.,
|
||||
st::slideWrapDuration,
|
||||
anim::easeOutCirc);
|
||||
toggleSelectedControls(hasSelected);
|
||||
} else {
|
||||
updateControlsGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
void TopBarWidget::toggleSelectedControls(bool shown) {
|
||||
_selectedShown.start(
|
||||
[this] { selectedShowCallback(); },
|
||||
shown ? 0. : 1.,
|
||||
shown ? 1. : 0.,
|
||||
st::slideWrapDuration,
|
||||
anim::easeOutCirc);
|
||||
}
|
||||
|
||||
bool TopBarWidget::showSelectedActions() const {
|
||||
return (_selectedCount > 0) && !_chooseForReportReason;
|
||||
}
|
||||
|
||||
void TopBarWidget::selectedShowCallback() {
|
||||
updateControlsGeometry();
|
||||
update();
|
||||
|
|
|
@ -24,6 +24,7 @@ class IconButton;
|
|||
class DropdownMenu;
|
||||
class UnreadBadge;
|
||||
class InfiniteRadialAnimation;
|
||||
enum class ReportReason;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Window {
|
||||
|
@ -66,6 +67,9 @@ public:
|
|||
SendActionPainter *sendAction);
|
||||
void setCustomTitle(const QString &title);
|
||||
|
||||
void showChooseMessagesForReport(Ui::ReportReason reason);
|
||||
void clearChooseMessagesForReport();
|
||||
|
||||
rpl::producer<> forwardSelectionRequest() const {
|
||||
return _forwardSelection.events();
|
||||
}
|
||||
|
@ -78,6 +82,9 @@ public:
|
|||
rpl::producer<> clearSelectionRequest() const {
|
||||
return _clearSelection.events();
|
||||
}
|
||||
rpl::producer<> cancelChooseForReportRequest() const {
|
||||
return _cancelChooseForReport.events();
|
||||
}
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
@ -126,6 +133,9 @@ private:
|
|||
|
||||
void refreshUnreadBadge();
|
||||
void updateUnreadBadge();
|
||||
void setChooseForReportReason(std::optional<Ui::ReportReason> reason);
|
||||
void toggleSelectedControls(bool shown);
|
||||
[[nodiscard]] bool showSelectedActions() const;
|
||||
|
||||
const not_null<Window::SessionController*> _controller;
|
||||
ActiveChat _activeChat;
|
||||
|
@ -143,6 +153,7 @@ private:
|
|||
object_ptr<Ui::RoundButton> _forward, _sendNow, _delete;
|
||||
|
||||
object_ptr<Ui::IconButton> _back;
|
||||
object_ptr<Ui::IconButton> _cancelChoose;
|
||||
object_ptr<Ui::UnreadBadge> _unreadBadge = { nullptr };
|
||||
object_ptr<Ui::AbstractButton> _info = { nullptr };
|
||||
|
||||
|
@ -164,6 +175,7 @@ private:
|
|||
std::unique_ptr<Ui::InfiniteRadialAnimation> _connecting;
|
||||
|
||||
SendActionPainter *_sendAction = nullptr;
|
||||
std::optional<Ui::ReportReason> _chooseForReportReason;
|
||||
|
||||
base::Timer _onlineUpdater;
|
||||
|
||||
|
@ -171,6 +183,7 @@ private:
|
|||
rpl::event_stream<> _sendNowSelection;
|
||||
rpl::event_stream<> _deleteSelection;
|
||||
rpl::event_stream<> _clearSelection;
|
||||
rpl::event_stream<> _cancelChooseForReport;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -749,6 +749,13 @@ topBarSearch: IconButton {
|
|||
color: windowBgOver;
|
||||
}
|
||||
}
|
||||
topBarCloseChoose: IconButton(topBarSearch) {
|
||||
width: 56px;
|
||||
icon: icon {{ "info_close", boxTitleCloseFg }};
|
||||
iconOver: icon {{ "info_close", boxTitleCloseFgOver }};
|
||||
iconPosition: point(10px, -1px);
|
||||
rippleAreaPosition: point(7px, 7px);
|
||||
}
|
||||
topBarSkip: -5px;
|
||||
topBarCallSkip: -1px;
|
||||
topBarMenuToggle: IconButton(topBarSearch) {
|
||||
|
|
|
@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/box_content_divider.h"
|
||||
#include "ui/boxes/report_box.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/text/text_utilities.h" // Ui::Text::ToUpper
|
||||
|
@ -29,7 +30,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/peer_list_box.h"
|
||||
#include "boxes/peer_list_controllers.h"
|
||||
#include "boxes/add_contact_box.h"
|
||||
#include "boxes/report_box.h"
|
||||
#include "boxes/peers/edit_contact_box.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "info/info_controller.h"
|
||||
|
@ -586,11 +586,14 @@ void ActionsFiller::addBotCommandActions(not_null<UserData*> user) {
|
|||
|
||||
void ActionsFiller::addReportAction() {
|
||||
const auto peer = _peer;
|
||||
const auto report = [=] {
|
||||
|
||||
};
|
||||
AddActionButton(
|
||||
_wrap,
|
||||
tr::lng_profile_report(),
|
||||
rpl::single(true),
|
||||
[=] { Ui::show(Box<ReportBox>(peer)); },
|
||||
report,
|
||||
st::infoBlockButton);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/abstract_box.h"
|
||||
#include "boxes/add_contact_box.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "boxes/report_box.h"
|
||||
#include "mainwidget.h"
|
||||
#include "main/main_session.h"
|
||||
#include "apiwrap.h"
|
||||
|
|
|
@ -1414,6 +1414,18 @@ void MainWidget::ctrlEnterSubmitUpdated() {
|
|||
_history->updateFieldSubmitSettings();
|
||||
}
|
||||
|
||||
void MainWidget::showChooseReportMessages(
|
||||
not_null<PeerData*> peer,
|
||||
Ui::ReportReason reason,
|
||||
Fn<void(MessageIdsList)> done) {
|
||||
_history->setChooseReportMessagesDetails(reason, std::move(done));
|
||||
ui_showPeerHistory(peer->id, SectionShow(), ShowForChooseMessagesMsgId);
|
||||
}
|
||||
|
||||
void MainWidget::clearChooseReportMessages() {
|
||||
_history->setChooseReportMessagesDetails({}, nullptr);
|
||||
}
|
||||
|
||||
void MainWidget::ui_showPeerHistory(
|
||||
PeerId peerId,
|
||||
const SectionShow ¶ms,
|
||||
|
|
|
@ -65,6 +65,7 @@ namespace Ui {
|
|||
class ResizeArea;
|
||||
class PlainShadow;
|
||||
class DropdownMenu;
|
||||
enum class ReportReason;
|
||||
template <typename Widget>
|
||||
class SlideWrap;
|
||||
} // namespace Ui
|
||||
|
@ -210,6 +211,12 @@ public:
|
|||
|
||||
void searchInChat(Dialogs::Key chat);
|
||||
|
||||
void showChooseReportMessages(
|
||||
not_null<PeerData*> peer,
|
||||
Ui::ReportReason reason,
|
||||
Fn<void(MessageIdsList)> done);
|
||||
void clearChooseReportMessages();
|
||||
|
||||
void ui_showPeerHistory(
|
||||
PeerId peer,
|
||||
const SectionShow ¶ms,
|
||||
|
|
93
Telegram/SourceFiles/ui/boxes/report_box.cpp
Normal file
93
Telegram/SourceFiles/ui/boxes/report_box.cpp
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "ui/boxes/report_box.h"
|
||||
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_profile.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
constexpr auto kReportReasonLengthMax = 512;
|
||||
|
||||
using Source = ReportSource;
|
||||
using Reason = ReportReason;
|
||||
|
||||
} // namespace
|
||||
|
||||
void ReportReasonBox(
|
||||
not_null<GenericBox*> box,
|
||||
ReportSource source,
|
||||
Fn<void(Reason)> done) {
|
||||
box->setTitle([&] {
|
||||
switch (source) {
|
||||
case Source::Message: return tr::lng_report_message_title();
|
||||
case Source::Channel: return tr::lng_report_title();
|
||||
case Source::Group: return tr::lng_report_group_title();
|
||||
case Source::Bot: return tr::lng_report_bot_title();
|
||||
}
|
||||
Unexpected("'source' in ReportReasonBox.");
|
||||
}());
|
||||
const auto add = [&](Reason reason, tr::phrase<> text) {
|
||||
const auto layout = box->verticalLayout();
|
||||
const auto button = layout->add(
|
||||
object_ptr<Ui::SettingsButton>(layout, text()));
|
||||
button->setClickedCallback([=] {
|
||||
done(reason);
|
||||
});
|
||||
};
|
||||
add(Reason::Spam, tr::lng_report_reason_spam);
|
||||
if (source != Source::Message) {
|
||||
add(Reason::Fake, tr::lng_report_reason_fake);
|
||||
}
|
||||
add(Reason::Violence, tr::lng_report_reason_violence);
|
||||
add(Reason::ChildAbuse, tr::lng_report_reason_child_abuse);
|
||||
add(Reason::Pornography, tr::lng_report_reason_pornography);
|
||||
add(Reason::Other, tr::lng_report_reason_other);
|
||||
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
}
|
||||
|
||||
void ReportDetailsBox(
|
||||
not_null<GenericBox*> box,
|
||||
Fn<void(QString)> done) {
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box, // #TODO reports
|
||||
tr::lng_report_details_about(),
|
||||
st::boxLabel),
|
||||
{
|
||||
st::boxRowPadding.left(),
|
||||
st::boxPadding.top(),
|
||||
st::boxRowPadding.right(),
|
||||
st::boxPadding.bottom() });
|
||||
const auto details = box->addRow(
|
||||
object_ptr<Ui::InputField>(
|
||||
box,
|
||||
st::newGroupDescription,
|
||||
Ui::InputField::Mode::MultiLine,
|
||||
tr::lng_report_details(),
|
||||
QString()));
|
||||
details->setMaxLength(kReportReasonLengthMax);
|
||||
box->setFocusCallback([=] {
|
||||
details->setFocusFast();
|
||||
});
|
||||
box->addButton(tr::lng_report_button(), [=] {
|
||||
const auto text = details->getLastText();
|
||||
done(text);
|
||||
});
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
}
|
||||
|
||||
} // namespace Ui
|
39
Telegram/SourceFiles/ui/boxes/report_box.h
Normal file
39
Telegram/SourceFiles/ui/boxes/report_box.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class GenericBox;
|
||||
|
||||
enum class ReportSource {
|
||||
Message,
|
||||
Channel,
|
||||
Group,
|
||||
Bot,
|
||||
};
|
||||
|
||||
enum class ReportReason {
|
||||
Spam,
|
||||
Fake,
|
||||
Violence,
|
||||
ChildAbuse,
|
||||
Pornography,
|
||||
Other,
|
||||
};
|
||||
|
||||
void ReportReasonBox(
|
||||
not_null<GenericBox*> box,
|
||||
ReportSource source,
|
||||
Fn<void(ReportReason)> done);
|
||||
|
||||
void ReportDetailsBox(
|
||||
not_null<GenericBox*> box,
|
||||
Fn<void(QString)> done);
|
||||
|
||||
} // namespace Ui
|
|
@ -11,10 +11,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/confirm_box.h"
|
||||
#include "boxes/mute_settings_box.h"
|
||||
#include "boxes/add_contact_box.h"
|
||||
#include "boxes/report_box.h"
|
||||
#include "boxes/create_poll_box.h"
|
||||
#include "boxes/peers/add_participants_box.h"
|
||||
#include "boxes/peers/edit_contact_box.h"
|
||||
#include "ui/boxes/report_box.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
|
@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_message.h" // GetErrorTextForSending.
|
||||
#include "history/view/history_view_context_menu.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "support/support_helper.h"
|
||||
|
@ -604,8 +605,8 @@ void Filler::addChannelActions(not_null<ChannelData*> channel) {
|
|||
const auto needReport = !channel->amCreator()
|
||||
&& (!isGroup || channel->isPublic());
|
||||
if (needReport) {
|
||||
_addAction(tr::lng_profile_report(tr::now), [channel] {
|
||||
Ui::show(Box<ReportBox>(channel));
|
||||
_addAction(tr::lng_profile_report(tr::now), [=] {
|
||||
HistoryView::ShowReportPeerBox(navigation, channel);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -974,6 +975,21 @@ void PeerMenuUnblockUserWithBotRestart(not_null<UserData*> user) {
|
|||
});
|
||||
}
|
||||
|
||||
void BlockSenderFromRepliesBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<SessionController*> controller,
|
||||
FullMsgId id) {
|
||||
const auto item = controller->session().data().message(id);
|
||||
Assert(item != nullptr);
|
||||
|
||||
PeerMenuBlockUserBox(
|
||||
box,
|
||||
&controller->window(),
|
||||
item->senderOriginal(),
|
||||
true,
|
||||
Window::ClearReply{ id });
|
||||
}
|
||||
|
||||
QPointer<Ui::RpWidget> ShowForwardMessagesBox(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
MessageIdsList &&items,
|
||||
|
|
|
@ -86,6 +86,11 @@ void PeerMenuBlockUserBox(
|
|||
std::variant<v::null_t, ClearChat, ClearReply> suggestClear);
|
||||
void PeerMenuUnblockUserWithBotRestart(not_null<UserData*> user);
|
||||
|
||||
void BlockSenderFromRepliesBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<Window::SessionController*> controller,
|
||||
FullMsgId id);
|
||||
|
||||
void ToggleHistoryArchived(not_null<History*> history, bool archived);
|
||||
Fn<void()> ClearHistoryHandler(not_null<PeerData*> peer);
|
||||
Fn<void()> DeleteAndLeaveHandler(not_null<PeerData*> peer);
|
||||
|
|
|
@ -1073,6 +1073,17 @@ void SessionController::clearPassportForm() {
|
|||
_passportForm = nullptr;
|
||||
}
|
||||
|
||||
void SessionController::showChooseReportMessages(
|
||||
not_null<PeerData*> peer,
|
||||
Ui::ReportReason reason,
|
||||
Fn<void(MessageIdsList)> done) {
|
||||
content()->showChooseReportMessages(peer, reason, std::move(done));
|
||||
}
|
||||
|
||||
void SessionController::clearChooseReportMessages() {
|
||||
content()->clearChooseReportMessages();
|
||||
}
|
||||
|
||||
void SessionController::updateColumnLayout() {
|
||||
content()->updateColumnLayout();
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ class FormController;
|
|||
|
||||
namespace Ui {
|
||||
class LayerWidget;
|
||||
enum class ReportReason;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Window {
|
||||
|
@ -332,6 +333,12 @@ public:
|
|||
void showPassportForm(const Passport::FormRequest &request);
|
||||
void clearPassportForm();
|
||||
|
||||
void showChooseReportMessages(
|
||||
not_null<PeerData*> peer,
|
||||
Ui::ReportReason reason,
|
||||
Fn<void(MessageIdsList)> done);
|
||||
void clearChooseReportMessages();
|
||||
|
||||
base::Variable<bool> &dialogsListFocused() {
|
||||
return _dialogsListFocused;
|
||||
}
|
||||
|
|
|
@ -72,6 +72,8 @@ PRIVATE
|
|||
ui/boxes/choose_date_time.h
|
||||
ui/boxes/edit_invite_link.cpp
|
||||
ui/boxes/edit_invite_link.h
|
||||
ui/boxes/report_box.cpp
|
||||
ui/boxes/report_box.h
|
||||
ui/chat/attach/attach_album_thumbnail.cpp
|
||||
ui/chat/attach/attach_album_thumbnail.h
|
||||
ui/chat/attach/attach_album_preview.cpp
|
||||
|
|
Loading…
Add table
Reference in a new issue