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_folder.h"
#include "data/data_forum.h"
#include "data/data_forum_icons.h"
#include "data/data_location.h"
#include "data/data_histories.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))
? mgInfo->takeForumData()
: nullptr;
if ((diff & Flag::Forum) && (which & Flag::Forum)) {
if (const auto raw = taken.get()) {
owner().forumIcons().clearUserpicsReset(taken.get());
} else if ((diff & Flag::Forum) && (which & Flag::Forum)) {
mgInfo->ensureForum(this);
}
_flags.set(which);

View File

@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "data/data_session.h"
#include "data/data_document.h"
#include "data/data_forum.h"
#include "data/data_forum_topic.h"
#include "apiwrap.h"
namespace Data {
@ -22,7 +24,8 @@ constexpr auto kMaxTimeout = 6 * 60 * 60 * crl::time(1000);
} // namespace
ForumIcons::ForumIcons(not_null<Session*> owner)
: _owner(owner) {
: _owner(owner)
, _resetUserpicsTimer([=] { resetUserpics(); }) {
}
ForumIcons::~ForumIcons() = default;
@ -79,4 +82,45 @@ void ForumIcons::updateDefault(const MTPDmessages_stickerSet &data) {
_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

View File

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

View File

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

View File

@ -138,6 +138,7 @@ public:
Painter &p,
std::shared_ptr<CloudImageView> &view,
const Dialogs::Ui::PaintContext &context) const override;
void clearUserpicLoops();
[[nodiscard]] bool isServerSideUnread(
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_folder.h"
#include "data/data_forum.h"
#include "data/data_forum_icons.h"
#include "data/data_session.h"
#include "data/data_channel.h"
#include "data/data_forum_topic.h"
@ -428,6 +429,10 @@ void InnerWidget::changeOpenedForum(ChannelData *forum) {
_filterId = forum
? 0
: _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;
_st = forum ? &st::forumTopicRow : &st::defaultDialogRow;