Added context menu to top bar of sponsored messages.

This commit is contained in:
23rd 2024-10-26 14:09:19 +03:00
parent 2db30690ce
commit 84055ed74e
5 changed files with 84 additions and 16 deletions

View File

@ -271,21 +271,36 @@ void SponsoredMessages::parse(
void SponsoredMessages::fillTopBar(
not_null<History*> history,
not_null<Ui::RpWidget*> widget) {
not_null<Ui::RpWidget*> widget,
Fn<void()> hide) {
const auto it = _data.find(history);
if (it == end(_data)) {
return;
}
const auto &list = it->second;
auto &list = it->second;
if (list.entries.empty()) {
return;
}
auto &entry = list.entries.front();
if (!entry.optionalDestructionNotifier) {
entry.optionalDestructionNotifier = std::make_unique<rpl::lifetime>();
}
const auto fullId = entry.itemFullId;
entry.optionalDestructionNotifier->add(std::move(hide));
Ui::FillSponsoredMessageBar(
widget,
_session,
list.entries.front().itemFullId,
list.entries.front().sponsored.from,
list.entries.front().sponsored.textWithEntities);
fullId,
entry.sponsored.from,
entry.sponsored.textWithEntities);
const auto viewLifetime = std::make_shared<rpl::lifetime>();
widget->shownValue() | rpl::filter(
rpl::mappers::_1
) | rpl::start_with_next([=, this](bool shown) {
view(fullId);
viewLifetime->destroy();
}, *viewLifetime);
}
void SponsoredMessages::append(
@ -461,7 +476,9 @@ void SponsoredMessages::view(const FullMsgId &fullId) {
}
request.requestId = _session->api().request(
MTPmessages_ViewSponsoredMessage(
entryPtr->item->history()->peer->input,
entryPtr->item
? entryPtr->item->history()->peer->input
: _session->data().peer(fullId.peer)->input,
MTP_bytes(randomId))
).done([=] {
auto &request = _viewRequests[randomId];
@ -517,7 +534,9 @@ void SponsoredMessages::clicked(
MTP_flags(Flag(0)
| (isMedia ? Flag::f_media : Flag(0))
| (isFullscreen ? Flag::f_fullscreen : Flag(0))),
entryPtr->item->history()->peer->input,
entryPtr->item
? entryPtr->item->history()->peer->input
: _session->data().peer(fullId.peer)->input,
MTP_bytes(randomId)
)).send();
}
@ -546,7 +565,7 @@ auto SponsoredMessages::createReportCallback(const FullMsgId &fullId)
return;
}
const auto history = entry->item->history();
const auto history = _session->data().history(fullId.peer);
const auto erase = [=] {
const auto it = _data.find(history);

View File

@ -105,7 +105,8 @@ public:
void clicked(const FullMsgId &fullId, bool isMedia, bool isFullscreen);
void fillTopBar(
not_null<History*> history,
not_null<Ui::RpWidget*> widget);
not_null<Ui::RpWidget*> widget,
Fn<void()> hide);
[[nodiscard]] AppendResult append(not_null<History*> history);
void inject(
@ -130,6 +131,7 @@ private:
FullMsgId itemFullId;
SponsoredMessage sponsored;
std::unique_ptr<MediaPreload> preload;
std::unique_ptr<rpl::lifetime> optionalDestructionNotifier;
};
struct List {
std::vector<Entry> entries;

View File

@ -2529,9 +2529,15 @@ void HistoryWidget::showHistory(
= base::make_unique_q<Ui::SlideWrap<>>(
this,
object_ptr<Ui::RpWidget>(this));
auto destruction = [this] {
if (_sponsoredMessageBar) {
_sponsoredMessageBar->hide(anim::type::normal);
}
};
session().sponsoredMessages().fillTopBar(
_history,
_sponsoredMessageBar->entity());
_sponsoredMessageBar->entity(),
std::move(destruction));
_sponsoredMessageBarHeight = 0;
_sponsoredMessageBar->heightValue(
) | rpl::start_with_next([=](int height) {

View File

@ -8,11 +8,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/chat/sponsored_message_bar.h"
#include "core/application.h"
#include "core/click_handler_types.h"
#include "core/ui_integration.h" // Core::MarkedTextContext.
#include "data/components/sponsored_messages.h"
#include "data/data_session.h"
#include "history/history_item_helpers.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "menu/menu_sponsored.h"
#include "ui/chat/chat_style.h"
#include "ui/chat/chat_theme.h"
#include "ui/dynamic_image.h"
@ -80,12 +83,17 @@ public:
};
[[nodiscard]] Window::SessionController *FindSessionController(
not_null<RpWidget*> widget) {
const auto window = Core::App().findWindow(widget);
return window ? window->sessionController() : nullptr;
}
[[nodiscard]] ColorFactory GenerateReplyColorCallback(
not_null<RpWidget*> widget,
FullMsgId fullId,
int colorIndex) {
const auto window = Core::App().findWindow(widget);
const auto controller = window ? window->sessionController() : nullptr;
const auto controller = FindSessionController(widget);
if (!controller) {
return [] -> Colors {
return { st::windowBgActive->c, st::windowActiveTextFg->c };
@ -121,11 +129,31 @@ public:
} // namespace
void FillSponsoredMessageBar(
not_null<RpWidget*> widget,
not_null<RpWidget*> container,
not_null<Main::Session*> session,
FullMsgId fullId,
Data::SponsoredFrom from,
const TextWithEntities &textWithEntities) {
const auto widget = CreateSimpleRectButton(
container,
st::defaultRippleAnimationBgOver);
widget->show();
container->sizeValue() | rpl::start_with_next([=](const QSize &s) {
widget->resize(s);
}, widget->lifetime());
widget->setAcceptBoth();
widget->addClickHandler([=](Qt::MouseButton button) {
if (button == Qt::RightButton) {
if (const auto controller = FindSessionController(widget)) {
::Menu::ShowSponsored(widget, controller->uiShow(), fullId);
}
} else if (button == Qt::LeftButton) {
session->sponsoredMessages().clicked(fullId, false, false);
UrlClickHandler::Open(from.link);
}
});
struct State final {
Ui::Text::String title;
Ui::Text::String contentTitle;
@ -179,6 +207,18 @@ void FillSponsoredMessageBar(
widget,
fullId,
from.colorIndex ? from.colorIndex : 4/*blue*/));
const auto handler = HideSponsoredClickHandler();
removeButton->setClickedCallback([=] {
if (const auto controller = FindSessionController(widget)) {
ActivateClickHandler(widget, handler, {
.other = QVariant::fromValue(ClickHandlerContext{
.itemId = fullId,
.sessionWindow = base::make_weak(controller),
.show = controller->uiShow(),
})
});
}
});
removeButton->show();
widget->paintRequest(
@ -186,6 +226,7 @@ void FillSponsoredMessageBar(
auto p = QPainter(widget);
const auto r = widget->rect();
p.fillRect(r, st::historyPinnedBg);
widget->paintRipple(p, 0, 0);
const auto leftPadding = st::msgReplyBarSkip + st::msgReplyBarSkip;
const auto rightPadding = st::msgReplyBarSkip;
const auto topPadding = st::msgReplyPadding.top();
@ -300,14 +341,14 @@ void FillSponsoredMessageBar(
const auto minHeight = hasRightPhoto
? (rightPhotoPlaceholder + bottomPadding * 2)
: desiredHeight;
widget->resize(
container->resize(
widget->width(),
std::clamp(
desiredHeight,
minHeight,
st::sponsoredMessageBarMaxHeight));
}, widget->lifetime());
widget->resize(widget->width(), 1);
container->resize(widget->width(), 1);
{
const auto top = Ui::CreateChild<PlainShadow>(widget);

View File

@ -20,7 +20,7 @@ namespace Ui {
class RpWidget;
void FillSponsoredMessageBar(
not_null<RpWidget*> widget,
not_null<RpWidget*> container,
not_null<Main::Session*> session,
FullMsgId fullId,
Data::SponsoredFrom from,