Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/unfinal/document_server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -215,5 +215,11 @@ defmodule Unfinal.DocumentServer do
path,
%{content: doc.content, etag: doc.etag, revision: doc.revision}
})

Phoenix.PubSub.broadcast(Unfinal.PubSub, Documents.edit_topic(), {
:edit,
path,
System.system_time(:second)
})
end
end
3 changes: 3 additions & 0 deletions lib/unfinal/documents.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ defmodule Unfinal.Documents do
def topic(path),
do: @topic_prefix <> Base.url_encode64(ContentStore.normalize_path(path), padding: false)

@spec edit_topic() :: String.t()
def edit_topic, do: "edits"

@spec get(path()) :: Document.t()
def get(path), do: path |> ContentStore.normalize_path() |> server_call(:get)

Expand Down
44 changes: 44 additions & 0 deletions lib/unfinal_web/live/live_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ defmodule UnfinalWeb.LiveLive do

if connected?(socket) do
Phoenix.PubSub.subscribe(Unfinal.PubSub, @topic)
Phoenix.PubSub.subscribe(Unfinal.PubSub, Documents.edit_topic())
active_paths = active_paths()
Enum.each(active_paths, &Phoenix.PubSub.subscribe(Unfinal.PubSub, Documents.topic(&1)))

Expand All @@ -25,6 +26,7 @@ defmodule UnfinalWeb.LiveLive do
active_paths: active_paths,
sorted_paths: sorted_paths(),
excerpts: excerpts(active_paths, %{}),
recent_edits: %{},
authenticated: authenticated,
user: user,
claimed_namespace: claimed_namespace,
Expand All @@ -37,6 +39,7 @@ defmodule UnfinalWeb.LiveLive do
active_paths: MapSet.new(),
sorted_paths: [],
excerpts: %{},
recent_edits: %{},
authenticated: authenticated,
user: user,
claimed_namespace: claimed_namespace,
Expand Down Expand Up @@ -72,6 +75,20 @@ defmodule UnfinalWeb.LiveLive do
end
end

def handle_info({:edit, path, timestamp}, socket) do
socket = update(socket, :recent_edits, &Map.put(&1, path, timestamp))

socket =
if not MapSet.member?(socket.assigns.active_paths, path) and
not Map.has_key?(socket.assigns.excerpts, path) do
update(socket, :excerpts, &Map.put(&1, path, Documents.get(path).content))
else
socket
end

{:noreply, socket}
end

@impl true
def handle_event("toggle_mobile_menu", _params, socket) do
{:noreply, assign(socket, mobile_menu_open: !socket.assigns.mobile_menu_open)}
Expand Down Expand Up @@ -120,6 +137,14 @@ defmodule UnfinalWeb.LiveLive do
defp document_href("/" <> path), do: "/n/" <> path
defp document_href(_path), do: "/n"

defp visible_recent(recent_edits, active_paths, limit \\ 10) do
recent_edits
|> Enum.reject(fn {path, _ts} -> MapSet.member?(active_paths, path) end)
|> Enum.sort_by(fn {_, ts} -> -ts end)
|> Enum.take(limit)
|> Enum.map(fn {path, _ts} -> path end)
end

@impl true
def render(assigns) do
~H"""
Expand Down Expand Up @@ -160,6 +185,25 @@ defmodule UnfinalWeb.LiveLive do
</p>
</a>
</div>

<% visible_recent = visible_recent(@recent_edits, @active_paths) %>

<div :if={visible_recent != []}>
<hr class="my-8 border-stone-200" />
<h2 class="text-xl font-semibold tracking-tight">Recently edited</h2>
<div class="mt-4 space-y-3">
<a
:for={path <- visible_recent}
href={document_href(path)}
class="block rounded-2xl border border-stone-200 bg-white px-5 py-4 shadow-sm shadow-stone-200/40 transition hover:border-stone-300 hover:shadow-md"
>
<div class="truncate text-sm font-semibold text-stone-900">{path}</div>
<p :if={excerpt(Map.get(@excerpts, path, "")) != ""} class="mt-2 text-sm leading-6 text-stone-600">
{excerpt(Map.get(@excerpts, path, ""))}
</p>
</a>
</div>
</div>
</section>
</main>
</div>
Expand Down
Loading