Skip to content

Commit e2f28c6

Browse files
committed
Order feeds by newest unread entry
1 parent a1d93b3 commit e2f28c6

File tree

2 files changed

+92
-7
lines changed

2 files changed

+92
-7
lines changed

lib/ex_rss/feed.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ defmodule ExRss.Feed do
3434
field :unread_entries_count, :integer, virtual: true
3535
field :read_entries_count, :integer, virtual: true
3636
field :has_error, :boolean, virtual: true
37+
field :newest_unread_entry_posted_at, :utc_datetime, virtual: true
3738
field :position, :integer
3839

3940
belongs_to :user, User

lib/ex_rss_web/feed_live/index.ex

Lines changed: 91 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,17 @@ defmodule ExRssWeb.FeedLive.Index do
2222
join: e in Entry,
2323
on: f.id == e.feed_id,
2424
group_by: f.id,
25-
order_by: [desc_nulls_last: f.position],
25+
order_by: [
26+
desc_nulls_last: f.position,
27+
desc_nulls_last: selected_as(:newest_unread_entry_posted_at)
28+
],
2629
select: %{
2730
f
2831
| unread_entries_count: filter(count(e.id), e.read == false),
2932
read_entries_count: filter(count(e.id), e.read == true),
33+
newest_unread_entry_posted_at:
34+
filter(max(e.posted_at), e.read == false)
35+
|> selected_as(:newest_unread_entry_posted_at),
3036
has_error: f.retries > 0
3137
}
3238
)
@@ -49,14 +55,47 @@ defmodule ExRssWeb.FeedLive.Index do
4955
end
5056

5157
def handle_event("mark_as_read", %{"entry-id" => entry_id}, socket) do
52-
changeset =
58+
current_user =
5359
Repo.get!(User, socket.assigns.current_user.id)
60+
61+
changeset =
62+
current_user
5463
|> Ecto.assoc(:entries)
5564
|> Repo.get!(entry_id)
5665
|> Entry.changeset(%{"read" => true})
5766

5867
case Repo.update(changeset) do
5968
{:ok, entry} ->
69+
feeds_of_current_user = current_user |> Ecto.assoc(:feeds)
70+
71+
feeds_with_counts =
72+
from(
73+
f in feeds_of_current_user,
74+
join: e in Entry,
75+
on: f.id == e.feed_id,
76+
group_by: f.id,
77+
order_by: [
78+
desc_nulls_last: f.position,
79+
desc_nulls_last: selected_as(:newest_unread_entry_posted_at)
80+
],
81+
select: %{
82+
f
83+
| unread_entries_count: filter(count(e.id), e.read == false),
84+
read_entries_count: filter(count(e.id), e.read == true),
85+
newest_unread_entry_posted_at:
86+
filter(max(e.posted_at), e.read == false)
87+
|> selected_as(:newest_unread_entry_posted_at),
88+
has_error: f.retries > 0
89+
}
90+
)
91+
92+
feeds =
93+
feeds_with_counts
94+
|> Repo.all()
95+
|> Repo.preload(
96+
entries: from(e in Entry, where: e.read == false, order_by: [desc: e.posted_at])
97+
)
98+
6099
feed_with_counts_query =
61100
from(
62101
f in Feed,
@@ -93,7 +132,7 @@ defmodule ExRssWeb.FeedLive.Index do
93132
socket =
94133
socket
95134
|> assign(:oldest_unread_entry, oldest_unread_entry)
96-
|> stream_insert(:feeds, updated_feed)
135+
|> stream(:feeds, feeds, reset: true)
97136

98137
{:noreply, socket}
99138

@@ -103,15 +142,48 @@ defmodule ExRssWeb.FeedLive.Index do
103142
end
104143

105144
def handle_event("mark_as_read", %{"feed-id" => feed_id}, socket) do
106-
changeset =
145+
current_user =
107146
Repo.get!(User, socket.assigns.current_user.id)
147+
148+
changeset =
149+
current_user
108150
|> Ecto.assoc(:feeds)
109151
|> Repo.get!(feed_id)
110152
|> Repo.preload(:entries)
111153
|> Feed.mark_as_read()
112154

113155
case Repo.update(changeset) do
114156
{:ok, feed} ->
157+
feeds_of_current_user = current_user |> Ecto.assoc(:feeds)
158+
159+
feeds_with_counts =
160+
from(
161+
f in feeds_of_current_user,
162+
join: e in Entry,
163+
on: f.id == e.feed_id,
164+
group_by: f.id,
165+
order_by: [
166+
desc_nulls_last: f.position,
167+
desc_nulls_last: selected_as(:newest_unread_entry_posted_at)
168+
],
169+
select: %{
170+
f
171+
| unread_entries_count: filter(count(e.id), e.read == false),
172+
read_entries_count: filter(count(e.id), e.read == true),
173+
newest_unread_entry_posted_at:
174+
filter(max(e.posted_at), e.read == false)
175+
|> selected_as(:newest_unread_entry_posted_at),
176+
has_error: f.retries > 0
177+
}
178+
)
179+
180+
feeds =
181+
feeds_with_counts
182+
|> Repo.all()
183+
|> Repo.preload(
184+
entries: from(e in Entry, where: e.read == false, order_by: [desc: e.posted_at])
185+
)
186+
115187
feed_with_counts_query =
116188
from(
117189
f in Feed,
@@ -148,7 +220,7 @@ defmodule ExRssWeb.FeedLive.Index do
148220
socket =
149221
socket
150222
|> assign(:oldest_unread_entry, oldest_unread_entry)
151-
|> stream_insert(:feeds, updated_feed)
223+
|> stream(:feeds, feeds, reset: true)
152224

153225
{:noreply, socket}
154226

@@ -181,11 +253,17 @@ defmodule ExRssWeb.FeedLive.Index do
181253
join: e in Entry,
182254
on: f.id == e.feed_id,
183255
group_by: f.id,
184-
order_by: [desc_nulls_last: f.position],
256+
order_by: [
257+
desc_nulls_last: f.position,
258+
desc_nulls_last: selected_as(:newest_unread_entry_posted_at)
259+
],
185260
select: %{
186261
f
187262
| unread_entries_count: filter(count(e.id), e.read == false),
188263
read_entries_count: filter(count(e.id), e.read == true),
264+
newest_unread_entry_posted_at:
265+
filter(max(e.posted_at), e.read == false)
266+
|> selected_as(:newest_unread_entry_posted_at),
189267
has_error: f.retries > 0
190268
}
191269
)
@@ -231,11 +309,17 @@ defmodule ExRssWeb.FeedLive.Index do
231309
join: e in Entry,
232310
on: f.id == e.feed_id,
233311
group_by: f.id,
234-
order_by: [desc_nulls_last: f.position],
312+
order_by: [
313+
desc_nulls_last: f.position,
314+
desc_nulls_last: selected_as(:newest_unread_entry_posted_at)
315+
],
235316
select: %{
236317
f
237318
| unread_entries_count: filter(count(e.id), e.read == false),
238319
read_entries_count: filter(count(e.id), e.read == true),
320+
newest_unread_entry_posted_at:
321+
filter(max(e.posted_at), e.read == false)
322+
|> selected_as(:newest_unread_entry_posted_at),
239323
has_error: f.retries > 0
240324
}
241325
)

0 commit comments

Comments
 (0)