Track stories deletion and refresh views.

This commit is contained in:
John Preston 2023-06-30 11:48:18 +04:00
parent 1d5b57c39c
commit 074a4e3c92
6 changed files with 64 additions and 6 deletions

View File

@ -1991,7 +1991,10 @@ MediaStory::MediaStory(
: Media(parent)
, _storyId(storyId)
, _mention(mention) {
const auto stories = &parent->history()->owner().stories();
const auto owner = &parent->history()->owner();
owner->registerStoryItem(storyId, parent);
const auto stories = &owner->stories();
if (const auto maybeStory = stories->lookup(storyId)) {
if (!_mention) {
parent->setText((*maybeStory)->caption());
@ -2017,6 +2020,11 @@ MediaStory::MediaStory(
}
}
MediaStory::~MediaStory() {
const auto owner = &parent()->history()->owner();
owner->unregisterStoryItem(_storyId, parent());
}
std::unique_ptr<Media> MediaStory::clone(not_null<HistoryItem*> parent) {
return std::make_unique<MediaStory>(parent, _storyId, false);
}

View File

@ -575,6 +575,7 @@ public:
not_null<HistoryItem*> parent,
FullStoryId storyId,
bool mention);
~MediaStory();
std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override;

View File

@ -194,4 +194,13 @@ struct hash<MsgId> : private hash<int64> {
}
};
template <>
struct hash<FullStoryId> {
size_t operator()(FullStoryId value) const {
return QtPrivate::QHashCombine().operator()(
std::hash<BareId>()(value.peer.value),
value.story);
}
};
} // namespace std

View File

@ -3881,6 +3881,33 @@ void Session::destroyAllCallItems() {
}
}
void Session::registerStoryItem(
FullStoryId id,
not_null<HistoryItem*> item) {
_storyItems[id].emplace(item);
}
void Session::unregisterStoryItem(
FullStoryId id,
not_null<HistoryItem*> item) {
const auto i = _storyItems.find(id);
if (i != _storyItems.end()) {
auto &items = i->second;
if (items.remove(item) && items.empty()) {
_storyItems.erase(i);
}
}
}
void Session::refreshStoryItemViews(FullStoryId id) {
const auto i = _storyItems.find(id);
if (i != _storyItems.end()) {
for (const auto item : i->second) {
requestItemViewRefresh(item);
}
}
}
void Session::documentMessageRemoved(not_null<DocumentData*> document) {
if (_documentItems.find(document) != _documentItems.end()) {
return;

View File

@ -637,6 +637,9 @@ public:
not_null<HistoryItem*> item);
void registerCallItem(not_null<HistoryItem*> item);
void unregisterCallItem(not_null<HistoryItem*> item);
void registerStoryItem(FullStoryId id, not_null<HistoryItem*> item);
void unregisterStoryItem(FullStoryId id, not_null<HistoryItem*> item);
void refreshStoryItemViews(FullStoryId id);
void documentMessageRemoved(not_null<DocumentData*> document);
@ -949,6 +952,9 @@ private:
UserId,
base::flat_set<not_null<ViewElement*>>> _contactViews;
std::unordered_set<not_null<HistoryItem*>> _callItems;
std::unordered_map<
FullStoryId,
base::flat_set<not_null<HistoryItem*>>> _storyItems;
base::flat_set<not_null<WebPageData*>> _webpagesUpdated;
base::flat_set<not_null<GameData*>> _gamesUpdated;

View File

@ -331,6 +331,7 @@ Story *Stories::parseAndApply(
return nullptr;
}
const auto id = data.vid().v;
const auto fullId = FullStoryId{ peer->id, id };
auto &stories = _stories[peer->id];
const auto i = stories.find(id);
if (i != end(stories)) {
@ -349,7 +350,6 @@ Story *Stories::parseAndApply(
}
}
if (mediaChanged) {
const auto fullId = result->fullId();
_preloaded.remove(fullId);
if (_preloading && _preloading->id() == fullId) {
_preloading = nullptr;
@ -357,9 +357,11 @@ Story *Stories::parseAndApply(
rebuildPreloadSources(StorySourcesList::Hidden);
continuePreloading();
}
_owner->refreshStoryItemViews(fullId);
}
return result;
}
const auto wasDeleted = _deleted.remove(fullId);
const auto result = stories.emplace(id, std::make_unique<Story>(
id,
peer,
@ -382,10 +384,14 @@ Story *Stories::parseAndApply(
}
if (expired) {
_expiring.remove(expires, result->fullId());
applyExpired(result->fullId());
_expiring.remove(expires, fullId);
applyExpired(fullId);
} else {
registerExpiring(expires, result->fullId());
registerExpiring(expires, fullId);
}
if (wasDeleted) {
_owner->refreshStoryItemViews(fullId);
}
return result;
@ -605,7 +611,7 @@ void Stories::finalizeResolve(FullStoryId id) {
void Stories::applyDeleted(FullStoryId id) {
applyRemovedFromActive(id);
_deleted.emplace(id);
_deleted.emplace(id).second;
const auto i = _stories.find(id.peer);
if (i != end(_stories)) {
const auto j = i->second.find(id.story);
@ -639,6 +645,7 @@ void Stories::applyDeleted(FullStoryId id) {
if (_preloading && _preloading->id() == id) {
preloadFinished(id);
}
_owner->refreshStoryItemViews(id);
if (i->second.empty()) {
_stories.erase(i);
}