mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added support of sponsored messages with revenue to bar.
This commit is contained in:
parent
ae3f16ccbd
commit
7d52787e54
7 changed files with 80 additions and 52 deletions
|
@ -5200,13 +5200,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_sponsored_revenued_subtitle" = "Telegram Ads are very different from ads on other platforms. Ads such as this one:";
|
"lng_sponsored_revenued_subtitle" = "Telegram Ads are very different from ads on other platforms. Ads such as this one:";
|
||||||
"lng_sponsored_revenued_info1_title" = "Respect Your Privacy";
|
"lng_sponsored_revenued_info1_title" = "Respect Your Privacy";
|
||||||
"lng_sponsored_revenued_info1_description" = "Ads on Telegram do not use your personal information and are based on the channel in which you see them.";
|
"lng_sponsored_revenued_info1_description" = "Ads on Telegram do not use your personal information and are based on the channel in which you see them.";
|
||||||
|
"lng_sponsored_revenued_info1_bot_description" = "Ads on Telegram do not use your personal information and are based on the mini app in which you see them.";
|
||||||
"lng_sponsored_revenued_info2_title" = "Help the Channel Creator";
|
"lng_sponsored_revenued_info2_title" = "Help the Channel Creator";
|
||||||
"lng_sponsored_revenued_info2_description" = "50% of the revenue from Telegram Ads goes to the owner of the channel where they are displayed.";
|
"lng_sponsored_revenued_info2_description" = "50% of the revenue from Telegram Ads goes to the owner of the channel where they are displayed.";
|
||||||
|
"lng_sponsored_revenued_info2_bot_description" = "50% of the revenue from Telegram Ads goes to the developer of the mini app where they are displayed.";
|
||||||
"lng_sponsored_revenued_info3_title" = "Can Be Removed";
|
"lng_sponsored_revenued_info3_title" = "Can Be Removed";
|
||||||
"lng_sponsored_revenued_info3_description#one" = "You can turn off ads by subscribing to {link}, and Level {count} channels can remove them for their subscribers.";
|
"lng_sponsored_revenued_info3_description#one" = "You can turn off ads by subscribing to {link}, and Level {count} channels can remove them for their subscribers.";
|
||||||
"lng_sponsored_revenued_info3_description#other" = "You can turn off ads by subscribing to {link}, and Level {count} channels can remove them for their subscribers.";
|
"lng_sponsored_revenued_info3_description#other" = "You can turn off ads by subscribing to {link}, and Level {count} channels can remove them for their subscribers.";
|
||||||
|
"lng_sponsored_revenued_info3_bot_description" = "You can turn off ads in mini apps by subscribing to {link}.";
|
||||||
"lng_sponsored_revenued_footer_title" = "Can I Launch an Ad?";
|
"lng_sponsored_revenued_footer_title" = "Can I Launch an Ad?";
|
||||||
"lng_sponsored_revenued_footer_description" = "Anyone can create an ad to display in this channel — with minimal budgets. Check out the **Telegram Ad Platform** for details. {link}";
|
"lng_sponsored_revenued_footer_description" = "Anyone can create an ad to display in this channel — with minimal budgets. Check out the **Telegram Ad Platform** for details. {link}";
|
||||||
|
"lng_sponsored_revenued_footer_bot_description" = "Anyone can create an ad to display in this bot — with minimal budgets. Check out the **Telegram Ad Platform** for details. {link}";
|
||||||
"lng_sponsored_top_bar_hide" = "remove";
|
"lng_sponsored_top_bar_hide" = "remove";
|
||||||
|
|
||||||
"lng_telegram_features_url" = "https://t.me/TelegramTips";
|
"lng_telegram_features_url" = "https://t.me/TelegramTips";
|
||||||
|
|
|
@ -414,6 +414,16 @@ ClickHandlerPtr ReportSponsoredClickHandler(not_null<HistoryItem*> item) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClickHandlerPtr AboutSponsoredClickHandler() {
|
||||||
|
return std::make_shared<LambdaClickHandler>([=](ClickContext context) {
|
||||||
|
const auto my = context.other.value<ClickHandlerContext>();
|
||||||
|
if (const auto controller = my.sessionWindow.get()) {
|
||||||
|
Menu::ShowSponsoredAbout(controller->uiShow(), my.itemId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MessageFlags FlagsFromMTP(
|
MessageFlags FlagsFromMTP(
|
||||||
MsgId id,
|
MsgId id,
|
||||||
MTPDmessage::Flags flags,
|
MTPDmessage::Flags flags,
|
||||||
|
|
|
@ -148,6 +148,7 @@ ClickHandlerPtr JumpToStoryClickHandler(
|
||||||
[[nodiscard]] ClickHandlerPtr HideSponsoredClickHandler();
|
[[nodiscard]] ClickHandlerPtr HideSponsoredClickHandler();
|
||||||
[[nodiscard]] ClickHandlerPtr ReportSponsoredClickHandler(
|
[[nodiscard]] ClickHandlerPtr ReportSponsoredClickHandler(
|
||||||
not_null<HistoryItem*> item);
|
not_null<HistoryItem*> item);
|
||||||
|
[[nodiscard]] ClickHandlerPtr AboutSponsoredClickHandler();
|
||||||
|
|
||||||
[[nodiscard]] not_null<HistoryItem*> GenerateJoinedMessage(
|
[[nodiscard]] not_null<HistoryItem*> GenerateJoinedMessage(
|
||||||
not_null<History*> history,
|
not_null<History*> history,
|
||||||
|
|
|
@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/view/history_view_sponsored_click_handler.h"
|
#include "history/view/history_view_sponsored_click_handler.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item_components.h"
|
#include "history/history_item_components.h"
|
||||||
|
#include "history/history_item_helpers.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "menu/menu_sponsored.h"
|
#include "menu/menu_sponsored.h"
|
||||||
|
@ -144,15 +145,6 @@ constexpr auto kFactcheckAboutDuration = 5 * crl::time(1000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] ClickHandlerPtr AboutSponsoredClickHandler() {
|
|
||||||
return std::make_shared<LambdaClickHandler>([=](ClickContext context) {
|
|
||||||
const auto my = context.other.value<ClickHandlerContext>();
|
|
||||||
if (const auto controller = my.sessionWindow.get()) {
|
|
||||||
Menu::ShowSponsoredAbout(controller->uiShow());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] QString LookupFactcheckCountryIso2(
|
[[nodiscard]] QString LookupFactcheckCountryIso2(
|
||||||
not_null<HistoryItem*> item) {
|
not_null<HistoryItem*> item) {
|
||||||
const auto info = item->Get<HistoryMessageFactcheck>();
|
const auto info = item->Get<HistoryMessageFactcheck>();
|
||||||
|
|
|
@ -41,11 +41,13 @@ namespace {
|
||||||
|
|
||||||
void AboutBox(
|
void AboutBox(
|
||||||
not_null<Ui::GenericBox*> box,
|
not_null<Ui::GenericBox*> box,
|
||||||
std::shared_ptr<ChatHelpers::Show> show) {
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
|
const FullMsgId &fullId) {
|
||||||
constexpr auto kUrl = "https://promote.telegram.org"_cs;
|
constexpr auto kUrl = "https://promote.telegram.org"_cs;
|
||||||
|
|
||||||
box->setNoContentMargin(true);
|
box->setNoContentMargin(true);
|
||||||
|
|
||||||
|
const auto isChannel = peerIsChannel(fullId.peer);
|
||||||
const auto session = &show->session();
|
const auto session = &show->session();
|
||||||
|
|
||||||
const auto content = box->verticalLayout().get();
|
const auto content = box->verticalLayout().get();
|
||||||
|
@ -131,29 +133,39 @@ void AboutBox(
|
||||||
};
|
};
|
||||||
addEntry(
|
addEntry(
|
||||||
tr::lng_sponsored_revenued_info1_title(),
|
tr::lng_sponsored_revenued_info1_title(),
|
||||||
tr::lng_sponsored_revenued_info1_description(
|
(isChannel
|
||||||
Ui::Text::RichLangValue),
|
? tr::lng_sponsored_revenued_info1_description
|
||||||
|
: tr::lng_sponsored_revenued_info1_bot_description)(
|
||||||
|
Ui::Text::RichLangValue),
|
||||||
st::sponsoredAboutPrivacyIcon);
|
st::sponsoredAboutPrivacyIcon);
|
||||||
Ui::AddSkip(content);
|
Ui::AddSkip(content);
|
||||||
Ui::AddSkip(content);
|
Ui::AddSkip(content);
|
||||||
addEntry(
|
addEntry(
|
||||||
tr::lng_sponsored_revenued_info2_title(),
|
tr::lng_sponsored_revenued_info2_title(),
|
||||||
tr::lng_sponsored_revenued_info2_description(
|
(isChannel
|
||||||
Ui::Text::RichLangValue),
|
? tr::lng_sponsored_revenued_info2_description
|
||||||
|
: tr::lng_sponsored_revenued_info2_bot_description)(
|
||||||
|
Ui::Text::RichLangValue),
|
||||||
st::sponsoredAboutSplitIcon);
|
st::sponsoredAboutSplitIcon);
|
||||||
Ui::AddSkip(content);
|
Ui::AddSkip(content);
|
||||||
Ui::AddSkip(content);
|
Ui::AddSkip(content);
|
||||||
|
auto link = tr::lng_settings_privacy_premium_link(
|
||||||
|
) | rpl::map([](QString t) {
|
||||||
|
return Ui::Text::Link(std::move(t), u"internal:"_q);
|
||||||
|
});
|
||||||
addEntry(
|
addEntry(
|
||||||
tr::lng_sponsored_revenued_info3_title(),
|
tr::lng_sponsored_revenued_info3_title(),
|
||||||
tr::lng_sponsored_revenued_info3_description(
|
isChannel
|
||||||
lt_count,
|
? tr::lng_sponsored_revenued_info3_description(
|
||||||
rpl::single(float64(levels)),
|
lt_count,
|
||||||
lt_link,
|
rpl::single(float64(levels)),
|
||||||
tr::lng_settings_privacy_premium_link(
|
lt_link,
|
||||||
) | rpl::map([=](QString t) {
|
std::move(link),
|
||||||
return Ui::Text::Link(std::move(t), u"internal:"_q);
|
Ui::Text::RichLangValue)
|
||||||
}),
|
: tr::lng_sponsored_revenued_info3_bot_description(
|
||||||
Ui::Text::RichLangValue),
|
lt_link,
|
||||||
|
std::move(link),
|
||||||
|
Ui::Text::RichLangValue),
|
||||||
st::sponsoredAboutRemoveIcon)->setClickHandlerFilter([=](
|
st::sponsoredAboutRemoveIcon)->setClickHandlerFilter([=](
|
||||||
const auto &...) {
|
const auto &...) {
|
||||||
ShowPremiumPreviewBox(show, PremiumFeature::NoAds);
|
ShowPremiumPreviewBox(show, PremiumFeature::NoAds);
|
||||||
|
@ -185,16 +197,18 @@ void AboutBox(
|
||||||
box->addRow(
|
box->addRow(
|
||||||
Ui::CreateLabelWithCustomEmoji(
|
Ui::CreateLabelWithCustomEmoji(
|
||||||
content,
|
content,
|
||||||
tr::lng_sponsored_revenued_footer_description(
|
(isChannel
|
||||||
lt_link,
|
? tr::lng_sponsored_revenued_footer_description
|
||||||
tr::lng_channel_earn_about_link(
|
: tr::lng_sponsored_revenued_footer_bot_description)(
|
||||||
lt_emoji,
|
lt_link,
|
||||||
rpl::single(arrow),
|
tr::lng_channel_earn_about_link(
|
||||||
Ui::Text::RichLangValue
|
lt_emoji,
|
||||||
) | rpl::map([=](TextWithEntities text) {
|
rpl::single(arrow),
|
||||||
return Ui::Text::Link(std::move(text), kUrl.utf16());
|
Ui::Text::RichLangValue
|
||||||
}),
|
) | rpl::map([=](TextWithEntities t) {
|
||||||
Ui::Text::RichLangValue),
|
return Ui::Text::Link(std::move(t), kUrl.utf16());
|
||||||
|
}),
|
||||||
|
Ui::Text::RichLangValue),
|
||||||
{ .session = session },
|
{ .session = session },
|
||||||
st::channelEarnLearnDescription))->resizeToWidth(available);
|
st::channelEarnLearnDescription))->resizeToWidth(available);
|
||||||
}
|
}
|
||||||
|
@ -309,7 +323,7 @@ void FillSponsored(
|
||||||
const auto session = &show->session();
|
const auto session = &show->session();
|
||||||
|
|
||||||
addAction(tr::lng_sponsored_menu_revenued_about(tr::now), [=] {
|
addAction(tr::lng_sponsored_menu_revenued_about(tr::now), [=] {
|
||||||
show->show(Box(AboutBox, show));
|
show->show(Box(AboutBox, show, fullId));
|
||||||
}, (mediaViewer ? &st::mediaMenuIconInfo : &st::menuIconInfo));
|
}, (mediaViewer ? &st::mediaMenuIconInfo : &st::menuIconInfo));
|
||||||
|
|
||||||
addAction(tr::lng_sponsored_menu_revenued_report(tr::now), [=] {
|
addAction(tr::lng_sponsored_menu_revenued_report(tr::now), [=] {
|
||||||
|
@ -352,9 +366,11 @@ void ShowSponsored(
|
||||||
menu->popup(QCursor::pos());
|
menu->popup(QCursor::pos());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowSponsoredAbout(std::shared_ptr<ChatHelpers::Show> show) {
|
void ShowSponsoredAbout(
|
||||||
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
|
const FullMsgId &fullId) {
|
||||||
show->showBox(Box([=](not_null<Ui::GenericBox*> box) {
|
show->showBox(Box([=](not_null<Ui::GenericBox*> box) {
|
||||||
AboutBox(box, show);
|
AboutBox(box, show, fullId);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,8 @@ void ShowSponsored(
|
||||||
std::shared_ptr<ChatHelpers::Show> show,
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
const FullMsgId &fullId);
|
const FullMsgId &fullId);
|
||||||
|
|
||||||
void ShowSponsoredAbout(std::shared_ptr<ChatHelpers::Show> show);
|
void ShowSponsoredAbout(
|
||||||
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
|
const FullMsgId &fullId);
|
||||||
|
|
||||||
} // namespace Menu
|
} // namespace Menu
|
||||||
|
|
|
@ -42,13 +42,14 @@ struct Colors final {
|
||||||
|
|
||||||
using ColorFactory = Fn<Colors()>;
|
using ColorFactory = Fn<Colors()>;
|
||||||
|
|
||||||
class RemoveButton final : public Ui::RippleButton {
|
class BadgeButton final : public Ui::RippleButton {
|
||||||
public:
|
public:
|
||||||
RemoveButton(
|
BadgeButton(
|
||||||
not_null<Ui::RpWidget*> parent,
|
not_null<Ui::RpWidget*> parent,
|
||||||
|
tr::phrase<> text,
|
||||||
ColorFactory cache)
|
ColorFactory cache)
|
||||||
: Ui::RippleButton(parent, st::defaultRippleAnimation) {
|
: Ui::RippleButton(parent, st::defaultRippleAnimation) {
|
||||||
tr::lng_sponsored_top_bar_hide(
|
text(
|
||||||
) | rpl::start_with_next([this](const QString &t) {
|
) | rpl::start_with_next([this](const QString &t) {
|
||||||
const auto height = st::stickersHeaderBadgeFont->height;
|
const auto height = st::stickersHeaderBadgeFont->height;
|
||||||
resize(
|
resize(
|
||||||
|
@ -56,7 +57,7 @@ public:
|
||||||
height);
|
height);
|
||||||
update();
|
update();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
paintRequest() | rpl::start_with_next([this, cache] {
|
paintRequest() | rpl::start_with_next([this, cache, text] {
|
||||||
auto p = QPainter(this);
|
auto p = QPainter(this);
|
||||||
const auto colors = cache();
|
const auto colors = cache();
|
||||||
const auto r = rect();
|
const auto r = rect();
|
||||||
|
@ -70,10 +71,7 @@ public:
|
||||||
p.drawRoundedRect(r, r.height() / 2, r.height() / 2);
|
p.drawRoundedRect(r, r.height() / 2, r.height() / 2);
|
||||||
p.setFont(st::stickersHeaderBadgeFont);
|
p.setFont(st::stickersHeaderBadgeFont);
|
||||||
p.setPen(colors.fg);
|
p.setPen(colors.fg);
|
||||||
p.drawText(
|
p.drawText(r, text(tr::now), style::al_center);
|
||||||
r,
|
|
||||||
tr::lng_sponsored_top_bar_hide(tr::now),
|
|
||||||
style::al_center);
|
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,14 +197,19 @@ void FillSponsoredMessageBar(
|
||||||
state->rightPhoto->subscribeToUpdates(callback);
|
state->rightPhoto->subscribeToUpdates(callback);
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
const auto removeButton = Ui::CreateChild<RemoveButton>(
|
const auto badgeButton = Ui::CreateChild<BadgeButton>(
|
||||||
widget,
|
widget,
|
||||||
|
from.canReport
|
||||||
|
? tr::lng_sponsored_message_revenue_button
|
||||||
|
: tr::lng_sponsored_top_bar_hide,
|
||||||
GenerateReplyColorCallback(
|
GenerateReplyColorCallback(
|
||||||
widget,
|
widget,
|
||||||
fullId,
|
fullId,
|
||||||
from.colorIndex ? from.colorIndex : 4/*blue*/));
|
from.colorIndex ? from.colorIndex : 4/*blue*/));
|
||||||
const auto handler = HideSponsoredClickHandler();
|
const auto handler = from.canReport
|
||||||
removeButton->setClickedCallback([=] {
|
? AboutSponsoredClickHandler()
|
||||||
|
: HideSponsoredClickHandler();
|
||||||
|
badgeButton->setClickedCallback([=] {
|
||||||
if (const auto controller = FindSessionController(widget)) {
|
if (const auto controller = FindSessionController(widget)) {
|
||||||
ActivateClickHandler(widget, handler, {
|
ActivateClickHandler(widget, handler, {
|
||||||
.other = QVariant::fromValue(ClickHandlerContext{
|
.other = QVariant::fromValue(ClickHandlerContext{
|
||||||
|
@ -217,7 +220,7 @@ void FillSponsoredMessageBar(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
removeButton->show();
|
badgeButton->show();
|
||||||
|
|
||||||
const auto draw = [=](QPainter &p) {
|
const auto draw = [=](QPainter &p) {
|
||||||
const auto r = widget->rect();
|
const auto r = widget->rect();
|
||||||
|
@ -237,14 +240,14 @@ void FillSponsoredMessageBar(
|
||||||
const auto hasSecondLineTitle = (titleRight
|
const auto hasSecondLineTitle = (titleRight
|
||||||
> (availableWidth
|
> (availableWidth
|
||||||
- state->contentTitle.maxWidth()
|
- state->contentTitle.maxWidth()
|
||||||
- removeButton->width()));
|
- badgeButton->width()));
|
||||||
p.setPen(st::windowActiveTextFg);
|
p.setPen(st::windowActiveTextFg);
|
||||||
state->title.draw(p, {
|
state->title.draw(p, {
|
||||||
.position = QPoint(leftPadding, topPadding),
|
.position = QPoint(leftPadding, topPadding),
|
||||||
.outerWidth = availableWidth,
|
.outerWidth = availableWidth,
|
||||||
.availableWidth = availableWidth,
|
.availableWidth = availableWidth,
|
||||||
});
|
});
|
||||||
removeButton->moveToLeft(
|
badgeButton->moveToLeft(
|
||||||
hasSecondLineTitle
|
hasSecondLineTitle
|
||||||
? titleRight
|
? titleRight
|
||||||
: std::min(
|
: std::min(
|
||||||
|
@ -257,7 +260,7 @@ void FillSponsoredMessageBar(
|
||||||
: 0)
|
: 0)
|
||||||
- rightPadding),
|
- rightPadding),
|
||||||
topPadding
|
topPadding
|
||||||
+ (titleSt.font->height - removeButton->height()) / 2);
|
+ (titleSt.font->height - badgeButton->height()) / 2);
|
||||||
p.setPen(st::windowFg);
|
p.setPen(st::windowFg);
|
||||||
{
|
{
|
||||||
const auto left = hasSecondLineTitle ? leftPadding : titleRight;
|
const auto left = hasSecondLineTitle ? leftPadding : titleRight;
|
||||||
|
|
Loading…
Add table
Reference in a new issue