You've already forked tribes-plugin-aether
forked from tribes/tribes-plugin-template
refactor: use typed plugin nostr data
This commit is contained in:
@@ -4,6 +4,7 @@ defmodule AetherWeb.TimelineLive do
|
||||
on_mount({Tribes.Plugin.LiveUserAuth, :live_user_optional})
|
||||
|
||||
alias Tribes.Plugin.Layouts
|
||||
alias Tribes.Plugin.Nostr.Profile
|
||||
alias Tribes.Plugin.Services.Cluster
|
||||
alias Tribes.Plugin.Services.Communities
|
||||
alias Tribes.Plugin.Services.Nostr
|
||||
@@ -15,7 +16,7 @@ defmodule AetherWeb.TimelineLive do
|
||||
relay_urls = load_relay_urls()
|
||||
notes = load_notes(feed.member_pubkeys)
|
||||
profile_cache = load_profile_cache(notes)
|
||||
note_ids = notes |> Enum.map(& &1["id"]) |> MapSet.new()
|
||||
note_ids = notes |> Enum.map(& &1.id) |> MapSet.new()
|
||||
|
||||
socket =
|
||||
socket
|
||||
@@ -29,7 +30,7 @@ defmodule AetherWeb.TimelineLive do
|
||||
|> assign(:note_ids, note_ids)
|
||||
|> assign(:note_count, MapSet.size(note_ids))
|
||||
|> assign(:subscription_ref, nil)
|
||||
|> stream_configure(:notes, dom_id: &("note-" <> &1["id"]))
|
||||
|> stream_configure(:notes, dom_id: &("note-" <> &1.id))
|
||||
|> stream(:notes, notes)
|
||||
|
||||
if connected?(socket) do
|
||||
@@ -69,24 +70,28 @@ defmodule AetherWeb.TimelineLive do
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_info({:parrhesia, :event, _ref, _sub_id, %{"kind" => 1} = event}, socket) do
|
||||
if note_in_scope?(event, socket.assigns.tribe_member_pubkeys) do
|
||||
profile_cache = maybe_put_profile(socket.assigns.profile_cache, event["pubkey"])
|
||||
def handle_info({:parrhesia, :event, _ref, _sub_id, %{"kind" => 1} = raw_event}, socket) do
|
||||
with {:ok, event} <- Nostr.to_event(raw_event) do
|
||||
if note_in_scope?(event, socket.assigns.tribe_member_pubkeys) do
|
||||
profile_cache = maybe_put_profile(socket.assigns.profile_cache, event.pubkey)
|
||||
|
||||
if MapSet.member?(socket.assigns.note_ids, event["id"]) do
|
||||
{:noreply, assign(socket, :profile_cache, profile_cache)}
|
||||
if MapSet.member?(socket.assigns.note_ids, event.id) do
|
||||
{:noreply, assign(socket, :profile_cache, profile_cache)}
|
||||
else
|
||||
note_ids = MapSet.put(socket.assigns.note_ids, event.id)
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> assign(:profile_cache, profile_cache)
|
||||
|> assign(:note_ids, note_ids)
|
||||
|> assign(:note_count, MapSet.size(note_ids))
|
||||
|> stream_insert(:notes, event, at: 0)}
|
||||
end
|
||||
else
|
||||
note_ids = MapSet.put(socket.assigns.note_ids, event["id"])
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> assign(:profile_cache, profile_cache)
|
||||
|> assign(:note_ids, note_ids)
|
||||
|> assign(:note_count, MapSet.size(note_ids))
|
||||
|> stream_insert(:notes, event, at: 0)}
|
||||
{:noreply, socket}
|
||||
end
|
||||
else
|
||||
{:noreply, socket}
|
||||
{:error, _reason} -> {:noreply, socket}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -171,20 +176,20 @@ defmodule AetherWeb.TimelineLive do
|
||||
<article :for={{id, note} <- @streams.notes} id={id} class="card bg-base-100 shadow-sm">
|
||||
<div class="card-body gap-2">
|
||||
<div class="flex items-center justify-between gap-4 text-xs text-base-content/60">
|
||||
<a href={Routes.profile_path(note["pubkey"])} class="link link-hover font-medium">
|
||||
{author_label(@profile_cache, note["pubkey"])}
|
||||
<a href={Routes.profile_path(note.pubkey)} class="link link-hover font-medium">
|
||||
{author_label(@profile_cache, note.pubkey)}
|
||||
</a>
|
||||
<span
|
||||
phx-hook="DateTime"
|
||||
id={"time-#{note["id"]}"}
|
||||
id={"time-#{note.id}"}
|
||||
phx-update="ignore"
|
||||
data-timestamp={note["created_at"] * 1000}
|
||||
data-timestamp={note.created_at * 1000}
|
||||
data-relative="true"
|
||||
data-format="LLL"
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
<p class="whitespace-pre-wrap text-sm leading-6">{note["content"]}</p>
|
||||
<p class="whitespace-pre-wrap text-sm leading-6">{note.content}</p>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
@@ -195,7 +200,7 @@ defmodule AetherWeb.TimelineLive do
|
||||
|
||||
defp handle_published_note(socket, event) do
|
||||
if note_in_scope?(event, socket.assigns.tribe_member_pubkeys) do
|
||||
note_ids = MapSet.put(socket.assigns.note_ids, event["id"])
|
||||
note_ids = MapSet.put(socket.assigns.note_ids, event.id)
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
@@ -262,7 +267,7 @@ defmodule AetherWeb.TimelineLive do
|
||||
end
|
||||
|
||||
defp note_in_scope?(event, member_pubkeys) do
|
||||
MapSet.member?(member_pubkeys, event["pubkey"])
|
||||
MapSet.member?(member_pubkeys, event.pubkey)
|
||||
end
|
||||
|
||||
defp filter_notes(notes, member_pubkeys) do
|
||||
@@ -271,13 +276,13 @@ defmodule AetherWeb.TimelineLive do
|
||||
|
||||
defp sort_notes(notes) do
|
||||
Enum.sort_by(notes, fn note ->
|
||||
{-Map.get(note, "created_at", 0), Map.get(note, "id", "")}
|
||||
{-note.created_at, note.id}
|
||||
end)
|
||||
end
|
||||
|
||||
defp load_profile_cache(notes) do
|
||||
notes
|
||||
|> Enum.map(& &1["pubkey"])
|
||||
|> Enum.map(& &1.pubkey)
|
||||
|> Enum.uniq()
|
||||
|> Enum.reduce(%{}, &maybe_put_profile(&2, &1))
|
||||
end
|
||||
@@ -288,24 +293,17 @@ defmodule AetherWeb.TimelineLive do
|
||||
else
|
||||
case Nostr.get_profile(pubkey) do
|
||||
{:ok, nil} -> Map.put(cache, pubkey, nil)
|
||||
{:ok, event} -> Map.put(cache, pubkey, parse_profile(event))
|
||||
{:ok, %Profile{} = profile} -> Map.put(cache, pubkey, profile)
|
||||
{:error, _reason} -> Map.put(cache, pubkey, nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp parse_profile(%{"content" => content}) when is_binary(content) do
|
||||
case JSON.decode(content) do
|
||||
{:ok, profile} when is_map(profile) -> profile
|
||||
_other -> %{}
|
||||
end
|
||||
end
|
||||
|
||||
defp parse_profile(_event), do: %{}
|
||||
|
||||
defp author_label(profile_cache, pubkey) do
|
||||
profile = Map.get(profile_cache, pubkey, %{}) || %{}
|
||||
profile["name"] || "#{String.slice(pubkey, 0, 8)}…"
|
||||
case Map.get(profile_cache, pubkey) do
|
||||
%Profile{name: name} when is_binary(name) and name != "" -> name
|
||||
_other -> "#{String.slice(pubkey, 0, 8)}…"
|
||||
end
|
||||
end
|
||||
|
||||
defp timeline_title(nil), do: "Aether"
|
||||
|
||||
Reference in New Issue
Block a user