mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +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 {
|
enum class Flag : uint32 {
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
||||||
UnreadView = (1U << 1),
|
UnreadView = (1U << 1),
|
||||||
UnreadMentions = (1U << 2),
|
UnreadMentions = (1U << 2),
|
||||||
UnreadReactions = (1U << 3),
|
UnreadReactions = (1U << 3),
|
||||||
Notifications = (1U << 4),
|
Notifications = (1U << 4),
|
||||||
Title = (1U << 5),
|
Title = (1U << 5),
|
||||||
IconId = (1U << 6),
|
IconId = (1U << 6),
|
||||||
ColorId = (1U << 7),
|
ColorId = (1U << 7),
|
||||||
CloudDraft = (1U << 8),
|
CloudDraft = (1U << 8),
|
||||||
Closed = (1U << 9),
|
Closed = (1U << 9),
|
||||||
Creator = (1U << 10),
|
Creator = (1U << 10),
|
||||||
Destroyed = (1U << 11),
|
Destroyed = (1U << 11),
|
||||||
|
|
||||||
LastUsedBit = (1U << 11),
|
LastUsedBit = (1U << 11),
|
||||||
};
|
};
|
||||||
using Flags = base::flags<Flag>;
|
using Flags = base::flags<Flag>;
|
||||||
friend inline constexpr auto is_flag_type(Flag) { return true; }
|
friend inline constexpr auto is_flag_type(Flag) { return true; }
|
||||||
|
@ -199,14 +199,14 @@ struct EntryUpdate {
|
||||||
enum class Flag : uint32 {
|
enum class Flag : uint32 {
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
||||||
Repaint = (1U << 0),
|
Repaint = (1U << 0),
|
||||||
HasPinnedMessages = (1U << 1),
|
HasPinnedMessages = (1U << 1),
|
||||||
ForwardDraft = (1U << 2),
|
ForwardDraft = (1U << 2),
|
||||||
LocalDraftSet = (1U << 3),
|
LocalDraftSet = (1U << 3),
|
||||||
Height = (1U << 4),
|
Height = (1U << 4),
|
||||||
Destroyed = (1U << 5),
|
Destroyed = (1U << 5),
|
||||||
|
|
||||||
LastUsedBit = (1U << 5),
|
LastUsedBit = (1U << 5),
|
||||||
};
|
};
|
||||||
using Flags = base::flags<Flag>;
|
using Flags = base::flags<Flag>;
|
||||||
friend inline constexpr auto is_flag_type(Flag) { return true; }
|
friend inline constexpr auto is_flag_type(Flag) { return true; }
|
||||||
|
@ -220,12 +220,13 @@ struct StoryUpdate {
|
||||||
enum class Flag : uint32 {
|
enum class Flag : uint32 {
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
||||||
Edited = (1U << 0),
|
Edited = (1U << 0),
|
||||||
Destroyed = (1U << 1),
|
Destroyed = (1U << 1),
|
||||||
NewAdded = (1U << 2),
|
NewAdded = (1U << 2),
|
||||||
ViewsAdded = (1U << 3),
|
ViewsAdded = (1U << 3),
|
||||||
|
MarkRead = (1U << 4),
|
||||||
|
|
||||||
LastUsedBit = (1U << 3),
|
LastUsedBit = (1U << 4),
|
||||||
};
|
};
|
||||||
using Flags = base::flags<Flag>;
|
using Flags = base::flags<Flag>;
|
||||||
friend inline constexpr auto is_flag_type(Flag) { return true; }
|
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(
|
refreshItems = ranges::make_subrange(
|
||||||
i->second.lower_bound(from + 1),
|
i->second.lower_bound(from + 1),
|
||||||
i->second.lower_bound(till + 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;
|
return pair.first;
|
||||||
}) | ranges::to_vector;
|
}) | ranges::to_vector;
|
||||||
}
|
}
|
||||||
|
|
|
@ -402,17 +402,25 @@ rpl::producer<Content> LastForPeer(not_null<PeerData*> peer) {
|
||||||
}
|
}
|
||||||
return rpl::make_producer<Content>([=](auto consumer) {
|
return rpl::make_producer<Content>([=](auto consumer) {
|
||||||
auto lifetime = rpl::lifetime();
|
auto lifetime = rpl::lifetime();
|
||||||
|
if (ids.empty()) {
|
||||||
|
consumer.put_next(Content());
|
||||||
|
consumer.put_done();
|
||||||
|
return lifetime;
|
||||||
|
}
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
Fn<void()> check;
|
Fn<void()> check;
|
||||||
base::has_weak_ptr guard;
|
base::has_weak_ptr guard;
|
||||||
|
int readTill = StoryId();
|
||||||
bool pushed = false;
|
bool pushed = false;
|
||||||
};
|
};
|
||||||
const auto state = lifetime.make_state<State>();
|
const auto state = lifetime.make_state<State>();
|
||||||
|
state->readTill = readTill;
|
||||||
state->check = [=] {
|
state->check = [=] {
|
||||||
if (state->pushed) {
|
if (state->pushed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
auto done = true;
|
||||||
auto resolving = false;
|
auto resolving = false;
|
||||||
auto result = Content{};
|
auto result = Content{};
|
||||||
for (const auto id : ids) {
|
for (const auto id : ids) {
|
||||||
|
@ -420,13 +428,17 @@ rpl::producer<Content> LastForPeer(not_null<PeerData*> peer) {
|
||||||
const auto maybe = stories->lookup(storyId);
|
const auto maybe = stories->lookup(storyId);
|
||||||
if (maybe) {
|
if (maybe) {
|
||||||
if (!resolving) {
|
if (!resolving) {
|
||||||
|
const auto unread = (id > state->readTill);
|
||||||
result.elements.reserve(ids.size());
|
result.elements.reserve(ids.size());
|
||||||
result.elements.push_back({
|
result.elements.push_back({
|
||||||
.id = uint64(id),
|
.id = uint64(id),
|
||||||
.thumbnail = MakeStoryThumbnail(*maybe),
|
.thumbnail = MakeStoryThumbnail(*maybe),
|
||||||
.count = 1U,
|
.count = 1U,
|
||||||
.unreadCount = (id > readTill) ? 1U : 0U,
|
.unreadCount = unread ? 1U : 0U,
|
||||||
});
|
});
|
||||||
|
if (unread) {
|
||||||
|
done = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (maybe.error() == Data::NoStory::Unknown) {
|
} else if (maybe.error() == Data::NoStory::Unknown) {
|
||||||
resolving = true;
|
resolving = true;
|
||||||
|
@ -440,12 +452,30 @@ rpl::producer<Content> LastForPeer(not_null<PeerData*> peer) {
|
||||||
}
|
}
|
||||||
state->pushed = true;
|
state->pushed = true;
|
||||||
consumer.put_next(std::move(result));
|
consumer.put_next(std::move(result));
|
||||||
consumer.put_done();
|
if (done) {
|
||||||
|
consumer.put_done();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
rpl::single(peerId) | rpl::then(
|
rpl::single(peerId) | rpl::then(
|
||||||
stories->itemsChanged() | rpl::filter(_1 == peerId)
|
stories->itemsChanged() | rpl::filter(_1 == peerId)
|
||||||
) | rpl::start_with_next(state->check, lifetime);
|
) | 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;
|
return lifetime;
|
||||||
});
|
});
|
||||||
}) | rpl::flatten_latest();
|
}) | rpl::flatten_latest();
|
||||||
|
|
Loading…
Add table
Reference in a new issue