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); return (top < till && bottom > from);
} }
bool InnerWidget::elementStartStickerLoop(not_null<const Element*> view) { void 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::saveState(not_null<SectionMemento*> memento) { void InnerWidget::saveState(not_null<SectionMemento*> memento) {

View File

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

View File

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

View File

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

View File

@ -133,6 +133,8 @@ public:
} }
virtual void stopAnimation() { virtual void stopAnimation() {
} }
virtual void clearStickerLoopPlayed() {
}
[[nodiscard]] virtual QSize sizeForGrouping() const { [[nodiscard]] virtual QSize sizeForGrouping() const {
Unexpected("Grouping method call."); 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 "history/view/history_view_cursor_state.h"
#include "ui/image/image.h" #include "ui/image/image.h"
#include "ui/emoji_config.h" #include "ui/emoji_config.h"
#include "main/main_session.h"
#include "mainwindow.h" // App::wnd()->sessionController. #include "mainwindow.h" // App::wnd()->sessionController.
#include "window/window_session_controller.h" // isGifPausedAtLeastFor. #include "window/window_session_controller.h" // isGifPausedAtLeastFor.
#include "data/data_session.h" #include "data/data_session.h"
@ -212,12 +213,14 @@ void HistorySticker::draw(
frame.image); frame.image);
const auto paused = App::wnd()->sessionController()->isGifPausedAtLeastFor(Window::GifPauseReason::Any); const auto paused = App::wnd()->sessionController()->isGifPausedAtLeastFor(Window::GifPauseReason::Any);
const auto playOnce = !_data->session().settings().loopAnimatedStickers();
if (!paused if (!paused
&& (frame.index != 0 && (!playOnce || frame.index != 0 || !_lottieOncePlayed)
|| _parent->delegate()->elementStartStickerLoop(_parent))
&& _lottie->markFrameShown() && _lottie->markFrameShown()
&& !frame.index) { && playOnce
_parent->delegate()->elementStickerLoopStarted(_parent); && !_lottieOncePlayed) {
_lottieOncePlayed = true;
_parent->delegate()->elementStartStickerLoop(_parent);
} }
} }
if (!inWebPage) { if (!inWebPage) {

View File

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

View File

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

View File

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

View File

@ -1141,15 +1141,7 @@ bool ListWidget::elementIntersectsRange(
return (top < till && bottom > from); return (top < till && bottom > from);
} }
bool ListWidget::elementStartStickerLoop(not_null<const Element*> view) { void 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::saveState(not_null<ListMemento*> memento) { void ListWidget::saveState(not_null<ListMemento*> memento) {

View File

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