mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-29 15:01:03 +00:00
Show premium stickers toast on double click.
This commit is contained in:
parent
e5d95c0ab0
commit
be16a7725c
@ -692,6 +692,8 @@ PRIVATE
|
||||
history/view/history_view_service_message.h
|
||||
history/view/history_view_spoiler_click_handler.cpp
|
||||
history/view/history_view_spoiler_click_handler.h
|
||||
history/view/history_view_sticker_toast.cpp
|
||||
history/view/history_view_sticker_toast.h
|
||||
history/view/history_view_transcribe_button.cpp
|
||||
history/view/history_view_transcribe_button.h
|
||||
history/view/history_view_top_bar_widget.cpp
|
||||
|
@ -232,14 +232,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
"lng_sticker_premium_about" = "Unlock this sticker and more by subscribing to\nTelegram Premium.";
|
||||
"lng_sticker_premium_button" = "Unlock Premium Stickers";
|
||||
"lng_sticker_premium_title" = "With Effects";
|
||||
"lng_sticker_premium_text" = "This pack contains premium stickers like this one.";
|
||||
"lng_sticker_premium_view" = "View";
|
||||
|
||||
"lng_flood_error" = "Too many tries. Please try again later.";
|
||||
"lng_gif_error" = "An error has occurred while reading GIF animation :(";
|
||||
"lng_edit_error" = "You cannot edit this message";
|
||||
"lng_error_phone_flood" = "Sorry, you have deleted and re-created your account too many times recently. Please wait for a few days before signing up again.";
|
||||
"lng_error_start_minimized_passcoded" = "You have set a local passcode, so Telegram Desktop can't be launched minimised; it will ask you to enter your passcode before it can start working.";
|
||||
"lng_error_pinned_max#one" = "Sorry, you can pin no more than {count} chat to the top.";
|
||||
"lng_error_pinned_max#other" = "Sorry, you can pin no more than {count} chats to the top.";
|
||||
"lng_error_public_groups_denied" = "Unfortunately, you were banned from participating in public groups.\n{more_info}";
|
||||
"lng_error_cant_add_member" = "Sorry, you can't add the bot to this group. Ask a group admin to do it.";
|
||||
"lng_error_cant_add_bot" = "Sorry, this bot can't be added to groups.";
|
||||
@ -1661,8 +1662,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_group_stickers_description" = "You can choose a sticker set which will be available for every member while in the group chat.";
|
||||
"lng_group_stickers_add" = "Choose sticker set";
|
||||
"lng_premium_stickers" = "Premium stickers";
|
||||
"lng_premium_unlock_button" = "Unlock Premium Stickers";
|
||||
"lng_premium_unlock_about" = "Unlock this sticker and more by subscribing to Telegram Premium.";
|
||||
|
||||
"lng_premium" = "Premium";
|
||||
"lng_premium_free" = "Free";
|
||||
|
@ -3232,8 +3232,13 @@ void HistoryInner::elementStartInteraction(not_null<const Element*> view) {
|
||||
void HistoryInner::elementStartPremium(
|
||||
not_null<const Element*> view,
|
||||
Element *replacing) {
|
||||
_emojiInteractions->playPremiumEffect(view, replacing);
|
||||
const auto already = !_emojiInteractions->playPremiumEffect(
|
||||
view,
|
||||
replacing);
|
||||
_animatedStickersPlayed.emplace(view->data());
|
||||
if (already) {
|
||||
_widget->showPremiumStickerTooltip(view);
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryInner::elementCancelPremium(not_null<const Element*> view) {
|
||||
|
@ -98,6 +98,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/view/history_view_group_call_bar.h"
|
||||
#include "history/view/history_view_item_preview.h"
|
||||
#include "history/view/history_view_requests_bar.h"
|
||||
#include "history/view/history_view_sticker_toast.h"
|
||||
#include "history/view/media/history_view_media.h"
|
||||
#include "profile/profile_block_group_members.h"
|
||||
#include "info/info_memento.h"
|
||||
@ -6771,6 +6772,21 @@ void HistoryWidget::hideInfoTooltip(anim::type animated) {
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::showPremiumStickerTooltip(
|
||||
not_null<const HistoryView::Element*> view) {
|
||||
if (const auto media = view->data()->media()) {
|
||||
if (const auto document = media->document()) {
|
||||
if (!_stickerToast) {
|
||||
_stickerToast = std::make_unique<HistoryView::StickerToast>(
|
||||
controller(),
|
||||
_scroll.data(),
|
||||
[=] { _stickerToast = nullptr; });
|
||||
}
|
||||
_stickerToast->showFor(document);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::setFieldText(
|
||||
const TextWithTags &textWithTags,
|
||||
TextUpdateEvents events,
|
||||
|
@ -102,6 +102,7 @@ enum class MimeDataState;
|
||||
} // namespace Storage
|
||||
|
||||
namespace HistoryView {
|
||||
class StickerToast;
|
||||
class TopBarWidget;
|
||||
class ContactStatus;
|
||||
class Element;
|
||||
@ -277,6 +278,8 @@ public:
|
||||
const TextWithEntities &text,
|
||||
Fn<void()> hiddenCallback);
|
||||
void hideInfoTooltip(anim::type animated);
|
||||
void showPremiumStickerTooltip(
|
||||
not_null<const HistoryView::Element*> view);
|
||||
|
||||
// Tabbed selector management.
|
||||
bool pushTabbedSelectorToThirdSection(
|
||||
@ -798,6 +801,7 @@ private:
|
||||
base::Timer _saveCloudDraftTimer;
|
||||
|
||||
base::weak_ptr<Ui::Toast::Instance> _topToast;
|
||||
std::unique_ptr<HistoryView::StickerToast> _stickerToast;
|
||||
std::unique_ptr<ChooseMessagesForReport> _chooseForReport;
|
||||
|
||||
base::flat_set<not_null<HistoryItem*>> _itemRevealPending;
|
||||
|
@ -91,7 +91,7 @@ void EmojiInteractions::play(
|
||||
}
|
||||
}
|
||||
|
||||
void EmojiInteractions::playPremiumEffect(
|
||||
bool EmojiInteractions::playPremiumEffect(
|
||||
not_null<const Element*> view,
|
||||
Element *replacing) {
|
||||
const auto already = ranges::contains(_plays, view, &Play::view);
|
||||
@ -109,10 +109,10 @@ void EmojiInteractions::playPremiumEffect(
|
||||
//if (i->premium) {
|
||||
// view->externalLottieProgressing(true);
|
||||
//}
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
} else if (already) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (const auto media = view->media()) {
|
||||
if (const auto document = media->getDocument()) {
|
||||
@ -128,6 +128,7 @@ void EmojiInteractions::playPremiumEffect(
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void EmojiInteractions::cancelPremiumEffect(not_null<const Element*> view) {
|
||||
|
@ -37,7 +37,7 @@ public:
|
||||
void play(
|
||||
ChatHelpers::EmojiInteractionPlayRequest request,
|
||||
not_null<Element*> view);
|
||||
void playPremiumEffect(
|
||||
bool playPremiumEffect(
|
||||
not_null<const Element*> view,
|
||||
Element *replacing);
|
||||
void cancelPremiumEffect(not_null<const Element*> view);
|
||||
|
125
Telegram/SourceFiles/history/view/history_view_sticker_toast.cpp
Normal file
125
Telegram/SourceFiles/history/view/history_view_sticker_toast.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
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 "history/view/history_view_sticker_toast.h"
|
||||
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/toast/toast_widget.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_document_media.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "boxes/sticker_set_box.h"
|
||||
#include "lottie/lottie_single_player.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
namespace HistoryView {
|
||||
namespace {
|
||||
|
||||
constexpr auto kPremiumToastDuration = 5 * crl::time(1000);
|
||||
|
||||
} // namespace
|
||||
|
||||
StickerToast::StickerToast(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<QWidget*> parent,
|
||||
Fn<void()> destroy)
|
||||
: _controller(controller)
|
||||
, _parent(parent)
|
||||
, _destroy(std::move(destroy)) {
|
||||
}
|
||||
|
||||
StickerToast::~StickerToast() = default;
|
||||
|
||||
void StickerToast::showFor(not_null<DocumentData*> document) {
|
||||
const auto sticker = document->sticker();
|
||||
if (!sticker || sticker->type != StickerType::Tgs) {
|
||||
return;
|
||||
} else if (const auto strong = _weak.get()) {
|
||||
if (_for == document) {
|
||||
return;
|
||||
}
|
||||
strong->hideAnimated();
|
||||
}
|
||||
_for = document;
|
||||
|
||||
const auto text = Ui::Text::Bold(
|
||||
tr::lng_sticker_premium_title(tr::now)
|
||||
).append('\n').append(
|
||||
tr::lng_sticker_premium_text(tr::now)
|
||||
);
|
||||
_st = st::historyPremiumToast;
|
||||
const auto skip = _st.padding.top();
|
||||
const auto size = _st.style.font->height * 2;
|
||||
const auto view = tr::lng_sticker_premium_view(tr::now);
|
||||
_st.padding.setLeft(skip + size + skip);
|
||||
_st.padding.setRight(st::historyPremiumViewSet.font->width(view)
|
||||
- st::historyPremiumViewSet.width);
|
||||
_weak = Ui::Toast::Show(_parent, Ui::Toast::Config{
|
||||
.text = text,
|
||||
.st = &_st,
|
||||
.durationMs = kPremiumToastDuration,
|
||||
.multiline = true,
|
||||
.dark = true,
|
||||
.slideSide = RectPart::Bottom,
|
||||
});
|
||||
const auto strong = _weak.get();
|
||||
if (!strong) {
|
||||
return;
|
||||
}
|
||||
strong->setInputUsed(true);
|
||||
const auto widget = strong->widget();
|
||||
const auto button = Ui::CreateChild<Ui::RoundButton>(
|
||||
widget.get(),
|
||||
rpl::single(view),
|
||||
st::historyPremiumViewSet);
|
||||
button->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
||||
button->show();
|
||||
widget->widthValue(
|
||||
) | rpl::start_with_next([=](int width) {
|
||||
button->moveToRight(0, 0, width);
|
||||
}, widget->lifetime());
|
||||
const auto preview = Ui::CreateChild<Ui::RpWidget>(widget.get());
|
||||
preview->moveToLeft(skip, skip);
|
||||
preview->resize(size, size);
|
||||
preview->show();
|
||||
|
||||
const auto bytes = document->createMediaView()->bytes();
|
||||
const auto filepath = document->filepath();
|
||||
const auto player = preview->lifetime().make_state<Lottie::SinglePlayer>(
|
||||
Lottie::ReadContent(bytes, filepath),
|
||||
Lottie::FrameRequest{ QSize(size, size) },
|
||||
Lottie::Quality::Default);
|
||||
preview->paintRequest(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (!player->ready()) {
|
||||
return;
|
||||
}
|
||||
const auto image = player->frame();
|
||||
QPainter(preview).drawImage(
|
||||
QRect(QPoint(), image.size() / image.devicePixelRatio()),
|
||||
image);
|
||||
player->markFrameShown();
|
||||
}, preview->lifetime());
|
||||
player->updates(
|
||||
) | rpl::start_with_next([=] {
|
||||
preview->update();
|
||||
}, preview->lifetime());
|
||||
|
||||
button->setClickedCallback([=, weak = _weak] {
|
||||
_controller->show(
|
||||
Box<StickerSetBox>(_controller, document->sticker()->set),
|
||||
Ui::LayerOption::KeepOther);
|
||||
if (const auto strong = weak.get()) {
|
||||
strong->hideAnimated();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace HistoryView
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
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 "styles/style_widgets.h"
|
||||
|
||||
namespace Ui {
|
||||
class Show;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Ui::Toast {
|
||||
class Instance;
|
||||
} // namespace Ui::Toast
|
||||
|
||||
namespace Window {
|
||||
class SessionController;
|
||||
} // namespace Window
|
||||
|
||||
namespace HistoryView {
|
||||
|
||||
class StickerToast final {
|
||||
public:
|
||||
StickerToast(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<QWidget*> parent,
|
||||
Fn<void()> destroy);
|
||||
~StickerToast();
|
||||
|
||||
void showFor(not_null<DocumentData*> document);
|
||||
|
||||
private:
|
||||
const not_null<Window::SessionController*> _controller;
|
||||
const not_null<QWidget*> _parent;
|
||||
style::Toast _st;
|
||||
base::weak_ptr<Ui::Toast::Instance> _weak;
|
||||
DocumentData *_for = nullptr;
|
||||
Fn<void()> _destroy;
|
||||
|
||||
};
|
||||
|
||||
} // namespace HistoryView
|
@ -75,6 +75,22 @@ historyResizeWidth: 6px;
|
||||
|
||||
historyPaddingBottom: 8px;
|
||||
|
||||
historyPremiumToast: Toast(defaultToast) {
|
||||
minWidth: msgMinWidth;
|
||||
maxWidth: 380px;
|
||||
padding: margins(19px, 13px, 19px, 12px);
|
||||
}
|
||||
historyPremiumViewSet: RoundButton(defaultActiveButton) {
|
||||
width: -24px;
|
||||
height: 44px;
|
||||
textTop: 13px;
|
||||
textFg: mediaviewTextLinkFg;
|
||||
textFgOver: mediaviewTextLinkFg;
|
||||
textBg: transparent;
|
||||
textBgOver: transparent;
|
||||
ripple: emptyRippleAnimation;
|
||||
}
|
||||
|
||||
historyToDownPosition: point(12px, 10px);
|
||||
historyToDownAbove: icon {{ "history_down_arrow", historyToDownFg }};
|
||||
historyToDownAboveOver: icon {{ "history_down_arrow", historyToDownFgOver }};
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 79af7c5523ae59d4dd13cc2bde86bb8611bde11c
|
||||
Subproject commit a78089716bf153b4283ec79757268d1047913f12
|
Loading…
Reference in New Issue
Block a user