Animate topic icons only twice in topics list.

This commit is contained in:
John Preston 2022-11-07 14:25:43 +04:00
parent d8a0497a7e
commit 6e606f3bb6
6 changed files with 81 additions and 7 deletions

View file

@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_folder.h" #include "data/data_folder.h"
#include "data/data_forum.h" #include "data/data_forum.h"
#include "data/data_forum_icons.h"
#include "data/data_location.h" #include "data/data_location.h"
#include "data/data_histories.h" #include "data/data_histories.h"
#include "data/data_group_call.h" #include "data/data_group_call.h"
@ -164,8 +165,9 @@ void ChannelData::setFlags(ChannelDataFlags which) {
const auto taken = ((diff & Flag::Forum) && !(which & Flag::Forum)) const auto taken = ((diff & Flag::Forum) && !(which & Flag::Forum))
? mgInfo->takeForumData() ? mgInfo->takeForumData()
: nullptr; : nullptr;
if (const auto raw = taken.get()) {
if ((diff & Flag::Forum) && (which & Flag::Forum)) { owner().forumIcons().clearUserpicsReset(taken.get());
} else if ((diff & Flag::Forum) && (which & Flag::Forum)) {
mgInfo->ensureForum(this); mgInfo->ensureForum(this);
} }
_flags.set(which); _flags.set(which);

View file

@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h" #include "main/main_session.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_document.h" #include "data/data_document.h"
#include "data/data_forum.h"
#include "data/data_forum_topic.h"
#include "apiwrap.h" #include "apiwrap.h"
namespace Data { namespace Data {
@ -22,7 +24,8 @@ constexpr auto kMaxTimeout = 6 * 60 * 60 * crl::time(1000);
} // namespace } // namespace
ForumIcons::ForumIcons(not_null<Session*> owner) ForumIcons::ForumIcons(not_null<Session*> owner)
: _owner(owner) { : _owner(owner)
, _resetUserpicsTimer([=] { resetUserpics(); }) {
} }
ForumIcons::~ForumIcons() = default; ForumIcons::~ForumIcons() = default;
@ -79,4 +82,45 @@ void ForumIcons::updateDefault(const MTPDmessages_stickerSet &data) {
_defaultUpdated.fire({}); _defaultUpdated.fire({});
} }
void ForumIcons::scheduleUserpicsReset(not_null<Forum*> forum) {
const auto duration = crl::time(st::slideDuration);
_resetUserpicsWhen[forum] = crl::now() + duration;
if (!_resetUserpicsTimer.isActive()) {
_resetUserpicsTimer.callOnce(duration);
}
}
void ForumIcons::clearUserpicsReset(not_null<Forum*> forum) {
_resetUserpicsWhen.remove(forum);
}
void ForumIcons::resetUserpics() {
auto nearest = crl::time();
auto now = crl::now();
for (auto i = begin(_resetUserpicsWhen); i != end(_resetUserpicsWhen);) {
if (i->second > now) {
if (!nearest || nearest > i->second) {
nearest = i->second;
}
++i;
} else {
const auto forum = i->first;
i = _resetUserpicsWhen.erase(i);
resetUserpicsFor(forum);
}
}
if (nearest) {
_resetUserpicsTimer.callOnce(
std::min(nearest - now, 86400 * crl::time(1000)));
} else {
_resetUserpicsTimer.cancel();
}
}
void ForumIcons::resetUserpicsFor(not_null<Forum*> forum) {
forum->enumerateTopics([](not_null<ForumTopic*> topic) {
topic->clearUserpicLoops();
});
}
} // namespace Data } // namespace Data

View file

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#pragma once #pragma once
#include "base/timer.h"
namespace Main { namespace Main {
class Session; class Session;
} // namespace Main } // namespace Main
@ -15,6 +17,7 @@ namespace Data {
class DocumentMedia; class DocumentMedia;
class Session; class Session;
class Forum;
class ForumIcons final { class ForumIcons final {
public: public:
@ -33,8 +36,13 @@ public:
[[nodiscard]] rpl::producer<> defaultUpdates() const; [[nodiscard]] rpl::producer<> defaultUpdates() const;
void scheduleUserpicsReset(not_null<Forum*> forum);
void clearUserpicsReset(not_null<Forum*> forum);
private: private:
void requestDefault(); void requestDefault();
void resetUserpics();
void resetUserpicsFor(not_null<Forum*> forum);
void updateDefault(const MTPDmessages_stickerSet &data); void updateDefault(const MTPDmessages_stickerSet &data);
@ -45,6 +53,9 @@ private:
mtpRequestId _defaultRequestId = 0; mtpRequestId _defaultRequestId = 0;
base::flat_map<not_null<Forum*>, crl::time> _resetUserpicsWhen;
base::Timer _resetUserpicsTimer;
rpl::lifetime _lifetime; rpl::lifetime _lifetime;
}; };

View file

@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/unixtime.h" #include "base/unixtime.h"
#include "ui/painter.h" #include "ui/painter.h"
#include "ui/color_int_conversion.h" #include "ui/color_int_conversion.h"
#include "ui/text/text_custom_emoji.h"
#include "styles/style_dialogs.h" #include "styles/style_dialogs.h"
#include "styles/style_chat_helpers.h" #include "styles/style_chat_helpers.h"
@ -41,6 +42,8 @@ namespace {
using UpdateFlag = TopicUpdate::Flag; using UpdateFlag = TopicUpdate::Flag;
constexpr auto kUserpicLoopsCount = 2;
} // namespace } // namespace
const base::flat_map<int32, QString> &ForumTopicIcons() { const base::flat_map<int32, QString> &ForumTopicIcons() {
@ -544,6 +547,12 @@ void ForumTopic::paintUserpic(
} }
} }
void ForumTopic::clearUserpicLoops() {
if (_icon) {
_icon->unload();
}
}
void ForumTopic::validateDefaultIcon() const { void ForumTopic::validateDefaultIcon() const {
if (_defaultIcon.isNull()) { if (_defaultIcon.isNull()) {
_defaultIcon = ForumTopicIconFrame( _defaultIcon = ForumTopicIconFrame(
@ -629,10 +638,12 @@ void ForumTopic::applyIconId(DocumentId iconId) {
} }
_iconId = iconId; _iconId = iconId;
_icon = iconId _icon = iconId
? owner().customEmojiManager().create( ? std::make_unique<Ui::Text::LimitedLoopsEmoji>(
_iconId, owner().customEmojiManager().create(
[=] { updateChatListEntry(); }, _iconId,
Data::CustomEmojiManager::SizeTag::Normal) [=] { updateChatListEntry(); },
Data::CustomEmojiManager::SizeTag::Normal),
kUserpicLoopsCount)
: nullptr; : nullptr;
if (iconId) { if (iconId) {
_defaultIcon = QImage(); _defaultIcon = QImage();

View file

@ -138,6 +138,7 @@ public:
Painter &p, Painter &p,
std::shared_ptr<CloudImageView> &view, std::shared_ptr<CloudImageView> &view,
const Dialogs::Ui::PaintContext &context) const override; const Dialogs::Ui::PaintContext &context) const override;
void clearUserpicLoops();
[[nodiscard]] bool isServerSideUnread( [[nodiscard]] bool isServerSideUnread(
not_null<const HistoryItem*> item) const override; not_null<const HistoryItem*> item) const override;

View file

@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_drafts.h" #include "data/data_drafts.h"
#include "data/data_folder.h" #include "data/data_folder.h"
#include "data/data_forum.h" #include "data/data_forum.h"
#include "data/data_forum_icons.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_channel.h" #include "data/data_channel.h"
#include "data/data_forum_topic.h" #include "data/data_forum_topic.h"
@ -428,6 +429,10 @@ void InnerWidget::changeOpenedForum(ChannelData *forum) {
_filterId = forum _filterId = forum
? 0 ? 0
: _controller->activeChatsFilterCurrent(); : _controller->activeChatsFilterCurrent();
if (const auto old = now ? now->forum() : nullptr) {
// If we close it inside forum destruction we should not schedule.
old->owner().forumIcons().scheduleUserpicsReset(old);
}
_openedForum = forum ? forum->forum() : nullptr; _openedForum = forum ? forum->forum() : nullptr;
_st = forum ? &st::forumTopicRow : &st::defaultDialogRow; _st = forum ? &st::forumTopicRow : &st::defaultDialogRow;