mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-04-11 04:01:18 +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_service_message.h
|
||||||
history/view/history_view_spoiler_click_handler.cpp
|
history/view/history_view_spoiler_click_handler.cpp
|
||||||
history/view/history_view_spoiler_click_handler.h
|
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.cpp
|
||||||
history/view/history_view_transcribe_button.h
|
history/view/history_view_transcribe_button.h
|
||||||
history/view/history_view_top_bar_widget.cpp
|
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_about" = "Unlock this sticker and more by subscribing to\nTelegram Premium.";
|
||||||
"lng_sticker_premium_button" = "Unlock Premium Stickers";
|
"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_flood_error" = "Too many tries. Please try again later.";
|
||||||
"lng_gif_error" = "An error has occurred while reading GIF animation :(";
|
"lng_gif_error" = "An error has occurred while reading GIF animation :(";
|
||||||
"lng_edit_error" = "You cannot edit this message";
|
"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_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_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_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_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.";
|
"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_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_group_stickers_add" = "Choose sticker set";
|
||||||
"lng_premium_stickers" = "Premium stickers";
|
"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" = "Premium";
|
||||||
"lng_premium_free" = "Free";
|
"lng_premium_free" = "Free";
|
||||||
|
@ -3232,8 +3232,13 @@ void HistoryInner::elementStartInteraction(not_null<const Element*> view) {
|
|||||||
void HistoryInner::elementStartPremium(
|
void HistoryInner::elementStartPremium(
|
||||||
not_null<const Element*> view,
|
not_null<const Element*> view,
|
||||||
Element *replacing) {
|
Element *replacing) {
|
||||||
_emojiInteractions->playPremiumEffect(view, replacing);
|
const auto already = !_emojiInteractions->playPremiumEffect(
|
||||||
|
view,
|
||||||
|
replacing);
|
||||||
_animatedStickersPlayed.emplace(view->data());
|
_animatedStickersPlayed.emplace(view->data());
|
||||||
|
if (already) {
|
||||||
|
_widget->showPremiumStickerTooltip(view);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::elementCancelPremium(not_null<const Element*> 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_group_call_bar.h"
|
||||||
#include "history/view/history_view_item_preview.h"
|
#include "history/view/history_view_item_preview.h"
|
||||||
#include "history/view/history_view_requests_bar.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 "history/view/media/history_view_media.h"
|
||||||
#include "profile/profile_block_group_members.h"
|
#include "profile/profile_block_group_members.h"
|
||||||
#include "info/info_memento.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(
|
void HistoryWidget::setFieldText(
|
||||||
const TextWithTags &textWithTags,
|
const TextWithTags &textWithTags,
|
||||||
TextUpdateEvents events,
|
TextUpdateEvents events,
|
||||||
|
@ -102,6 +102,7 @@ enum class MimeDataState;
|
|||||||
} // namespace Storage
|
} // namespace Storage
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
class StickerToast;
|
||||||
class TopBarWidget;
|
class TopBarWidget;
|
||||||
class ContactStatus;
|
class ContactStatus;
|
||||||
class Element;
|
class Element;
|
||||||
@ -277,6 +278,8 @@ public:
|
|||||||
const TextWithEntities &text,
|
const TextWithEntities &text,
|
||||||
Fn<void()> hiddenCallback);
|
Fn<void()> hiddenCallback);
|
||||||
void hideInfoTooltip(anim::type animated);
|
void hideInfoTooltip(anim::type animated);
|
||||||
|
void showPremiumStickerTooltip(
|
||||||
|
not_null<const HistoryView::Element*> view);
|
||||||
|
|
||||||
// Tabbed selector management.
|
// Tabbed selector management.
|
||||||
bool pushTabbedSelectorToThirdSection(
|
bool pushTabbedSelectorToThirdSection(
|
||||||
@ -798,6 +801,7 @@ private:
|
|||||||
base::Timer _saveCloudDraftTimer;
|
base::Timer _saveCloudDraftTimer;
|
||||||
|
|
||||||
base::weak_ptr<Ui::Toast::Instance> _topToast;
|
base::weak_ptr<Ui::Toast::Instance> _topToast;
|
||||||
|
std::unique_ptr<HistoryView::StickerToast> _stickerToast;
|
||||||
std::unique_ptr<ChooseMessagesForReport> _chooseForReport;
|
std::unique_ptr<ChooseMessagesForReport> _chooseForReport;
|
||||||
|
|
||||||
base::flat_set<not_null<HistoryItem*>> _itemRevealPending;
|
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,
|
not_null<const Element*> view,
|
||||||
Element *replacing) {
|
Element *replacing) {
|
||||||
const auto already = ranges::contains(_plays, view, &Play::view);
|
const auto already = ranges::contains(_plays, view, &Play::view);
|
||||||
@ -109,10 +109,10 @@ void EmojiInteractions::playPremiumEffect(
|
|||||||
//if (i->premium) {
|
//if (i->premium) {
|
||||||
// view->externalLottieProgressing(true);
|
// view->externalLottieProgressing(true);
|
||||||
//}
|
//}
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (already) {
|
} else if (already) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (const auto media = view->media()) {
|
if (const auto media = view->media()) {
|
||||||
if (const auto document = media->getDocument()) {
|
if (const auto document = media->getDocument()) {
|
||||||
@ -128,6 +128,7 @@ void EmojiInteractions::playPremiumEffect(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiInteractions::cancelPremiumEffect(not_null<const Element*> view) {
|
void EmojiInteractions::cancelPremiumEffect(not_null<const Element*> view) {
|
||||||
|
@ -37,7 +37,7 @@ public:
|
|||||||
void play(
|
void play(
|
||||||
ChatHelpers::EmojiInteractionPlayRequest request,
|
ChatHelpers::EmojiInteractionPlayRequest request,
|
||||||
not_null<Element*> view);
|
not_null<Element*> view);
|
||||||
void playPremiumEffect(
|
bool playPremiumEffect(
|
||||||
not_null<const Element*> view,
|
not_null<const Element*> view,
|
||||||
Element *replacing);
|
Element *replacing);
|
||||||
void cancelPremiumEffect(not_null<const Element*> view);
|
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;
|
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);
|
historyToDownPosition: point(12px, 10px);
|
||||||
historyToDownAbove: icon {{ "history_down_arrow", historyToDownFg }};
|
historyToDownAbove: icon {{ "history_down_arrow", historyToDownFg }};
|
||||||
historyToDownAboveOver: icon {{ "history_down_arrow", historyToDownFgOver }};
|
historyToDownAboveOver: icon {{ "history_down_arrow", historyToDownFgOver }};
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 79af7c5523ae59d4dd13cc2bde86bb8611bde11c
|
Subproject commit a78089716bf153b4283ec79757268d1047913f12
|
Loading…
Reference in New Issue
Block a user