mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Mark as read recent stories in profile top bar.
This commit is contained in:
parent
74014d18a5
commit
3c28e7b585
3 changed files with 59 additions and 25 deletions
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Reference in a new issue