mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-07-27 07:52:57 +02:00
Show sponsored messages in video.
This commit is contained in:
parent
f7e1b2c70c
commit
ecc955d2ce
12 changed files with 494 additions and 54 deletions
|
@ -682,7 +682,11 @@ SponsoredMessages::Details SponsoredMessages::lookupDetails(
|
|||
if (!entryPtr) {
|
||||
return {};
|
||||
}
|
||||
const auto &data = entryPtr->sponsored;
|
||||
return lookupDetails(entryPtr->sponsored);
|
||||
}
|
||||
|
||||
SponsoredMessages::Details SponsoredMessages::lookupDetails(
|
||||
const SponsoredMessage &data) const {
|
||||
return {
|
||||
.info = Prepare(data),
|
||||
.link = data.link,
|
||||
|
|
|
@ -67,7 +67,7 @@ struct SponsoredMessage {
|
|||
QByteArray randomId;
|
||||
SponsoredFrom from;
|
||||
TextWithEntities textWithEntities;
|
||||
History *history = nullptr;
|
||||
not_null<History*> history;
|
||||
QString link;
|
||||
TextWithEntities sponsorInfo;
|
||||
TextWithEntities additionalInfo;
|
||||
|
@ -141,6 +141,7 @@ public:
|
|||
SponsoredForVideoState state);
|
||||
void clearItems(not_null<History*> history);
|
||||
[[nodiscard]] Details lookupDetails(const FullMsgId &fullId) const;
|
||||
[[nodiscard]] Details lookupDetails(const SponsoredMessage &data) const;
|
||||
[[nodiscard]] Details lookupDetails(
|
||||
const Api::SponsoredSearchResult &data) const;
|
||||
void clicked(const FullMsgId &fullId, bool isMedia, bool isFullscreen);
|
||||
|
|
|
@ -3251,16 +3251,13 @@ void InnerWidget::showSponsoredMenu(int peerSearchIndex, QPoint globalPos) {
|
|||
refresh();
|
||||
});
|
||||
Menu::FillSponsored(
|
||||
this,
|
||||
Ui::Menu::CreateAddActionCallback(_menu),
|
||||
_controller->uiShow(),
|
||||
Menu::SponsoredPhrases::Search,
|
||||
session().sponsoredMessages().lookupDetails(entry->sponsored->data),
|
||||
session().sponsoredMessages().createReportCallback(
|
||||
entry->sponsored->data.randomId,
|
||||
remove),
|
||||
false,
|
||||
false);
|
||||
remove));
|
||||
QObject::connect(_menu.get(), &QObject::destroyed, [=] {
|
||||
if (_peerSearchMenu >= 0
|
||||
&& _peerSearchMenu < _peerSearchResults.size()) {
|
||||
|
|
|
@ -2880,11 +2880,9 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
|||
: nullptr;
|
||||
if (sponsored) {
|
||||
Menu::FillSponsored(
|
||||
this,
|
||||
Ui::Menu::CreateAddActionCallback(_menu),
|
||||
controller->uiShow(),
|
||||
sponsored->fullId(),
|
||||
false);
|
||||
sponsored->fullId());
|
||||
}
|
||||
if (isUponSelected > 0) {
|
||||
addReplyAction(item);
|
||||
|
|
|
@ -1086,3 +1086,34 @@ mediaviewSponsoredButton: RoundButton(defaultActiveButton) {
|
|||
|
||||
ripple: universalRippleAnimation;
|
||||
}
|
||||
|
||||
mediaSponsoredSkip: 16px;
|
||||
mediaSponsoredShift: 16px;
|
||||
mediaSponsoredPadding: margins(12px, 8px, 8px, 8px);
|
||||
mediaSponsoredThumb: 48px;
|
||||
mediaSponsoredClose: IconButton(mediaviewControlsButton) {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
rippleAreaSize: 40px;
|
||||
rippleAreaPosition: point(12px, 12px);
|
||||
|
||||
icon: icon {{ "box_button_close", mediaviewPlaybackIconFg }};
|
||||
iconOver: icon {{ "box_button_close", mediaviewPlaybackIconFgOver }};
|
||||
iconPosition: point(24px, 24px);
|
||||
}
|
||||
mediaSponsoredAbout: RoundButton(defaultActiveButton) {
|
||||
textFg: windowActiveTextFg;
|
||||
textFgOver: windowActiveTextFg;
|
||||
textBg: lightButtonBgOver;
|
||||
textBgOver: lightButtonBgOver;
|
||||
width: -12px;
|
||||
height: 18px;
|
||||
radius: 9px;
|
||||
textTop: 0px;
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(12px);
|
||||
}
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: lightButtonBgRipple;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1610,7 +1610,11 @@ void OverlayWidget::fillContextMenuActions(
|
|||
if (const auto window = findWindow()) {
|
||||
const auto show = window->uiShow();
|
||||
const auto fullId = _message->fullId();
|
||||
Menu::FillSponsored(_body, addAction, show, fullId, true);
|
||||
Menu::FillSponsored(
|
||||
addAction,
|
||||
show,
|
||||
fullId,
|
||||
{ .dark = true, .skipInfo = true });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -4129,7 +4133,10 @@ bool OverlayWidget::createStreamingObjects() {
|
|||
static_cast<PlaybackControls::Delegate*>(this));
|
||||
_streamed->controls->show();
|
||||
_streamed->sponsored = PlaybackSponsored::Has(_message)
|
||||
? std::make_unique<PlaybackSponsored>(_body, _message)
|
||||
? std::make_unique<PlaybackSponsored>(
|
||||
_streamed->controls.get(),
|
||||
uiShow(),
|
||||
_message)
|
||||
: nullptr;
|
||||
if (const auto sponsored = _streamed->sponsored.get()) {
|
||||
_layerBg->layerShownValue(
|
||||
|
|
|
@ -8,10 +8,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "media/view/media_view_playback_sponsored.h"
|
||||
|
||||
#include "data/components/sponsored_messages.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_photo_media.h"
|
||||
#include "data/data_session.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "menu/menu_sponsored.h"
|
||||
#include "ui/widgets/menu/menu_add_action_callback.h"
|
||||
#include "ui/widgets/menu/menu_add_action_callback_factory.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/basic_click_handlers.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_media_view.h"
|
||||
|
||||
namespace Media::View {
|
||||
namespace {
|
||||
|
@ -19,14 +33,341 @@ namespace {
|
|||
constexpr auto kStartDelayMin = crl::time(1000);
|
||||
constexpr auto kDurationMin = 5 * crl::time(1000);
|
||||
|
||||
enum class Action {
|
||||
Close,
|
||||
PromotePremium,
|
||||
Pause,
|
||||
Unpause,
|
||||
};
|
||||
|
||||
[[nodiscard]] style::RoundButton PrepareAboutStyle() {
|
||||
static auto textBg = style::complex_color([] {
|
||||
auto result = st::mediaviewTextLinkFg->c;
|
||||
result.setAlphaF(result.alphaF() * 0.1);
|
||||
return result;
|
||||
});
|
||||
static auto textBgOver = style::complex_color([] {
|
||||
auto result = st::mediaviewTextLinkFg->c;
|
||||
result.setAlphaF(result.alphaF() * 0.15);
|
||||
return result;
|
||||
});
|
||||
static auto rippleColor = style::complex_color([] {
|
||||
auto result = st::mediaviewTextLinkFg->c;
|
||||
result.setAlphaF(result.alphaF() * 0.2);
|
||||
return result;
|
||||
});
|
||||
|
||||
auto result = st::mediaSponsoredAbout;
|
||||
result.textFg = st::mediaviewTextLinkFg;
|
||||
result.textFgOver = st::mediaviewTextLinkFg;
|
||||
result.textBg = textBg.color();
|
||||
result.textBgOver = textBgOver.color();
|
||||
result.ripple.color = rippleColor.color();
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PlaybackSponsored::PlaybackSponsored(
|
||||
class PlaybackSponsored::Message final : public Ui::RpWidget {
|
||||
public:
|
||||
Message(
|
||||
QWidget *parent,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
const Data::SponsoredMessage &data);
|
||||
|
||||
[[nodiscard]] rpl::producer<Action> actions() const;
|
||||
|
||||
void setFinalPosition(int x, int y);
|
||||
|
||||
void fadeIn();
|
||||
void fadeOut(Fn<void()> hidden);
|
||||
|
||||
private:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
void populate();
|
||||
void startFadeIn();
|
||||
void updateShown(Fn<void()> finished = nullptr);
|
||||
|
||||
const not_null<Main::Session*> _session;
|
||||
const std::shared_ptr<ChatHelpers::Show> _show;
|
||||
const Data::SponsoredMessage _data;
|
||||
|
||||
style::RoundButton _aboutSt;
|
||||
std::unique_ptr<Ui::RoundButton> _about;
|
||||
std::unique_ptr<Ui::IconButton> _close;
|
||||
|
||||
base::unique_qptr<Ui::PopupMenu> _menu;
|
||||
rpl::event_stream<Action> _actions;
|
||||
|
||||
std::shared_ptr<Data::PhotoMedia> _photo;
|
||||
Ui::Text::String _title;
|
||||
Ui::Text::String _text;
|
||||
|
||||
QPoint _finalPosition;
|
||||
int _left = 0;
|
||||
int _top = 0;
|
||||
int _titleHeight = 0;
|
||||
int _textHeight = 0;
|
||||
|
||||
QImage _cache;
|
||||
Ui::Animations::Simple _showAnimation;
|
||||
bool _shown = false;
|
||||
bool _over = false;
|
||||
bool _pressed = false;
|
||||
|
||||
rpl::lifetime _photoLifetime;
|
||||
|
||||
};
|
||||
|
||||
PlaybackSponsored::Message::Message(
|
||||
QWidget *parent,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
const Data::SponsoredMessage &data)
|
||||
: RpWidget(parent)
|
||||
, _session(&data.history->session())
|
||||
, _show(std::move(show))
|
||||
, _data(data)
|
||||
, _aboutSt(PrepareAboutStyle())
|
||||
, _about(std::make_unique<Ui::RoundButton>(
|
||||
this,
|
||||
tr::lng_search_sponsored_button(),
|
||||
_aboutSt))
|
||||
, _close(std::make_unique<Ui::IconButton>(this, st::mediaSponsoredClose)) {
|
||||
_about->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
||||
setMouseTracking(true);
|
||||
populate();
|
||||
hide();
|
||||
}
|
||||
|
||||
rpl::producer<Action> PlaybackSponsored::Message::actions() const {
|
||||
return _actions.events();
|
||||
}
|
||||
|
||||
void PlaybackSponsored::Message::setFinalPosition(int x, int y) {
|
||||
_finalPosition = { x, y };
|
||||
if (_shown) {
|
||||
updateShown();
|
||||
}
|
||||
}
|
||||
|
||||
void PlaybackSponsored::Message::fadeIn() {
|
||||
_shown = true;
|
||||
if (!_photo || _photo->loaded()) {
|
||||
startFadeIn();
|
||||
return;
|
||||
}
|
||||
_photo->owner()->session().downloaderTaskFinished(
|
||||
) | rpl::filter([=] {
|
||||
return _photo->loaded();
|
||||
}) | rpl::start_with_next([=] {
|
||||
_photoLifetime.destroy();
|
||||
startFadeIn();
|
||||
}, _photoLifetime);
|
||||
}
|
||||
|
||||
void PlaybackSponsored::Message::startFadeIn() {
|
||||
if (!_shown) {
|
||||
return;
|
||||
}
|
||||
_cache = Ui::GrabWidgetToImage(this);
|
||||
_about->hide();
|
||||
_close->hide();
|
||||
_showAnimation.start([=] {
|
||||
updateShown([=] {
|
||||
_session->sponsoredMessages().view(_data.randomId);
|
||||
});
|
||||
}, 0., 1., st::fadeWrapDuration);
|
||||
show();
|
||||
}
|
||||
|
||||
void PlaybackSponsored::Message::fadeOut(Fn<void()> hidden) {
|
||||
if (!_shown) {
|
||||
if (const auto onstack = hidden) {
|
||||
onstack();
|
||||
}
|
||||
return;
|
||||
}
|
||||
_shown = false;
|
||||
_showAnimation.start([=] {
|
||||
updateShown(hidden);
|
||||
}, 1., 0., st::fadeWrapDuration);
|
||||
}
|
||||
|
||||
void PlaybackSponsored::Message::updateShown(Fn<void()> finished) {
|
||||
const auto shown = _showAnimation.value(_shown ? 1. : 0.);
|
||||
const auto shift = anim::interpolate(st::mediaSponsoredShift, 0, shown);
|
||||
move(_finalPosition.x(), _finalPosition.y() + shift);
|
||||
update();
|
||||
if (!_showAnimation.animating()) {
|
||||
_cache = QImage();
|
||||
_close->show();
|
||||
_about->show();
|
||||
if (const auto onstack = finished) {
|
||||
onstack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlaybackSponsored::Message::paintEvent(QPaintEvent *e) {
|
||||
auto p = QPainter(this);
|
||||
|
||||
const auto shown = _showAnimation.value(_shown ? 1. : 0.);
|
||||
if (!_cache.isNull()) {
|
||||
p.setOpacity(shown);
|
||||
p.drawImage(0, 0, _cache);
|
||||
return;
|
||||
}
|
||||
|
||||
Ui::FillRoundRect(
|
||||
p,
|
||||
rect(),
|
||||
st::mediaviewSaveMsgBg,
|
||||
Ui::MediaviewSaveCorners);
|
||||
|
||||
const auto &padding = st::mediaSponsoredPadding;
|
||||
if (_photo) {
|
||||
if (const auto image = _photo->image(Data::PhotoSize::Large)) {
|
||||
const auto size = st::mediaSponsoredThumb;
|
||||
const auto x = padding.left();
|
||||
const auto y = (height() - size) / 2;
|
||||
p.drawPixmap(
|
||||
x,
|
||||
y,
|
||||
image->pixSingle(
|
||||
size,
|
||||
size,
|
||||
{ .options = Images::Option::RoundCircle }));
|
||||
}
|
||||
}
|
||||
|
||||
p.setPen(st::mediaviewControlFg);
|
||||
|
||||
_title.draw(p, {
|
||||
.position = { _left, _top },
|
||||
.availableWidth = _about->x() - _left,
|
||||
.palette = &st::mediaviewTextPalette,
|
||||
});
|
||||
|
||||
_text.draw(p, {
|
||||
.position = { _left, _top + _titleHeight },
|
||||
.availableWidth = _close->x() - _left,
|
||||
.palette = &st::mediaviewTextPalette,
|
||||
});
|
||||
}
|
||||
|
||||
void PlaybackSponsored::Message::mouseMoveEvent(QMouseEvent *e) {
|
||||
const auto &padding = st::mediaSponsoredPadding;
|
||||
const auto point = e->pos();
|
||||
const auto about = _about->geometry();
|
||||
const auto close = _close->geometry();
|
||||
const auto over = !about.marginsAdded(padding).contains(point)
|
||||
&& !close.marginsAdded(padding).contains(point);
|
||||
if (_over != over) {
|
||||
_over = over;
|
||||
setCursor(_over ? style::cur_pointer : style::cur_default);
|
||||
}
|
||||
}
|
||||
|
||||
void PlaybackSponsored::Message::mousePressEvent(QMouseEvent *e) {
|
||||
if (_over) {
|
||||
_pressed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PlaybackSponsored::Message::mouseReleaseEvent(QMouseEvent *e) {
|
||||
if (base::take(_pressed) && _over) {
|
||||
_session->sponsoredMessages().clicked(_data.randomId, false, false);
|
||||
UrlClickHandler::Open(_data.link);
|
||||
}
|
||||
}
|
||||
|
||||
int PlaybackSponsored::Message::resizeGetHeight(int newWidth) {
|
||||
const auto &padding = st::mediaSponsoredPadding;
|
||||
const auto userpic = st::mediaSponsoredThumb;
|
||||
const auto innerWidth = newWidth - _left - _close->width();
|
||||
const auto titleWidth = innerWidth - _about->width() - padding.right();
|
||||
_titleHeight = _title.countHeight(titleWidth);
|
||||
_textHeight = _text.countHeight(innerWidth);
|
||||
|
||||
const auto use = std::max(_titleHeight + _textHeight, userpic);
|
||||
|
||||
const auto height = padding.top() + use + padding.bottom();
|
||||
_left = padding.left() + (_photo ? (userpic + padding.left()) : 0);
|
||||
_top = padding.top() + (use - _titleHeight - _textHeight) / 2;
|
||||
|
||||
_about->move(
|
||||
_left + std::min(titleWidth, _title.maxWidth()) + padding.right(),
|
||||
_top);
|
||||
_close->move(
|
||||
newWidth - _close->width(),
|
||||
(height - _close->height()) / 2);
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
void PlaybackSponsored::Message::populate() {
|
||||
const auto &from = _data.from;
|
||||
const auto photo = from.photoId
|
||||
? _data.history->owner().photo(from.photoId).get()
|
||||
: nullptr;
|
||||
if (photo) {
|
||||
_photo = photo->createMediaView();
|
||||
photo->load({}, LoadFromCloudOrLocal, true);
|
||||
}
|
||||
_title = Ui::Text::String(
|
||||
st::semiboldTextStyle,
|
||||
from.title,
|
||||
kDefaultTextOptions,
|
||||
st::msgMinWidth);
|
||||
_text = Ui::Text::String(
|
||||
st::defaultTextStyle,
|
||||
_data.textWithEntities,
|
||||
kMarkupTextOptions,
|
||||
st::msgMinWidth);
|
||||
|
||||
_about->setClickedCallback([=] {
|
||||
_menu = nullptr;
|
||||
const auto parent = parentWidget();
|
||||
_menu = base::make_unique_q<Ui::PopupMenu>(
|
||||
parent,
|
||||
st::mediaviewPopupMenu);
|
||||
const auto raw = _menu.get();
|
||||
const auto addAction = Ui::Menu::CreateAddActionCallback(raw);
|
||||
Menu::FillSponsored(
|
||||
addAction,
|
||||
_show,
|
||||
Menu::SponsoredPhrases::Channel,
|
||||
_session->sponsoredMessages().lookupDetails(_data),
|
||||
_session->sponsoredMessages().createReportCallback(
|
||||
_data.randomId,
|
||||
crl::guard(this, [=] { _actions.fire(Action::Close); })),
|
||||
{ .dark = true });
|
||||
_actions.fire(Action::Pause);
|
||||
Ui::Connect(raw, &QObject::destroyed, this, [=] {
|
||||
_actions.fire(Action::Unpause);
|
||||
});
|
||||
raw->popup(QCursor::pos());
|
||||
});
|
||||
_close->setClickedCallback([=] {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
PlaybackSponsored::PlaybackSponsored(
|
||||
not_null<Ui::RpWidget*> controls,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
not_null<HistoryItem*> item)
|
||||
: _parent(parent)
|
||||
: _parent(controls->parentWidget())
|
||||
, _session(&item->history()->session())
|
||||
, _show(std::move(show))
|
||||
, _itemId(item->fullId())
|
||||
, _controlsGeometry(controls->geometryValue())
|
||||
, _timer([=] { update(); }) {
|
||||
_session->sponsoredMessages().requestForVideo(item, crl::guard(this, [=](
|
||||
Data::SponsoredForVideo data) {
|
||||
|
@ -60,6 +401,11 @@ void PlaybackSponsored::start() {
|
|||
}
|
||||
|
||||
void PlaybackSponsored::setPaused(bool paused) {
|
||||
setPausedOutside(paused);
|
||||
}
|
||||
|
||||
void PlaybackSponsored::updatePaused() {
|
||||
const auto paused = _pausedInside || _pausedOutside;
|
||||
if (_paused == paused) {
|
||||
return;
|
||||
}
|
||||
|
@ -77,6 +423,22 @@ void PlaybackSponsored::setPaused(bool paused) {
|
|||
}
|
||||
}
|
||||
|
||||
void PlaybackSponsored::setPausedInside(bool paused) {
|
||||
if (_pausedInside == paused) {
|
||||
return;
|
||||
}
|
||||
_pausedInside = paused;
|
||||
updatePaused();
|
||||
}
|
||||
|
||||
void PlaybackSponsored::setPausedOutside(bool paused) {
|
||||
if (_pausedOutside == paused) {
|
||||
return;
|
||||
}
|
||||
_pausedOutside = paused;
|
||||
updatePaused();
|
||||
}
|
||||
|
||||
void PlaybackSponsored::finish() {
|
||||
_timer.cancel();
|
||||
if (_data) {
|
||||
|
@ -132,18 +494,36 @@ void PlaybackSponsored::update() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void PlaybackSponsored::show(const Data::SponsoredMessage &data) {
|
||||
_widget = std::make_unique<Ui::RpWidget>(_parent);
|
||||
_widget->setGeometry(_parent->rect());
|
||||
_widget->paintRequest() | rpl::start_with_next([=] {
|
||||
auto p = QPainter(_widget.get());
|
||||
p.fillRect(_widget->rect(), QColor(0, 128, 0, 128));
|
||||
}, _widget->lifetime());
|
||||
_widget->show();
|
||||
_widget = std::make_unique<Message>(_parent, _show, data);
|
||||
const auto raw = _widget.get();
|
||||
|
||||
_controlsGeometry.value() | rpl::start_with_next([=](QRect controls) {
|
||||
raw->resizeToWidth(controls.width());
|
||||
raw->setFinalPosition(
|
||||
controls.x(),
|
||||
controls.y() - st::mediaSponsoredSkip - raw->height());
|
||||
}, raw->lifetime());
|
||||
|
||||
raw->actions() | rpl::start_with_next([=](Action action) {
|
||||
switch (action) {
|
||||
case Action::Close: hide(); break;
|
||||
case Action::PromotePremium: break;
|
||||
case Action::Pause: setPausedInside(true); break;
|
||||
case Action::Unpause: setPausedInside(false); break;
|
||||
}
|
||||
}, raw->lifetime());
|
||||
|
||||
raw->fadeIn();
|
||||
}
|
||||
|
||||
void PlaybackSponsored::hide() {
|
||||
_widget = nullptr;
|
||||
_widget->fadeOut([this, raw = _widget.get()] {
|
||||
if (_widget.get() == raw) {
|
||||
_widget = nullptr;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void PlaybackSponsored::saveState() {
|
||||
|
|
|
@ -11,15 +11,26 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "base/weak_ptr.h"
|
||||
#include "data/components/sponsored_messages.h"
|
||||
|
||||
namespace ChatHelpers {
|
||||
class Show;
|
||||
} // namespace ChatHelpers
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Ui {
|
||||
class RpWidget;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Media::View {
|
||||
|
||||
class PlaybackSponsored final : public base::has_weak_ptr {
|
||||
public:
|
||||
PlaybackSponsored(QWidget *parent, not_null<HistoryItem*> item);
|
||||
PlaybackSponsored(
|
||||
not_null<Ui::RpWidget*> controls,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
not_null<HistoryItem*> item);
|
||||
~PlaybackSponsored();
|
||||
|
||||
void start();
|
||||
|
@ -30,6 +41,7 @@ public:
|
|||
[[nodiscard]] static bool Has(HistoryItem *item);
|
||||
|
||||
private:
|
||||
class Message;
|
||||
struct State {
|
||||
crl::time now = 0;
|
||||
Data::SponsoredForVideoState data;
|
||||
|
@ -37,6 +49,9 @@ private:
|
|||
|
||||
void update();
|
||||
void finish();
|
||||
void updatePaused();
|
||||
void setPausedInside(bool paused);
|
||||
void setPausedOutside(bool paused);
|
||||
void show(const Data::SponsoredMessage &data);
|
||||
void hide();
|
||||
[[nodiscard]] State computeState() const;
|
||||
|
@ -44,13 +59,17 @@ private:
|
|||
|
||||
const not_null<QWidget*> _parent;
|
||||
const not_null<Main::Session*> _session;
|
||||
const std::shared_ptr<ChatHelpers::Show> _show;
|
||||
const FullMsgId _itemId;
|
||||
|
||||
std::unique_ptr<Ui::RpWidget> _widget;
|
||||
rpl::variable<QRect> _controlsGeometry;
|
||||
std::unique_ptr<Message> _widget;
|
||||
|
||||
crl::time _start = 0;
|
||||
bool _started = false;
|
||||
bool _paused = false;
|
||||
bool _pausedInside = false;
|
||||
bool _pausedOutside = false;
|
||||
base::Timer _timer;
|
||||
|
||||
std::optional<Data::SponsoredForVideo> _data;
|
||||
|
|
|
@ -287,14 +287,12 @@ void AboutBox(
|
|||
top->setForceRippled(false);
|
||||
});
|
||||
FillSponsored(
|
||||
top,
|
||||
Ui::Menu::CreateAddActionCallback(menu->get()),
|
||||
show,
|
||||
phrases,
|
||||
details,
|
||||
report,
|
||||
false,
|
||||
true);
|
||||
{ .skipAbout = true });
|
||||
const auto global = top->mapToGlobal(
|
||||
QPoint(top->width() / 4 * 3, top->height() / 2));
|
||||
raw->setForcedOrigin(Ui::PanelAnimation::Origin::TopRight);
|
||||
|
@ -390,18 +388,17 @@ void ShowReportSponsoredBox(
|
|||
} // namespace
|
||||
|
||||
void FillSponsored(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
const Ui::Menu::MenuCallback &addAction,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
SponsoredPhrases phrases,
|
||||
const Data::SponsoredMessages::Details &details,
|
||||
Data::SponsoredReportAction report,
|
||||
bool mediaViewer,
|
||||
bool skipAbout) {
|
||||
SponsoredMenuSettings settings) {
|
||||
const auto session = &show->session();
|
||||
const auto &info = details.info;
|
||||
const auto dark = settings.dark;
|
||||
|
||||
if (!mediaViewer && !info.empty()) {
|
||||
if (!settings.skipInfo && !info.empty()) {
|
||||
auto fillSubmenu = [&](not_null<Ui::PopupMenu*> menu) {
|
||||
const auto allText = ranges::accumulate(
|
||||
info,
|
||||
|
@ -416,8 +413,10 @@ void FillSponsored(
|
|||
for (const auto &i : info) {
|
||||
auto item = base::make_unique_q<Ui::Menu::MultilineAction>(
|
||||
menu,
|
||||
st::defaultMenu,
|
||||
st::historySponsorInfoItem,
|
||||
dark ? st::storiesMenu : st::defaultMenu,
|
||||
(dark
|
||||
? st::historySponsorInfoItemDark
|
||||
: st::historySponsorInfoItem),
|
||||
st::historyHasCustomEmojiPosition,
|
||||
base::duplicate(i));
|
||||
item->clicks(
|
||||
|
@ -431,27 +430,31 @@ void FillSponsored(
|
|||
addAction({
|
||||
.text = tr::lng_sponsored_info_menu(tr::now),
|
||||
.handler = nullptr,
|
||||
.icon = &st::menuIconChannel,
|
||||
.icon = (dark
|
||||
? &st::mediaMenuIconChannel
|
||||
: &st::menuIconChannel),
|
||||
.fillSubmenu = std::move(fillSubmenu),
|
||||
});
|
||||
addAction({
|
||||
.separatorSt = &st::expandedMenuSeparator,
|
||||
.separatorSt = (dark
|
||||
? &st::mediaviewMenuSeparator
|
||||
: &st::expandedMenuSeparator),
|
||||
.isSeparator = true,
|
||||
});
|
||||
}
|
||||
if (details.canReport) {
|
||||
if (!skipAbout) {
|
||||
if (!settings.skipAbout) {
|
||||
addAction(tr::lng_sponsored_menu_revenued_about(tr::now), [=] {
|
||||
show->show(Box(AboutBox, show, phrases, details, report));
|
||||
}, (mediaViewer ? &st::mediaMenuIconInfo : &st::menuIconInfo));
|
||||
}, (dark ? &st::mediaMenuIconInfo : &st::menuIconInfo));
|
||||
}
|
||||
|
||||
addAction(tr::lng_sponsored_menu_revenued_report(tr::now), [=] {
|
||||
ShowReportSponsoredBox(show, report);
|
||||
}, (mediaViewer ? &st::mediaMenuIconBlock : &st::menuIconBlock));
|
||||
}, (dark ? &st::mediaMenuIconBlock : &st::menuIconBlock));
|
||||
|
||||
addAction({
|
||||
.separatorSt = (mediaViewer
|
||||
.separatorSt = (dark
|
||||
? &st::mediaviewMenuSeparator
|
||||
: &st::expandedMenuSeparator),
|
||||
.isSeparator = true,
|
||||
|
@ -464,26 +467,22 @@ void FillSponsored(
|
|||
} else {
|
||||
ShowPremiumPreviewBox(show, PremiumFeature::NoAds);
|
||||
}
|
||||
}, (mediaViewer ? &st::mediaMenuIconCancel : &st::menuIconCancel));
|
||||
}, (dark ? &st::mediaMenuIconCancel : &st::menuIconCancel));
|
||||
}
|
||||
|
||||
void FillSponsored(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
const Ui::Menu::MenuCallback &addAction,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
const FullMsgId &fullId,
|
||||
bool mediaViewer,
|
||||
bool skipAbout) {
|
||||
SponsoredMenuSettings settings) {
|
||||
const auto session = &show->session();
|
||||
FillSponsored(
|
||||
parent,
|
||||
addAction,
|
||||
show,
|
||||
PhrasesForMessage(fullId),
|
||||
session->sponsoredMessages().lookupDetails(fullId),
|
||||
session->sponsoredMessages().createReportCallback(fullId),
|
||||
mediaViewer,
|
||||
skipAbout);
|
||||
settings);
|
||||
}
|
||||
|
||||
void ShowSponsored(
|
||||
|
@ -495,11 +494,9 @@ void ShowSponsored(
|
|||
st::popupMenuWithIcons);
|
||||
|
||||
FillSponsored(
|
||||
parent,
|
||||
Ui::Menu::CreateAddActionCallback(menu),
|
||||
show,
|
||||
fullId,
|
||||
false);
|
||||
fullId);
|
||||
|
||||
menu->popup(QCursor::pos());
|
||||
}
|
||||
|
|
|
@ -33,23 +33,25 @@ enum class SponsoredPhrases {
|
|||
Search,
|
||||
};
|
||||
|
||||
struct SponsoredMenuSettings {
|
||||
bool dark = false;
|
||||
bool skipAbout = false;
|
||||
bool skipInfo = false;
|
||||
};
|
||||
|
||||
void FillSponsored(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
const Ui::Menu::MenuCallback &addAction,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
SponsoredPhrases phrases,
|
||||
const Data::SponsoredMessageDetails &details,
|
||||
Data::SponsoredReportAction report,
|
||||
bool mediaViewer,
|
||||
bool skipAbout);
|
||||
SponsoredMenuSettings settings = {});
|
||||
|
||||
void FillSponsored(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
const Ui::Menu::MenuCallback &addAction,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
const FullMsgId &fullId,
|
||||
bool mediaViewer,
|
||||
bool skipAbout = false);
|
||||
SponsoredMenuSettings settings = {});
|
||||
|
||||
void ShowSponsored(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
|
|
|
@ -947,6 +947,9 @@ historySponsorInfoItem: FlatLabel(defaultFlatLabel) {
|
|||
minWidth: 136px;
|
||||
maxHeight: 120px;
|
||||
}
|
||||
historySponsorInfoItemDark: FlatLabel(historySponsorInfoItem) {
|
||||
textFg: mediaviewControlFg;
|
||||
}
|
||||
historyHasCustomEmoji: FlatLabel(defaultFlatLabel) {
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(11px);
|
||||
|
|
|
@ -204,6 +204,7 @@ menuBlueIconGroupCreate: icon {{ "menu/groups_create", lightButtonFg }};
|
|||
|
||||
mediaMenuIconStickers: icon {{ "menu/stickers", mediaviewMenuFg }};
|
||||
mediaMenuIconCancel: icon {{ "menu/cancel", mediaviewMenuFg }};
|
||||
mediaMenuIconChannel: icon {{ "menu/channel", mediaviewMenuFg }};
|
||||
mediaMenuIconShowInChat: icon {{ "menu/show_in_chat", mediaviewMenuFg }};
|
||||
mediaMenuIconShowInFolder: icon {{ "menu/show_in_folder", mediaviewMenuFg }};
|
||||
mediaMenuIconDownload: icon {{ "menu/download", mediaviewMenuFg }};
|
||||
|
|
Loading…
Add table
Reference in a new issue