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
|
defmodule PutzplanWeb.TaskLive.FormComponent do
|
||||||
use PutzplanWeb, :live_component
|
use PutzplanWeb, :live_component
|
||||||
|
|
||||||
|
@pubsub_name Putzplan.PubSub
|
||||||
|
@pubsub_topic_tasks "tasks"
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
|
|
@ -47,7 +50,8 @@ defmodule PutzplanWeb.TaskLive.FormComponent do
|
||||||
def handle_event("save", %{"task" => task_params}, socket) do
|
def handle_event("save", %{"task" => task_params}, socket) do
|
||||||
case AshPhoenix.Form.submit(socket.assigns.form, params: task_params) do
|
case AshPhoenix.Form.submit(socket.assigns.form, params: task_params) do
|
||||||
{:ok, task} ->
|
{: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 =
|
||||||
socket
|
socket
|
||||||
|
|
@ -61,8 +65,6 @@ defmodule PutzplanWeb.TaskLive.FormComponent do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp notify_parent(msg), do: send(self(), {__MODULE__, msg})
|
|
||||||
|
|
||||||
defp assign_form(%{assigns: %{task: task}} = socket) do
|
defp assign_form(%{assigns: %{task: task}} = socket) do
|
||||||
form =
|
form =
|
||||||
if task do
|
if task do
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,13 @@
|
||||||
defmodule PutzplanWeb.TaskLive.Index do
|
defmodule PutzplanWeb.TaskLive.Index do
|
||||||
use PutzplanWeb, :live_view
|
use PutzplanWeb, :live_view
|
||||||
|
|
||||||
|
@pubsub_name Putzplan.PubSub
|
||||||
|
@pubsub_topic "tasks"
|
||||||
|
|
||||||
|
defp get_topic(id) do
|
||||||
|
"completed:" <> id
|
||||||
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
|
|
@ -116,6 +123,8 @@ defmodule PutzplanWeb.TaskLive.Index do
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(_params, _session, socket) do
|
def mount(_params, _session, socket) do
|
||||||
|
if connected?(socket), do: Phoenix.PubSub.subscribe(@pubsub_name, @pubsub_topic)
|
||||||
|
|
||||||
{:ok,
|
{:ok,
|
||||||
socket
|
socket
|
||||||
|> stream(
|
|> stream(
|
||||||
|
|
@ -130,12 +139,28 @@ defmodule PutzplanWeb.TaskLive.Index do
|
||||||
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
|
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
|
||||||
end
|
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
|
defp apply_action(socket, :edit, %{"id" => id}) do
|
||||||
socket
|
socket
|
||||||
|> assign(:page_title, "Edit Task")
|
|> assign(:page_title, "Edit Task")
|
||||||
|> assign(
|
|> assign(
|
||||||
:task,
|
: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
|
end
|
||||||
|
|
||||||
|
|
@ -151,31 +176,35 @@ defmodule PutzplanWeb.TaskLive.Index do
|
||||||
|> assign(:task, nil)
|
|> assign(:task, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
|
||||||
def handle_info({PutzplanWeb.TaskLive.FormComponent, {:saved, task}}, socket) do
|
|
||||||
{:noreply, stream_insert(socket, :tasks, task)}
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_event("delete", %{"id" => id}, socket) do
|
def handle_event("delete", %{"id" => id}, socket) do
|
||||||
task = Ash.get!(Putzplan.Tasks.Task, id, actor: socket.assigns.current_user)
|
task = Ash.get!(Putzplan.Tasks.Task, id, actor: socket.assigns.current_user)
|
||||||
Ash.destroy!(task, 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
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_event("complete", %{"id" => id}, socket) do
|
def handle_event("complete", %{"id" => id}, socket) do
|
||||||
Putzplan.Tasks.CompletedTask
|
completed_task =
|
||||||
|> Ash.Changeset.for_create(:create, %{task: id, user: socket.assigns.current_user.id})
|
Putzplan.Tasks.CompletedTask
|
||||||
|> Ash.create!(actor: socket.assigns.current_user)
|
|> 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
|
end
|
||||||
|
|
||||||
defp format_date(date) do
|
defp format_date(date) do
|
||||||
string =
|
string =
|
||||||
case Date.diff(date, Date.utc_today()) do
|
case Date.diff(date, Date.utc_today()) do
|
||||||
|
-1 ->
|
||||||
|
"yesterday"
|
||||||
|
|
||||||
0 ->
|
0 ->
|
||||||
"today"
|
"today"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,12 @@ defmodule PutzplanWeb.TaskLive.Show do
|
||||||
require Ash.Query
|
require Ash.Query
|
||||||
use PutzplanWeb, :live_view
|
use PutzplanWeb, :live_view
|
||||||
|
|
||||||
|
@pubsub_name Putzplan.PubSub
|
||||||
|
|
||||||
|
defp get_topic(id) do
|
||||||
|
"completed:" <> id
|
||||||
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
|
|
@ -90,7 +96,8 @@ defmodule PutzplanWeb.TaskLive.Show do
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@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}
|
{:ok, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -120,6 +127,19 @@ defmodule PutzplanWeb.TaskLive.Show do
|
||||||
|
|
||||||
Ash.destroy!(completed_task, actor: socket.assigns.current_user)
|
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)}
|
{:noreply, stream_delete(socket, :completed_tasks, completed_task)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_info({:upsert, completed_task}, socket) do
|
||||||
|
{:noreply, stream_insert(socket, :completed_tasks, completed_task)}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue