Added animation for spoilers in sections.

This commit is contained in:
23rd 2021-12-24 13:01:58 +03:00 committed by John Preston
parent 938aa5d577
commit fa4d1d72c4
13 changed files with 111 additions and 1 deletions

View File

@ -671,6 +671,8 @@ PRIVATE
history/view/history_view_send_action.h
history/view/history_view_service_message.cpp
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_top_bar_widget.cpp
history/view/history_view_top_bar_widget.h
history/view/history_view_view_button.cpp

View File

@ -673,6 +673,11 @@ void InnerWidget::elementStartInteraction(not_null<const Element*> view) {
void InnerWidget::elementShowReactions(not_null<const Element*> view) {
}
void InnerWidget::elementShowSpoilerAnimation() {
_spoilerOpacity.stop();
_spoilerOpacity.start([=] { update(); }, 0., 1., st::fadeWrapDuration);
}
void InnerWidget::saveState(not_null<SectionMemento*> memento) {
memento->setFilter(std::move(_filter));
memento->setAdmins(std::move(_admins));

View File

@ -141,6 +141,7 @@ public:
not_null<const HistoryView::Element*> view) override;
void elementShowReactions(
not_null<const HistoryView::Element*> view) override;
void elementShowSpoilerAnimation() override;
~InnerWidget();
@ -324,6 +325,8 @@ private:
QPoint _trippleClickPoint;
base::Timer _trippleClickTimer;
Ui::Animations::Simple _spoilerOpacity;
FilterValue _filter;
QString _searchQuery;
std::vector<not_null<UserData*>> _admins;

View File

@ -2903,6 +2903,11 @@ void HistoryInner::elementShowReactions(not_null<const Element*> view) {
view->data()));
}
void HistoryInner::elementShowSpoilerAnimation() {
_spoilerOpacity.stop();
_spoilerOpacity.start([=] { update(); }, 0., 1., st::fadeWrapDuration);
}
auto HistoryInner::getSelectionState() const
-> HistoryView::TopBarWidget::SelectedState {
auto result = HistoryView::TopBarWidget::SelectedState {};
@ -3862,6 +3867,11 @@ not_null<HistoryView::ElementDelegate*> HistoryInner::ElementDelegate() {
Instance->elementShowReactions(view);
}
}
void elementShowSpoilerAnimation() override {
if (Instance) {
Instance->elementShowSpoilerAnimation();
}
}
};

View File

@ -126,6 +126,7 @@ public:
void elementReplyTo(const FullMsgId &to);
void elementStartInteraction(not_null<const Element*> view);
void elementShowReactions(not_null<const Element*> view);
void elementShowSpoilerAnimation();
void updateBotInfo(bool recount = true);
@ -446,6 +447,8 @@ private:
crl::time _touchTime = 0;
base::Timer _touchScrollTimer;
Ui::Animations::Simple _spoilerOpacity;
base::unique_qptr<Ui::PopupMenu> _menu;
bool _scrollDateShown = false;

View File

@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_service.h"
#include "history/view/history_view_service_message.h"
#include "history/view/history_view_context_menu.h" // CopyPostLink.
#include "history/view/history_view_spoiler_click_handler.h"
#include "history/view/media/history_view_media.h" // AddTimestampLinks.
#include "chat_helpers/stickers_emoji_pack.h"
#include "main/main_session.h"
@ -1618,6 +1619,7 @@ void HistoryMessage::setText(const TextWithEntities &textWithEntities) {
withLocalEntities(textWithEntities),
Ui::ItemTextOptions(this),
context);
HistoryView::FillTextWithAnimatedSpoilers(_text, textWithEntities);
if (!textWithEntities.text.isEmpty() && _text.isEmpty()) {
// If server has allowed some text that we've trim-ed entirely,
// just replace it with something so that UI won't look buggy.

View File

@ -191,6 +191,9 @@ void SimpleElementDelegate::elementShowReactions(
not_null<const Element*> view) {
}
void SimpleElementDelegate::elementShowSpoilerAnimation() {
}
TextSelection UnshiftItemSelection(
TextSelection selection,
uint16 byLength) {

View File

@ -100,6 +100,7 @@ public:
virtual void elementReplyTo(const FullMsgId &to) = 0;
virtual void elementStartInteraction(not_null<const Element*> view) = 0;
virtual void elementShowReactions(not_null<const Element*> view) = 0;
virtual void elementShowSpoilerAnimation() = 0;
virtual ~ElementDelegate() {
}
@ -158,6 +159,7 @@ public:
void elementReplyTo(const FullMsgId &to) override;
void elementStartInteraction(not_null<const Element*> view) override;
void elementShowReactions(not_null<const Element*> view) override;
void elementShowSpoilerAnimation() override;
protected:
[[nodiscard]] not_null<Window::SessionController*> controller() const {

View File

@ -1461,6 +1461,11 @@ void ListWidget::elementStartInteraction(not_null<const Element*> view) {
void ListWidget::elementShowReactions(not_null<const Element*> view) {
}
void ListWidget::elementShowSpoilerAnimation() {
_spoilerOpacity.stop();
_spoilerOpacity.start([=] { update(); }, 0., 1., st::fadeWrapDuration);
}
void ListWidget::saveState(not_null<ListMemento*> memento) {
memento->setAroundPosition(_aroundPosition);
auto state = countScrollState();

View File

@ -279,6 +279,7 @@ public:
void elementReplyTo(const FullMsgId &to) override;
void elementStartInteraction(not_null<const Element*> view) override;
void elementShowReactions(not_null<const Element*> view) override;
void elementShowSpoilerAnimation() override;
void setEmptyInfoWidget(base::unique_qptr<Ui::RpWidget> &&w);
@ -608,6 +609,8 @@ private:
FullMsgId _highlightedMessageId;
base::Timer _highlightTimer;
Ui::Animations::Simple _spoilerOpacity;
Ui::SelectScrollManager _selectScroll;
rpl::event_stream<FullMsgId> _requestedToEditMessage;

View File

@ -0,0 +1,53 @@
/*
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_spoiler_click_handler.h"
#include "core/click_handler_types.h" // ClickHandlerContext
#include "history/view/history_view_element.h"
#include "ui/spoiler_click_handler.h"
namespace HistoryView {
namespace {
class AnimatedSpoilerClickHandler final : public SpoilerClickHandler {
public:
AnimatedSpoilerClickHandler() = default;
void onClick(ClickContext context) const override;
};
void AnimatedSpoilerClickHandler::onClick(ClickContext context) const {
const auto button = context.button;
if (button != Qt::LeftButton) {
return;
}
const auto my = context.other.value<ClickHandlerContext>();
if (const auto d = my.elementDelegate ? my.elementDelegate() : nullptr) {
d->elementShowSpoilerAnimation();
const auto nonconst = const_cast<AnimatedSpoilerClickHandler*>(this);
nonconst->setStartMs(crl::now());
SpoilerClickHandler::onClick({});
}
}
} // namespace
void FillTextWithAnimatedSpoilers(
Ui::Text::String &text,
const TextWithEntities &textWithEntities) {
for (auto i = 0; i < textWithEntities.entities.size(); i++) {
if (textWithEntities.entities[i].type() == EntityType::Spoiler) {
text.setSpoiler(
i + 1,
std::make_shared<AnimatedSpoilerClickHandler>());
}
}
}
} // namespace HistoryView

View File

@ -0,0 +1,16 @@
/*
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
namespace HistoryView {
void FillTextWithAnimatedSpoilers(
Ui::Text::String &text,
const TextWithEntities &textWithEntities);
} // namespace HistoryView

View File

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item.h"
#include "history/view/history_view_element.h"
#include "history/view/history_view_cursor_state.h"
#include "history/view/history_view_spoiler_click_handler.h"
#include "lottie/lottie_single_player.h"
#include "storage/storage_shared_media.h"
#include "data/data_document.h"
@ -196,11 +197,13 @@ Ui::Text::String Media::createCaption(not_null<HistoryItem*> item) const {
const auto context = Core::MarkedTextContext{
.session = &history()->session()
};
const auto textWithEntities = item->originalTextWithLocalEntities();
result.setMarkedText(
st::messageTextStyle,
item->originalTextWithLocalEntities(),
textWithEntities,
Ui::ItemTextOptions(item),
context);
FillTextWithAnimatedSpoilers(result, textWithEntities);
if (const auto width = _parent->skipBlockWidth()) {
result.updateSkipBlock(width, _parent->skipBlockHeight());
}