Mark as read recent stories in profile top bar.

This commit is contained in:
John Preston 2023-07-14 11:24:13 +04:00
parent 74014d18a5
commit 3c28e7b585
3 changed files with 59 additions and 25 deletions

View File

@ -148,19 +148,19 @@ struct TopicUpdate {
enum class Flag : uint32 {
None = 0,
UnreadView = (1U << 1),
UnreadMentions = (1U << 2),
UnreadView = (1U << 1),
UnreadMentions = (1U << 2),
UnreadReactions = (1U << 3),
Notifications = (1U << 4),
Title = (1U << 5),
IconId = (1U << 6),
ColorId = (1U << 7),
CloudDraft = (1U << 8),
Closed = (1U << 9),
Creator = (1U << 10),
Destroyed = (1U << 11),
Notifications = (1U << 4),
Title = (1U << 5),
IconId = (1U << 6),
ColorId = (1U << 7),
CloudDraft = (1U << 8),
Closed = (1U << 9),
Creator = (1U << 10),
Destroyed = (1U << 11),
LastUsedBit = (1U << 11),
LastUsedBit = (1U << 11),
};
using Flags = base::flags<Flag>;
friend inline constexpr auto is_flag_type(Flag) { return true; }
@ -199,14 +199,14 @@ struct EntryUpdate {
enum class Flag : uint32 {
None = 0,
Repaint = (1U << 0),
Repaint = (1U << 0),
HasPinnedMessages = (1U << 1),
ForwardDraft = (1U << 2),
LocalDraftSet = (1U << 3),
Height = (1U << 4),
Destroyed = (1U << 5),
ForwardDraft = (1U << 2),
LocalDraftSet = (1U << 3),
Height = (1U << 4),
Destroyed = (1U << 5),
LastUsedBit = (1U << 5),
LastUsedBit = (1U << 5),
};
using Flags = base::flags<Flag>;
friend inline constexpr auto is_flag_type(Flag) { return true; }
@ -220,12 +220,13 @@ struct StoryUpdate {
enum class Flag : uint32 {
None = 0,
Edited = (1U << 0),
Destroyed = (1U << 1),
NewAdded = (1U << 2),
ViewsAdded = (1U << 3),
Edited = (1U << 0),
Destroyed = (1U << 1),
NewAdded = (1U << 2),
ViewsAdded = (1U << 3),
MarkRead = (1U << 4),
LastUsedBit = (1U << 3),
LastUsedBit = (1U << 4),
};
using Flags = base::flags<Flag>;
friend inline constexpr auto is_flag_type(Flag) { return true; }

View File

@ -928,7 +928,10 @@ bool Stories::bumpReadTill(PeerId peerId, StoryId maxReadTill) {
refreshItems = ranges::make_subrange(
i->second.lower_bound(from + 1),
i->second.lower_bound(till + 1)
) | ranges::views::transform([](const auto &pair) {
) | ranges::views::transform([=](const auto &pair) {
_owner->session().changes().storyUpdated(
pair.second.get(),
StoryUpdate::Flag::MarkRead);
return pair.first;
}) | ranges::to_vector;
}

View File

@ -402,17 +402,25 @@ rpl::producer<Content> LastForPeer(not_null<PeerData*> peer) {
}
return rpl::make_producer<Content>([=](auto consumer) {
auto lifetime = rpl::lifetime();
if (ids.empty()) {
consumer.put_next(Content());
consumer.put_done();
return lifetime;
}
struct State {
Fn<void()> check;
base::has_weak_ptr guard;
int readTill = StoryId();
bool pushed = false;
};
const auto state = lifetime.make_state<State>();
state->readTill = readTill;
state->check = [=] {
if (state->pushed) {
return;
}
auto done = true;
auto resolving = false;
auto result = Content{};
for (const auto id : ids) {
@ -420,13 +428,17 @@ rpl::producer<Content> LastForPeer(not_null<PeerData*> peer) {
const auto maybe = stories->lookup(storyId);
if (maybe) {
if (!resolving) {
const auto unread = (id > state->readTill);
result.elements.reserve(ids.size());
result.elements.push_back({
.id = uint64(id),
.thumbnail = MakeStoryThumbnail(*maybe),
.count = 1U,
.unreadCount = (id > readTill) ? 1U : 0U,
.unreadCount = unread ? 1U : 0U,
});
if (unread) {
done = false;
}
}
} else if (maybe.error() == Data::NoStory::Unknown) {
resolving = true;
@ -440,12 +452,30 @@ rpl::producer<Content> LastForPeer(not_null<PeerData*> peer) {
}
state->pushed = true;
consumer.put_next(std::move(result));
consumer.put_done();
if (done) {
consumer.put_done();
}
};
rpl::single(peerId) | rpl::then(
stories->itemsChanged() | rpl::filter(_1 == peerId)
) | rpl::start_with_next(state->check, lifetime);
stories->session().changes().storyUpdates(
Data::StoryUpdate::Flag::MarkRead
) | rpl::start_with_next([=](const Data::StoryUpdate &update) {
if (update.story->peer()->id == peerId) {
if (update.story->id() > state->readTill) {
state->readTill = update.story->id();
if (ranges::contains(ids, state->readTill)
|| state->readTill > ids.front()) {
state->pushed = false;
state->check();
}
}
}
}, lifetime);
return lifetime;
});
}) | rpl::flatten_latest();