diff --git a/lib/radiator/event_store.ex b/lib/radiator/event_store.ex index 7a659948..b86cb675 100644 --- a/lib/radiator/event_store.ex +++ b/lib/radiator/event_store.ex @@ -12,22 +12,30 @@ defmodule Radiator.EventStore do create_event_data(%{ data: AbstractEvent.payload(event), event_type: AbstractEvent.event_type(event), - uuid: convert_to_uuid(event.event_id), + uuid: convert_to_uuid(event.uuid), user_id: event.user_id }) event end + def list_events_by_episode(episode_id) do + episode_id + |> list_event_data_by_episode + |> Enum.map(&event_data_to_event/1) + end + + defp event_data_to_event(_event), do: nil + defp convert_to_uuid(<>), do: uuid defp convert_to_uuid(uuid), do: uuid @doc """ - Returns the list of foo_events. + Returns the list of all event_data. ## Examples - iex> list_events() + iex> list_event_data() [%Event{}, ...] """ @@ -35,6 +43,20 @@ defmodule Radiator.EventStore do Repo.all(EventData) end + @doc """ + Returns the list of event_data per episode. + + ## Examples + + iex> list_event_data_by_episode() + [%Event{}, ...] + + """ + # def list_event_data_by_episode(nil), do: nil + def list_event_data_by_episode(episode_id) do + Repo.all(EventData, where: [episode_id: episode_id], order_by: [desc: :inserted_at]) + end + @doc """ Gets a single event data. diff --git a/lib/radiator/outline.ex b/lib/radiator/outline.ex index 4acdc74c..62204e41 100644 --- a/lib/radiator/outline.ex +++ b/lib/radiator/outline.ex @@ -25,6 +25,25 @@ defmodule Radiator.Outline do require Logger + @doc """ + Returns a list of direct child nodes in correct order. + """ + + def order_child_nodes(%Node{} = node) do + node + |> get_all_child_nodes() + |> Enum.map(fn node -> {node.prev_id, node} end) + |> Map.new() + |> order_nodes(nil, []) + end + + defp order_nodes(index, prev_id, collection) do + case index[prev_id] do + %{uuid: uuid} = node -> order_nodes(index, uuid, [node | collection]) + _ -> Enum.reverse(collection) + end + end + @doc """ Inserts a node. diff --git a/lib/radiator/outline/event/node_content_changed_event.ex b/lib/radiator/outline/event/node_content_changed_event.ex index 5c3b027b..9f170bd4 100644 --- a/lib/radiator/outline/event/node_content_changed_event.ex +++ b/lib/radiator/outline/event/node_content_changed_event.ex @@ -1,5 +1,5 @@ defmodule Radiator.Outline.Event.NodeContentChangedEvent do @moduledoc false - defstruct [:event_id, :node_id, :content, :user_id] + defstruct [:uuid, :node_id, :content, :user_id] end diff --git a/lib/radiator/outline/event/node_deleted_event.ex b/lib/radiator/outline/event/node_deleted_event.ex index 1bbf0f46..7d1c872b 100644 --- a/lib/radiator/outline/event/node_deleted_event.ex +++ b/lib/radiator/outline/event/node_deleted_event.ex @@ -1,4 +1,4 @@ defmodule Radiator.Outline.Event.NodeDeletedEvent do @moduledoc false - defstruct [:event_id, :node_id, :user_id, :children] + defstruct [:uuid, :node_id, :user_id, :children, :next_id] end diff --git a/lib/radiator/outline/event/node_inserted_event.ex b/lib/radiator/outline/event/node_inserted_event.ex index 783063aa..5220f6eb 100644 --- a/lib/radiator/outline/event/node_inserted_event.ex +++ b/lib/radiator/outline/event/node_inserted_event.ex @@ -1,5 +1,5 @@ defmodule Radiator.Outline.Event.NodeInsertedEvent do @moduledoc false - defstruct [:event_id, :node, :user_id, :next_id] + defstruct [:uuid, :node, :user_id, :next_id] end diff --git a/lib/radiator/outline/event/node_moved_event.ex b/lib/radiator/outline/event/node_moved_event.ex index 2e774cbc..bbcdd4d5 100644 --- a/lib/radiator/outline/event/node_moved_event.ex +++ b/lib/radiator/outline/event/node_moved_event.ex @@ -1,7 +1,7 @@ defmodule Radiator.Outline.Event.NodeMovedEvent do @moduledoc false defstruct [ - :event_id, + :uuid, :node_id, :parent_id, :prev_id, diff --git a/lib/radiator/outline/event_consumer.ex b/lib/radiator/outline/event_consumer.ex index 0af29e16..aeded465 100644 --- a/lib/radiator/outline/event_consumer.ex +++ b/lib/radiator/outline/event_consumer.ex @@ -74,7 +74,7 @@ defmodule Radiator.Outline.EventConsumer do node -> Outline.remove_node(node) end - %NodeDeletedEvent{node_id: node_id, event_id: command.event_id, user_id: command.user_id} + %NodeDeletedEvent{node_id: node_id, uuid: command.event_id, user_id: command.user_id} |> EventStore.persist_event() |> Dispatch.broadcast() @@ -84,7 +84,7 @@ defmodule Radiator.Outline.EventConsumer do defp handle_insert_node_result({:ok, %NodeRepoResult{node: node, next_id: next_id}}, command) do %NodeInsertedEvent{ node: node, - event_id: command.event_id, + uuid: command.event_id, user_id: command.user_id, next_id: next_id } @@ -108,7 +108,7 @@ defmodule Radiator.Outline.EventConsumer do parent_id: command.parent_id, prev_id: command.prev_id, user_id: command.user_id, - event_id: command.event_id, + uuid: command.event_id, next_id: result.next_id } |> EventStore.persist_event() @@ -127,7 +127,7 @@ defmodule Radiator.Outline.EventConsumer do node_id: node.uuid, content: node.content, user_id: command.user_id, - event_id: command.event_id + uuid: command.event_id } |> EventStore.persist_event() |> Dispatch.broadcast() diff --git a/lib/radiator/outline/node.ex b/lib/radiator/outline/node.ex index a11b50ef..0718b7a0 100644 --- a/lib/radiator/outline/node.ex +++ b/lib/radiator/outline/node.ex @@ -15,6 +15,7 @@ defmodule Radiator.Outline.Node do field :parent_id, Ecto.UUID field :prev_id, Ecto.UUID field :level, :integer, virtual: true + field :position, :integer, virtual: true belongs_to :episode, Episode diff --git a/lib/radiator_web/components/outline_components.ex b/lib/radiator_web/components/outline_components.ex index 16133f00..6ceb4d09 100644 --- a/lib/radiator_web/components/outline_components.ex +++ b/lib/radiator_web/components/outline_components.ex @@ -29,7 +29,7 @@ defmodule RadiatorWeb.OutlineComponents do ~H"""
- <%= @event.event_id %> + <%= @event.uuid %>
<%= @event.node_id %> - NodeContentChanged
@@ -42,11 +42,12 @@ defmodule RadiatorWeb.OutlineComponents do ~H"""
- <%= @event.event_id %> + <%= @event.uuid %>
<%= @event.node_id %> - NodeDeleted
-

moved nodes = ?

+

next node = ?

+

child nodes = ?

""" end @@ -55,14 +56,14 @@ defmodule RadiatorWeb.OutlineComponents do ~H"""
- <%= @event.event_id %> + <%= @event.uuid %>
<%= @event.node.uuid %> - NodeInserted

parent_id = <%= @event.node.parent_id %>

prev_id = <%= @event.node.prev_id %>

+

next_id = <%= @event.next_id %>

content = <%= @event.node.content %>

-

moved nodes = ?

""" end @@ -71,13 +72,15 @@ defmodule RadiatorWeb.OutlineComponents do ~H"""
- <%= @event.event_id %> + <%= @event.uuid %>
<%= @event.node_id %> - NodeMoved

parent_id = <%= @event.parent_id %>

prev_id = <%= @event.prev_id %>

-

moved nodes = ?

+

old_prev_id = <%= @event.old_prev_id %>

+

old_next_id = <%= @event.old_next_id %>

+

next_id = <%= @event.next_id %>

""" end diff --git a/lib/radiator_web/live/episode_live/index.ex b/lib/radiator_web/live/episode_live/index.ex index a0f31d4f..0fa1189a 100644 --- a/lib/radiator_web/live/episode_live/index.ex +++ b/lib/radiator_web/live/episode_live/index.ex @@ -10,14 +10,16 @@ defmodule RadiatorWeb.EpisodeLive.Index do NodeMovedEvent } + # alias Radiator.EventStore alias Radiator.Podcast alias Radiator.Podcast.Episode alias RadiatorWeb.OutlineComponents @impl true - def mount(%{"show" => show_id}, _session, socket) do + def mount(%{"show" => show_id} = params, _session, socket) do show = Podcast.get_show!(show_id, preload: :episodes) + episode = get_selected_episode(params) socket |> assign(:page_title, show.title) @@ -25,8 +27,8 @@ defmodule RadiatorWeb.EpisodeLive.Index do |> assign(:show, show) |> assign(:episodes, show.episodes) |> assign(action: nil, episode: nil, form: nil) - |> stream_configure(:event_logs, dom_id: & &1.event_id) - |> stream(:event_logs, []) + |> stream_configure(:event_logs, dom_id: & &1.uuid) + |> stream(:event_logs, get_event_logs(episode)) |> reply(:ok) end @@ -149,7 +151,7 @@ defmodule RadiatorWeb.EpisodeLive.Index do end @impl true - def handle_info(%{event_id: <<_::binary-size(36)>> <> ":" <> id} = event, %{id: id} = socket) do + def handle_info(%{uuid: <<_::binary-size(36)>> <> ":" <> id} = event, %{id: id} = socket) do id = case event do %{node: %{uuid: id}} -> id @@ -218,6 +220,13 @@ defmodule RadiatorWeb.EpisodeLive.Index do Podcast.get_current_episode_for_show(show_id) end + def get_event_logs(nil), do: [] + + def get_event_logs(_episode) do + # EventStore.list_event_data_by_episode(episode.id) + [] + end + defp get_nodes(%{id: id}), do: NodeRepository.list_nodes_by_episode(id) defp get_nodes(_), do: [] diff --git a/test/radiator/event_store_test.exs b/test/radiator/event_store_test.exs index d6bcead0..d93078f3 100644 --- a/test/radiator/event_store_test.exs +++ b/test/radiator/event_store_test.exs @@ -22,7 +22,7 @@ defmodule Radiator.EventStoreTest do event = node_inserted_event_fixture(user_id: user.id) EventStore.persist_event(event) - stored_event = EventStore.get_event_data!(event.event_id) + stored_event = EventStore.get_event_data!(event.uuid) assert stored_event.data["next_id"] == event.next_id assert stored_event.user_id == event.user_id assert stored_event.event_type == "NodeInsertedEvent" @@ -65,7 +65,7 @@ defmodule Radiator.EventStoreTest do event = node_moved_event_fixture(user_id: user.id) EventStore.persist_event(event) - stored_event = EventStore.get_event_data!(event.event_id) + stored_event = EventStore.get_event_data!(event.uuid) assert stored_event.data["node_id"] == event.node_id assert stored_event.data["parent_id"] == event.parent_id assert stored_event.data["prev_id"] == event.prev_id diff --git a/test/radiator/outline_test.exs b/test/radiator/outline_test.exs index b2e79a50..685cffc1 100644 --- a/test/radiator/outline_test.exs +++ b/test/radiator/outline_test.exs @@ -678,6 +678,15 @@ defmodule Radiator.OutlineTest do end end + describe "order_child_nodes/1" do + setup :complex_node_fixture + + test "get child nodes in correct order", %{parent_node: parent_node} do + assert parent_node |> Outline.order_child_nodes() |> Enum.map(& &1.content) == + ["node_1", "node_2", "node_3", "node_4", "node_5", "node_6"] + end + end + defp assert_level_for_node(tree, node, level) do node = Enum.filter(tree, fn n -> n.uuid == node.uuid end) |> List.first() assert node.level == level diff --git a/test/support/fixtures/event_store_fixtures.ex b/test/support/fixtures/event_store_fixtures.ex index 3b0adbde..5c0cbe66 100644 --- a/test/support/fixtures/event_store_fixtures.ex +++ b/test/support/fixtures/event_store_fixtures.ex @@ -40,7 +40,7 @@ defmodule Radiator.EventStoreFixtures do %NodeInsertedEvent{ node: node, user_id: user_id, - event_id: Ecto.UUID.generate(), + uuid: Ecto.UUID.generate(), next_id: next.uuid } end @@ -52,7 +52,7 @@ defmodule Radiator.EventStoreFixtures do node_id: node.uuid, content: node.content, user_id: user_id, - event_id: Ecto.UUID.generate() + uuid: Ecto.UUID.generate() } end @@ -62,7 +62,7 @@ defmodule Radiator.EventStoreFixtures do %NodeDeletedEvent{ node_id: node.uuid, user_id: user_id, - event_id: Ecto.UUID.generate() + uuid: Ecto.UUID.generate() } end @@ -84,7 +84,7 @@ defmodule Radiator.EventStoreFixtures do next_id: next.uuid, old_next_id: old_next.uuid, old_prev_id: old_prev.uuid, - event_id: Ecto.UUID.generate() + uuid: Ecto.UUID.generate() } end end