feat: use pubsub to sync states
This commit is contained in:
parent
e72f6f29c1
commit
8de0f1e39f
3 changed files with 66 additions and 15 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue