Added animated reactions in manage of groups / channels.

This commit is contained in:
23rd 2022-04-17 12:33:29 +03:00 committed by John Preston
parent 1ed7d482ab
commit e37866d0b9
6 changed files with 27 additions and 86 deletions

View File

@ -7,92 +7,26 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "boxes/peers/edit_peer_reactions.h"
#include "boxes/reactions_settings_box.h" // AddReactionLottieIcon
#include "data/data_message_reactions.h"
#include "data/data_document.h"
#include "data/data_document_media.h"
#include "data/data_peer.h"
#include "data/data_chat.h"
#include "data/data_channel.h"
#include "data/data_session.h"
#include "main/main_session.h"
#include "apiwrap.h"
#include "lottie/lottie_icon.h"
#include "lang/lang_keys.h"
#include "ui/layers/generic_box.h"
#include "ui/widgets/buttons.h"
#include "info/profile/info_profile_icon.h"
#include "settings/settings_common.h"
#include "styles/style_settings.h"
#include "styles/style_info.h"
namespace {
using Data::Reaction;
void AddReactionIcon(
not_null<Ui::RpWidget*> button,
not_null<DocumentData*> document) {
struct State {
std::shared_ptr<Data::DocumentMedia> media;
std::unique_ptr<Lottie::Icon> icon;
QImage image;
};
const auto size = st::editPeerReactionsPreview;
const auto state = button->lifetime().make_state<State>(State{
.media = document->createMediaView(),
});
const auto icon = Ui::CreateChild<Ui::RpWidget>(button.get());
icon->setAttribute(Qt::WA_TransparentForMouseEvents);
icon->resize(size, size);
button->sizeValue(
) | rpl::start_with_next([=](QSize size) {
icon->moveToLeft(
st::editPeerReactionsIconLeft,
(size.height() - icon->height()) / 2,
size.width());
}, icon->lifetime());
const auto initLottie = [=] {
state->icon = Lottie::MakeIcon({
.path = state->media->owner()->filepath(true),
.json = state->media->bytes(),
.sizeOverride = QSize(size, size),
.frame = -1,
});
state->media = nullptr;
};
state->media->checkStickerLarge();
if (state->media->loaded()) {
initLottie();
} else {
document->session().downloaderTaskFinished(
) | rpl::filter([=] {
return state->media->loaded();
}) | rpl::take(1) | rpl::start_with_next([=] {
initLottie();
icon->update();
}, icon->lifetime());
}
icon->paintRequest(
) | rpl::start_with_next([=] {
QPainter p(icon);
if (state->image.isNull() && state->icon) {
state->image = state->icon->frame();
crl::async([icon = std::move(state->icon)]{});
}
if (!state->image.isNull()) {
p.drawImage(QRect(0, 0, size, size), state->image);
}
}, icon->lifetime());
}
} // namespace
void EditAllowedReactionsBox(
not_null<Ui::GenericBox*> box,
bool isGroup,
const std::vector<Reaction> &list,
const std::vector<Data::Reaction> &list,
const base::flat_set<QString> &selected,
Fn<void(const std::vector<QString> &)> callback) {
box->setTitle(tr::lng_manage_peer_reactions());
@ -153,9 +87,23 @@ void EditAllowedReactionsBox(
container,
rpl::single(entry.title),
st::manageGroupButton.button);
AddReactionIcon(button, entry.centerIcon
? entry.centerIcon
: entry.appearAnimation.get());
const auto iconHeight = st::editPeerReactionsPreview;
AddReactionLottieIcon(
button,
button->sizeValue(
) | rpl::map([=](const QSize &size) {
return QPoint(
st::editPeerReactionsIconLeft,
(size.height() - iconHeight) / 2);
}),
iconHeight,
entry,
button->events(
) | rpl::filter([=](not_null<QEvent*> event) {
return event->type() == QEvent::Enter;
}) | rpl::to_empty,
rpl::never<>(),
&button->lifetime());
state->toggles.emplace(entry.emoji, button);
button->toggleOn(rpl::single(
active(entry)

View File

@ -7,14 +7,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "ui/layers/generic_box.h"
class PeerData;
namespace Data {
struct Reaction;
} // namespace Data
namespace Ui {
class GenericBox;
} // namespace Ui
void EditAllowedReactionsBox(
not_null<Ui::GenericBox*> box,
bool isGroup,

View File

@ -234,7 +234,6 @@ void AddMessage(
(rightSize.height() - iconSize) / 2);
}),
iconSize,
&controller->session(),
r,
rpl::never<>(),
rpl::duplicate(emojiValue) | rpl::skip(1) | rpl::to_empty,
@ -251,7 +250,6 @@ void AddReactionLottieIcon(
not_null<Ui::RpWidget*> parent,
rpl::producer<QPoint> iconPositionValue,
int iconSize,
not_null<Main::Session*> session,
const Data::Reaction &reaction,
rpl::producer<> &&selects,
rpl::producer<> &&destroys,
@ -280,7 +278,7 @@ void AddReactionLottieIcon(
state->appear.media->checkStickerLarge();
state->select.media->checkStickerLarge();
rpl::single() | rpl::then(
session->downloaderTaskFinished()
reaction.appearAnimation->session().downloaderTaskFinished()
) | rpl::start_with_next([=] {
const auto check = [&](State::Entry &entry) {
if (!entry.media) {
@ -448,7 +446,6 @@ void ReactionsSettingsBox(
(s.height() - iconSize) / 2);
}),
iconSize,
&controller->session(),
r,
button->events(
) | rpl::filter([=](not_null<QEvent*> event) {

View File

@ -16,10 +16,6 @@ namespace Window {
class SessionController;
} // namespace Window
namespace Main {
class Session;
} // namespace Main
namespace Data {
struct Reaction;
} // namespace Data
@ -28,7 +24,6 @@ void AddReactionLottieIcon(
not_null<Ui::RpWidget*> parent,
rpl::producer<QPoint> iconPositionValue,
int iconSize,
not_null<Main::Session*> session,
const Data::Reaction &reaction,
rpl::producer<> &&selects,
rpl::producer<> &&destroys,

View File

@ -657,8 +657,8 @@ editPeerInviteLinkBoxBottomSkip: 15px;
editPeerReactionsButton: SettingsButton(infoProfileButton) {
padding: margins(59px, 13px, 8px, 11px);
}
editPeerReactionsPreview: 48px;
editPeerReactionsIconLeft: 12px;
editPeerReactionsPreview: 24px;
editPeerReactionsIconLeft: 21px;
historyTopBarBack: IconButton(infoTopBarBack) {
width: 52px;

View File

@ -903,7 +903,6 @@ void SetupMessages(
r.top() + (r.height() - iconSize) / 2);
}),
iconSize,
&controller->session(),
r,
buttonRight->events(
) | rpl::filter([=](not_null<QEvent*> event) {