diff --git a/lib/putzplan_web/live/task_live/form_component.ex b/lib/putzplan_web/live/task_live/form_component.ex index c0e212d..38cf74f 100644 --- a/lib/putzplan_web/live/task_live/form_component.ex +++ b/lib/putzplan_web/live/task_live/form_component.ex @@ -1,6 +1,9 @@ defmodule PutzplanWeb.TaskLive.FormComponent do use PutzplanWeb, :live_component + @pubsub_name Putzplan.PubSub + @pubsub_topic_tasks "tasks" + @impl true def render(assigns) do ~H""" @@ -47,7 +50,8 @@ defmodule PutzplanWeb.TaskLive.FormComponent do def handle_event("save", %{"task" => task_params}, socket) do case AshPhoenix.Form.submit(socket.assigns.form, params: task_params) do {:ok, task} -> - notify_parent({:saved, task |> Ash.load!(:due)}) + task = Ash.load!(task, :due) + Phoenix.PubSub.broadcast(@pubsub_name, @pubsub_topic_tasks, {:upsert, task}) socket = socket @@ -61,8 +65,6 @@ defmodule PutzplanWeb.TaskLive.FormComponent do end end - defp notify_parent(msg), do: send(self(), {__MODULE__, msg}) - defp assign_form(%{assigns: %{task: task}} = socket) do form = if task do diff --git a/lib/putzplan_web/live/task_live/index.ex b/lib/putzplan_web/live/task_live/index.ex index 418a1f1..fbf9907 100644 --- a/lib/putzplan_web/live/task_live/index.ex +++ b/lib/putzplan_web/live/task_live/index.ex @@ -1,6 +1,13 @@ defmodule PutzplanWeb.TaskLive.Index do use PutzplanWeb, :live_view + @pubsub_name Putzplan.PubSub + @pubsub_topic "tasks" + + defp get_topic(id) do + "completed:" <> id + end + @impl true def render(assigns) do ~H""" @@ -116,6 +123,8 @@ defmodule PutzplanWeb.TaskLive.Index do @impl true def mount(_params, _session, socket) do + if connected?(socket), do: Phoenix.PubSub.subscribe(@pubsub_name, @pubsub_topic) + {:ok, socket |> stream( @@ -130,12 +139,28 @@ defmodule PutzplanWeb.TaskLive.Index do {:noreply, apply_action(socket, socket.assigns.live_action, params)} end + @impl true + def handle_info({:delete, task}, socket) do + {:noreply, stream_delete(socket, :tasks, task)} + end + + @impl true + def handle_info({:upsert, task}, socket) do + {:noreply, stream_insert(socket, :tasks, task)} + end + + @impl true + def handle_info({:update, task_id}, socket) do + task = Ash.get!(Putzplan.Tasks.Task, task_id, load: [:due]) + {:noreply, stream_insert(socket, :tasks, task)} + end + defp apply_action(socket, :edit, %{"id" => id}) do socket |> assign(:page_title, "Edit Task") |> assign( :task, - Ash.get!(Putzplan.Tasks.Task, id, load: [:due], actor: socket.assigns.current_user) + Ash.get!(Putzplan.Tasks.Task, id, actor: socket.assigns.current_user) ) end @@ -151,31 +176,35 @@ defmodule PutzplanWeb.TaskLive.Index do |> assign(:task, nil) end - @impl true - def handle_info({PutzplanWeb.TaskLive.FormComponent, {:saved, task}}, socket) do - {:noreply, stream_insert(socket, :tasks, task)} - end - @impl true def handle_event("delete", %{"id" => id}, socket) do task = Ash.get!(Putzplan.Tasks.Task, id, actor: socket.assigns.current_user) Ash.destroy!(task, actor: socket.assigns.current_user) + Phoenix.PubSub.broadcast(@pubsub_name, @pubsub_topic, {:delete, task}) - {:noreply, stream_delete(socket, :tasks, task)} + {:noreply, task} end @impl true def handle_event("complete", %{"id" => id}, socket) do - Putzplan.Tasks.CompletedTask - |> Ash.Changeset.for_create(:create, %{task: id, user: socket.assigns.current_user.id}) - |> Ash.create!(actor: socket.assigns.current_user) + completed_task = + Putzplan.Tasks.CompletedTask + |> Ash.Changeset.for_create(:create, %{task: id, user: socket.assigns.current_user.id}) + |> Ash.create!(actor: socket.assigns.current_user) - {:noreply, stream_insert(socket, :tasks, Ash.get!(Putzplan.Tasks.Task, id, load: [:due]))} + task = Ash.get!(Putzplan.Tasks.Task, id, load: [:due]) + Phoenix.PubSub.broadcast(@pubsub_name, @pubsub_topic, {:upsert, task}) + Phoenix.PubSub.broadcast(@pubsub_name, get_topic(id), {:upsert, completed_task}) + + {:noreply, socket} end defp format_date(date) do string = case Date.diff(date, Date.utc_today()) do + -1 -> + "yesterday" + 0 -> "today" diff --git a/lib/putzplan_web/live/task_live/show.ex b/lib/putzplan_web/live/task_live/show.ex index 7c24b73..daa59c2 100644 --- a/lib/putzplan_web/live/task_live/show.ex +++ b/lib/putzplan_web/live/task_live/show.ex @@ -2,6 +2,12 @@ defmodule PutzplanWeb.TaskLive.Show do require Ash.Query use PutzplanWeb, :live_view + @pubsub_name Putzplan.PubSub + + defp get_topic(id) do + "completed:" <> id + end + @impl true def render(assigns) do ~H""" @@ -90,7 +96,8 @@ defmodule PutzplanWeb.TaskLive.Show do end @impl true - def mount(_params, _session, socket) do + def mount(%{"id" => id}, _session, socket) do + if connected?(socket), do: Phoenix.PubSub.subscribe(@pubsub_name, get_topic(id)) {:ok, socket} end @@ -120,6 +127,19 @@ defmodule PutzplanWeb.TaskLive.Show do Ash.destroy!(completed_task, actor: socket.assigns.current_user) + Phoenix.PubSub.broadcast!(@pubsub_name, get_topic(id), {:delete, completed_task}) + Phoenix.PubSub.broadcast!(@pubsub_name, "tasks", {:update, completed_task.tasks.id}) + + {:noreply, socket} + end + + @impl true + def handle_info({:delete, completed_task}, socket) do {:noreply, stream_delete(socket, :completed_tasks, completed_task)} end + + @impl true + def handle_info({:upsert, completed_task}, socket) do + {:noreply, stream_insert(socket, :completed_tasks, completed_task)} + end end