summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLogan Hunt <loganhunt@simponic.xyz>2022-04-14 11:43:34 -0600
committerLogan Hunt <loganhunt@simponic.xyz>2022-04-14 11:43:34 -0600
commitcc58a376a94c28532121fca2e1ab1d0e7de11046 (patch)
treecb31a620c444e18ad8efa535ec946a7bcd792d6f /lib
parentddfab312f73a3f3e15ceb6fec7d350500adb53d6 (diff)
downloadaggiedit-cc58a376a94c28532121fca2e1ab1d0e7de11046.tar.gz
aggiedit-cc58a376a94c28532121fca2e1ab1d0e7de11046.zip
Add pubsub
Diffstat (limited to 'lib')
-rw-r--r--lib/aggiedit/rooms.ex118
-rw-r--r--lib/aggiedit_web/live/post_live/index.ex11
-rw-r--r--lib/aggiedit_web/live/post_live/index.html.heex55
-rw-r--r--lib/aggiedit_web/templates/layout/_user_menu.html.heex2
4 files changed, 48 insertions, 138 deletions
diff --git a/lib/aggiedit/rooms.ex b/lib/aggiedit/rooms.ex
index 1eb09f9..898dfe1 100644
--- a/lib/aggiedit/rooms.ex
+++ b/lib/aggiedit/rooms.ex
@@ -9,96 +9,30 @@ defmodule Aggiedit.Rooms do
alias Aggiedit.Accounts
alias Aggiedit.Rooms.Room
- @doc """
- Returns the list of rooms.
+ alias Phoenix.PubSub
- ## Examples
-
- iex> list_rooms()
- [%Room{}, ...]
-
- """
def list_rooms do
Repo.all(Room)
end
- @doc """
- Gets a single room.
-
- Raises `Ecto.NoResultsError` if the Room does not exist.
-
- ## Examples
-
- iex> get_room!(123)
- %Room{}
-
- iex> get_room!(456)
- ** (Ecto.NoResultsError)
-
- """
def get_room!(id), do: Repo.get!(Room, id)
- @doc """
- Creates a room.
-
- ## Examples
-
- iex> create_room(%{field: value})
- {:ok, %Room{}}
-
- iex> create_room(%{field: bad_value})
- {:error, %Ecto.Changeset{}}
-
- """
def create_room(attrs \\ %{}) do
%Room{}
|> Room.changeset(attrs)
|> Repo.insert()
end
- @doc """
- Updates a room.
-
- ## Examples
-
- iex> update_room(room, %{field: new_value})
- {:ok, %Room{}}
-
- iex> update_room(room, %{field: bad_value})
- {:error, %Ecto.Changeset{}}
-
- """
def update_room(%Room{} = room, attrs) do
room
|> Room.changeset(attrs)
|> Repo.update()
end
- @doc """
- Deletes a room.
-
- ## Examples
-
- iex> delete_room(room)
- {:ok, %Room{}}
-
- iex> delete_room(room)
- {:error, %Ecto.Changeset{}}
-
- """
def delete_room(%Room{} = room) do
Repo.delete(room)
end
- @doc """
- Returns an `%Ecto.Changeset{}` for tracking room changes.
-
- ## Examples
-
- iex> change_room(room)
- %Ecto.Changeset{data: %Room{}}
-
- """
def change_room(%Room{} = room, attrs \\ %{}) do
Room.changeset(room, attrs)
end
@@ -117,23 +51,9 @@ defmodule Aggiedit.Rooms do
end
def posts_in_room(room_id) do
- Repo.all((from p in Post, where: p.room_id == ^room_id, select: p))
+ Repo.all((from p in Post, where: p.room_id == ^room_id, order_by: [asc: :id], select: p))
end
- @doc """
- Gets a single post.
-
- Raises `Ecto.NoResultsError` if the Post does not exist.
-
- ## Examples
-
- iex> get_post!(123)
- %Post{}
-
- iex> get_post!(456)
- ** (Ecto.NoResultsError)
-
- """
def get_post!(id), do: Repo.get!(Post, id)
def create_post(attrs, user, after_save \\ &{:ok, &1}) do
@@ -145,6 +65,7 @@ defmodule Aggiedit.Rooms do
|> Ecto.Changeset.put_assoc(:user, user)
|> Ecto.Changeset.put_assoc(:room, user.room)
|> Repo.insert()
+ |> broadcast_post_over_room(:post_created)
|> post_saved(after_save)
end
@@ -152,6 +73,7 @@ defmodule Aggiedit.Rooms do
post
|> Post.changeset(attrs)
|> Repo.update()
+ |> broadcast_post_over_room(:post_updated)
|> post_saved(after_save)
end
@@ -160,32 +82,22 @@ defmodule Aggiedit.Rooms do
end
defp post_saved(error, _fun), do: error
- @doc """
- Deletes a post.
-
- ## Examples
-
- iex> delete_post(post)
- {:ok, %Post{}}
-
- iex> delete_post(post)
- {:error, %Ecto.Changeset{}}
-
- """
def delete_post(%Post{} = post) do
Repo.delete(post)
+ |> broadcast_post_over_room(:post_deleted)
end
- @doc """
- Returns an `%Ecto.Changeset{}` for tracking post changes.
-
- ## Examples
-
- iex> change_post(post)
- %Ecto.Changeset{data: %Post{}}
-
- """
def change_post(%Post{} = post, attrs \\ %{}) do
Post.changeset(post, attrs)
end
+
+ defp broadcast_post_over_room({:error, _reason}=error, _event), do: error
+ defp broadcast_post_over_room({:ok, post}, event) do
+ PubSub.broadcast(Aggiedit.PubSub, "room:#{post.room_id}:posts", {event, post})
+ {:ok, post}
+ end
+
+ def subscribe(room) do
+ PubSub.subscribe(Aggiedit.PubSub, "room:#{room.id}:posts")
+ end
end
diff --git a/lib/aggiedit_web/live/post_live/index.ex b/lib/aggiedit_web/live/post_live/index.ex
index 57ae727..6b2be56 100644
--- a/lib/aggiedit_web/live/post_live/index.ex
+++ b/lib/aggiedit_web/live/post_live/index.ex
@@ -10,7 +10,9 @@ defmodule AggieditWeb.PostLive.Index do
def mount(%{"room_id" => _room_id} = params, session, socket) do
{:ok, socket} = assign_socket_room_and_user_or_error(params, session, socket)
case socket.assigns do
- %{:room => room} -> {:ok, assign(socket, %{:posts => room |> Repo.preload(posts: [:user, :upload]) |> Map.get(:posts)})}
+ %{:room => room} ->
+ if connected?(socket), do: Rooms.subscribe(socket.assigns.room)
+ {:ok, assign(socket, %{:posts => room |> Repo.preload(posts: [:user, :upload]) |> Map.get(:posts)}), temporary_assigns: [posts: []]}
_ -> {:ok, socket}
end
end
@@ -59,4 +61,11 @@ defmodule AggieditWeb.PostLive.Index do
{:noreply, socket |> put_flash(:error, "You do not have permission to delete this post.") |> redirect(to: Routes.post_index_path(socket, :index, socket.assigns.room))}
end
end
+
+ @impl true
+ def handle_info({action, post}, socket) when action in [:post_created, :post_updated, :post_deleted] do
+ {:noreply, update(socket, :posts, fn posts ->
+ [posts | post]
+ end)}
+ end
end
diff --git a/lib/aggiedit_web/live/post_live/index.html.heex b/lib/aggiedit_web/live/post_live/index.html.heex
index 7532685..efb42cb 100644
--- a/lib/aggiedit_web/live/post_live/index.html.heex
+++ b/lib/aggiedit_web/live/post_live/index.html.heex
@@ -15,39 +15,28 @@
<% end %>
<span><%= live_patch "New Post", to: Routes.post_index_path(@socket, :new, @room) %></span>
-<%= for post <- @posts do %>
- <div class="card d-flex flex-row align-items-center p-2 m-2 shadow">
- <%= if !is_nil(post.upload) do %>
- <%= live_redirect to: Routes.post_show_path(@socket, :show, @room, post) do %>
- <div class="card-image d-flex justify-content-center" style="width: 100px">
- <img class="fluid-img thumbnail" src={Routes.static_path(@socket, "/uploads/#{post.upload.file}")} />
- </div>
+<div id="posts" phx-update="prepend">
+ <%= for post <- @posts do %>
+ <div id={"post-#{post.id}"} class="card d-flex flex-row align-items-center p-2 m-2 shadow">
+ <%= if !is_nil(post.upload) do %>
+ <%= live_redirect to: Routes.post_show_path(@socket, :show, @room, post) do %>
+ <div class="card-image d-flex justify-content-center" style="width: 100px">
+ <img class="fluid-img thumbnail" src={Routes.static_path(@socket, "/uploads/#{post.upload.file}")} />
+ </div>
+ <% end %>
<% end %>
- <% end %>
- <div class="card-body">
- <%= live_redirect to: Routes.post_show_path(@socket, :show, @room, post) do %>
- <h4 class="card-title"><%= post.title %></h4>
- <% end %>
- <h6 class="card-subtitle mb-2"><span class="text-muted">aggie/</span><%= post.user.username %></h6>
- <p class="card-text"><%= post.body %></p>
+ <div class="card-body">
+ <%= live_redirect to: Routes.post_show_path(@socket, :show, @room, post) do %>
+ <h4 class="card-title"><%= post.title %></h4>
+ <% end %>
+ <h6 class="card-subtitle mb-2"><span class="text-muted">aggie/</span><%= post.user.username %></h6>
+ <p class="card-text"><%= post.body %></p>
- <%= if Aggiedit.Roles.guard?(@current_user, :edit, post) && Aggiedit.Roles.guard?(@current_user, :edit, post) do %>
- <span><%= live_patch "Edit", to: Routes.post_index_path(@socket, :edit, @room, post) %></span>
- <span><%= link "Delete", to: "#", phx_click: "delete", phx_value_id: post.id %></span>
- <% end %>
+ <%= if Aggiedit.Roles.guard?(@current_user, :edit, post) && Aggiedit.Roles.guard?(@current_user, :edit, post) do %>
+ <span><%= live_patch "Edit", to: Routes.post_index_path(@socket, :edit, @room, post) %></span>
+ <span><%= link "Delete", to: "#", phx_click: "delete", phx_value_id: post.id %></span>
+ <% end %>
+ </div>
</div>
- </div>
-<!--
- <div class=>
- </div>
- <tr id={"post-#{post.id}"}>
- <td><%= post.title %></td>
- <td><%= post.body %></td>
-
- <td>
- <span></span>
- </td>
- </tr>
- -->
-<% end %>
-
+ <% end %>
+</div>
diff --git a/lib/aggiedit_web/templates/layout/_user_menu.html.heex b/lib/aggiedit_web/templates/layout/_user_menu.html.heex
index 4ab3b78..bbd9f97 100644
--- a/lib/aggiedit_web/templates/layout/_user_menu.html.heex
+++ b/lib/aggiedit_web/templates/layout/_user_menu.html.heex
@@ -1,6 +1,6 @@
<%= if @current_user do %>
<li class="nav-item active">
- <%= link "Settings", to: Routes.user_settings_path(@conn, :edit), class: "nav-link" %>
+ <%= link "#{@current_user.username}/settings", to: Routes.user_settings_path(@conn, :edit), class: "nav-link" %>
</li>
<li class="nav-item active">
<%= link "Log out", to: Routes.user_session_path(@conn, :delete), method: :delete, class: "nav-link" %>