Improve storing of played animated stickers.

This commit is contained in:
John Preston 2019-08-01 13:55:14 +01:00
parent 708b1d7ad4
commit 4b7b1c35e1
11 changed files with 37 additions and 60 deletions

View File

@ -548,15 +548,7 @@ bool InnerWidget::elementIntersectsRange(
return (top < till && bottom > from);
}
bool InnerWidget::elementStartStickerLoop(not_null<const Element*> view) {
if (_controller->session().settings().loopAnimatedStickers()) {
return true;
}
return !_animatedStickersPlayed.contains(view->data()->fullId());
}
void InnerWidget::elementStickerLoopStarted(not_null<const Element*> view) {
_animatedStickersPlayed.emplace(view->data()->fullId());
void InnerWidget::elementStartStickerLoop(not_null<const Element*> view) {
}
void InnerWidget::saveState(not_null<SectionMemento*> memento) {

View File

@ -99,9 +99,7 @@ public:
not_null<const HistoryView::Element*> view,
int from,
int till) override;
bool elementStartStickerLoop(
not_null<const HistoryView::Element*> view) override;
void elementStickerLoopStarted(
void elementStartStickerLoop(
not_null<const HistoryView::Element*> view) override;
~InnerWidget();

View File

@ -1245,6 +1245,8 @@ void HistoryInner::itemRemoved(not_null<const HistoryItem*> item) {
return;
}
_animatedStickersPlayed.remove(item);
auto i = _selected.find(item);
if (i != _selected.cend()) {
_selected.erase(i);
@ -2267,6 +2269,13 @@ void HistoryInner::leaveEventHook(QEvent *e) {
}
HistoryInner::~HistoryInner() {
for (const auto &item : _animatedStickersPlayed) {
if (const auto view = item->mainView()) {
if (const auto media = view->media()) {
media->clearStickerLoopPlayed();
}
}
}
if (Instance == this) {
Instance = nullptr;
}
@ -2384,16 +2393,9 @@ bool HistoryInner::elementIntersectsRange(
return (top < till && bottom > from);
}
bool HistoryInner::elementStartStickerLoop(
not_null<const Element*> view) const {
return _controller->session().settings().loopAnimatedStickers()
|| !_animatedStickersPlayed.contains(view->data()->fullId());
}
void HistoryInner::elementStickerLoopStarted(not_null<const Element*> view) {
if (!_controller->session().settings().loopAnimatedStickers()) {
_animatedStickersPlayed.emplace(view->data()->fullId());
}
void HistoryInner::elementStartStickerLoop(
not_null<const Element*> view) {
_animatedStickersPlayed.emplace(view->data());
}
auto HistoryInner::getSelectionState() const
@ -3246,16 +3248,10 @@ not_null<HistoryView::ElementDelegate*> HistoryInner::ElementDelegate() {
? Instance->elementIntersectsRange(view, from, till)
: false;
}
bool elementStartStickerLoop(
not_null<const Element*> view) override {
return Instance
? Instance->elementStartStickerLoop(view)
: true;
}
void elementStickerLoopStarted(
void elementStartStickerLoop(
not_null<const Element*> view) override {
if (Instance) {
Instance->elementStickerLoopStarted(view);
Instance->elementStartStickerLoop(view);
}
}

View File

@ -79,8 +79,7 @@ public:
not_null<const Element*> view,
int from,
int till) const;
bool elementStartStickerLoop(not_null<const Element*> view) const;
void elementStickerLoopStarted(not_null<const Element*> view);
void elementStartStickerLoop(not_null<const Element*> view);
void updateBotInfo(bool recount = true);
@ -332,7 +331,7 @@ private:
style::cursor _cursor = style::cur_default;
SelectedItems _selected;
base::flat_set<FullMsgId> _animatedStickersPlayed;
base::flat_set<not_null<const HistoryItem*>> _animatedStickersPlayed;
MouseAction _mouseAction = MouseAction::None;
TextSelectType _mouseSelectType = TextSelectType::Letters;

View File

@ -133,6 +133,8 @@ public:
}
virtual void stopAnimation() {
}
virtual void clearStickerLoopPlayed() {
}
[[nodiscard]] virtual QSize sizeForGrouping() const {
Unexpected("Grouping method call.");

View File

@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_cursor_state.h"
#include "ui/image/image.h"
#include "ui/emoji_config.h"
#include "main/main_session.h"
#include "mainwindow.h" // App::wnd()->sessionController.
#include "window/window_session_controller.h" // isGifPausedAtLeastFor.
#include "data/data_session.h"
@ -212,12 +213,14 @@ void HistorySticker::draw(
frame.image);
const auto paused = App::wnd()->sessionController()->isGifPausedAtLeastFor(Window::GifPauseReason::Any);
const auto playOnce = !_data->session().settings().loopAnimatedStickers();
if (!paused
&& (frame.index != 0
|| _parent->delegate()->elementStartStickerLoop(_parent))
&& (!playOnce || frame.index != 0 || !_lottieOncePlayed)
&& _lottie->markFrameShown()
&& !frame.index) {
_parent->delegate()->elementStickerLoopStarted(_parent);
&& playOnce
&& !_lottieOncePlayed) {
_lottieOncePlayed = true;
_parent->delegate()->elementStartStickerLoop(_parent);
}
}
if (!inWebPage) {

View File

@ -54,6 +54,9 @@ public:
bool hidesForwardedInfo() const override {
return true;
}
void clearStickerLoopPlayed() override {
_lottieOncePlayed = false;
}
void unloadHeavyPart() override {
unloadLottie();
@ -76,6 +79,8 @@ private:
not_null<DocumentData*> _data;
QString _emoji;
std::unique_ptr<Lottie::SinglePlayer> _lottie;
mutable bool _lottieOncePlayed = false;
rpl::lifetime _lifetime;
};

View File

@ -84,12 +84,7 @@ bool SimpleElementDelegate::elementIntersectsRange(
return true;
}
bool SimpleElementDelegate::elementStartStickerLoop(
not_null<const Element*> view) {
return true;
}
void SimpleElementDelegate::elementStickerLoopStarted(
void SimpleElementDelegate::elementStartStickerLoop(
not_null<const Element*> view) {
}

View File

@ -50,9 +50,7 @@ public:
not_null<const Element*> view,
int from,
int till) = 0;
virtual bool elementStartStickerLoop(not_null<const Element*> view) = 0;
virtual void elementStickerLoopStarted(
not_null<const Element*> view) = 0;
virtual void elementStartStickerLoop(not_null<const Element*> view) = 0;
};
@ -72,9 +70,7 @@ public:
not_null<const Element*> view,
int from,
int till) override;
bool elementStartStickerLoop(
not_null<const Element*> view) override;
void elementStickerLoopStarted(not_null<const Element*> view) override;
void elementStartStickerLoop(not_null<const Element*> view) override;
};

View File

@ -1141,15 +1141,7 @@ bool ListWidget::elementIntersectsRange(
return (top < till && bottom > from);
}
bool ListWidget::elementStartStickerLoop(not_null<const Element*> view) {
return _controller->session().settings().loopAnimatedStickers()
|| !_animatedStickersPlayed.contains(view->data()->fullId());
}
void ListWidget::elementStickerLoopStarted(not_null<const Element*> view) {
if (!_controller->session().settings().loopAnimatedStickers()) {
_animatedStickersPlayed.emplace(view->data()->fullId());
}
void ListWidget::elementStartStickerLoop(not_null<const Element*> view) {
}
void ListWidget::saveState(not_null<ListMemento*> memento) {

View File

@ -191,8 +191,7 @@ public:
not_null<const Element*> view,
int from,
int till) override;
bool elementStartStickerLoop(not_null<const Element*> view) override;
void elementStickerLoopStarted(not_null<const Element*> view) override;
void elementStartStickerLoop(not_null<const Element*> view) override;
~ListWidget();