Add pubsub
This commit is contained in:
parent
ddfab312f7
commit
cc58a376a9
@ -9,96 +9,30 @@ defmodule Aggiedit.Rooms do
|
|||||||
alias Aggiedit.Accounts
|
alias Aggiedit.Accounts
|
||||||
alias Aggiedit.Rooms.Room
|
alias Aggiedit.Rooms.Room
|
||||||
|
|
||||||
@doc """
|
alias Phoenix.PubSub
|
||||||
Returns the list of rooms.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> list_rooms()
|
|
||||||
[%Room{}, ...]
|
|
||||||
|
|
||||||
"""
|
|
||||||
def list_rooms do
|
def list_rooms do
|
||||||
Repo.all(Room)
|
Repo.all(Room)
|
||||||
end
|
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)
|
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
|
def create_room(attrs \\ %{}) do
|
||||||
%Room{}
|
%Room{}
|
||||||
|> Room.changeset(attrs)
|
|> Room.changeset(attrs)
|
||||||
|> Repo.insert()
|
|> Repo.insert()
|
||||||
end
|
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
|
def update_room(%Room{} = room, attrs) do
|
||||||
room
|
room
|
||||||
|> Room.changeset(attrs)
|
|> Room.changeset(attrs)
|
||||||
|> Repo.update()
|
|> Repo.update()
|
||||||
end
|
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
|
def delete_room(%Room{} = room) do
|
||||||
Repo.delete(room)
|
Repo.delete(room)
|
||||||
end
|
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
|
def change_room(%Room{} = room, attrs \\ %{}) do
|
||||||
Room.changeset(room, attrs)
|
Room.changeset(room, attrs)
|
||||||
end
|
end
|
||||||
@ -117,23 +51,9 @@ defmodule Aggiedit.Rooms do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def posts_in_room(room_id) do
|
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
|
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 get_post!(id), do: Repo.get!(Post, id)
|
||||||
|
|
||||||
def create_post(attrs, user, after_save \\ &{:ok, &1}) do
|
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(:user, user)
|
||||||
|> Ecto.Changeset.put_assoc(:room, user.room)
|
|> Ecto.Changeset.put_assoc(:room, user.room)
|
||||||
|> Repo.insert()
|
|> Repo.insert()
|
||||||
|
|> broadcast_post_over_room(:post_created)
|
||||||
|> post_saved(after_save)
|
|> post_saved(after_save)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -152,6 +73,7 @@ defmodule Aggiedit.Rooms do
|
|||||||
post
|
post
|
||||||
|> Post.changeset(attrs)
|
|> Post.changeset(attrs)
|
||||||
|> Repo.update()
|
|> Repo.update()
|
||||||
|
|> broadcast_post_over_room(:post_updated)
|
||||||
|> post_saved(after_save)
|
|> post_saved(after_save)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -160,32 +82,22 @@ defmodule Aggiedit.Rooms do
|
|||||||
end
|
end
|
||||||
defp post_saved(error, _fun), do: error
|
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
|
def delete_post(%Post{} = post) do
|
||||||
Repo.delete(post)
|
Repo.delete(post)
|
||||||
|
|> broadcast_post_over_room(:post_deleted)
|
||||||
end
|
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
|
def change_post(%Post{} = post, attrs \\ %{}) do
|
||||||
Post.changeset(post, attrs)
|
Post.changeset(post, attrs)
|
||||||
end
|
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
|
end
|
||||||
|
@ -10,7 +10,9 @@ defmodule AggieditWeb.PostLive.Index do
|
|||||||
def mount(%{"room_id" => _room_id} = params, session, socket) do
|
def mount(%{"room_id" => _room_id} = params, session, socket) do
|
||||||
{:ok, socket} = assign_socket_room_and_user_or_error(params, session, socket)
|
{:ok, socket} = assign_socket_room_and_user_or_error(params, session, socket)
|
||||||
case socket.assigns do
|
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}
|
_ -> {:ok, socket}
|
||||||
end
|
end
|
||||||
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))}
|
{: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
|
||||||
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
|
end
|
||||||
|
@ -15,39 +15,28 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<span><%= live_patch "New Post", to: Routes.post_index_path(@socket, :new, @room) %></span>
|
<span><%= live_patch "New Post", to: Routes.post_index_path(@socket, :new, @room) %></span>
|
||||||
<%= for post <- @posts do %>
|
<div id="posts" phx-update="prepend">
|
||||||
<div class="card d-flex flex-row align-items-center p-2 m-2 shadow">
|
<%= for post <- @posts do %>
|
||||||
<%= if !is_nil(post.upload) do %>
|
<div id={"post-#{post.id}"} class="card d-flex flex-row align-items-center p-2 m-2 shadow">
|
||||||
<%= live_redirect to: Routes.post_show_path(@socket, :show, @room, post) do %>
|
<%= if !is_nil(post.upload) do %>
|
||||||
<div class="card-image d-flex justify-content-center" style="width: 100px">
|
<%= live_redirect to: Routes.post_show_path(@socket, :show, @room, post) do %>
|
||||||
<img class="fluid-img thumbnail" src={Routes.static_path(@socket, "/uploads/#{post.upload.file}")} />
|
<div class="card-image d-flex justify-content-center" style="width: 100px">
|
||||||
</div>
|
<img class="fluid-img thumbnail" src={Routes.static_path(@socket, "/uploads/#{post.upload.file}")} />
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<div class="card-body">
|
||||||
<div class="card-body">
|
<%= live_redirect to: Routes.post_show_path(@socket, :show, @room, post) do %>
|
||||||
<%= live_redirect to: Routes.post_show_path(@socket, :show, @room, post) do %>
|
<h4 class="card-title"><%= post.title %></h4>
|
||||||
<h4 class="card-title"><%= post.title %></h4>
|
<% end %>
|
||||||
<% end %>
|
<h6 class="card-subtitle mb-2"><span class="text-muted">aggie/</span><%= post.user.username %></h6>
|
||||||
<h6 class="card-subtitle mb-2"><span class="text-muted">aggie/</span><%= post.user.username %></h6>
|
<p class="card-text"><%= post.body %></p>
|
||||||
<p class="card-text"><%= post.body %></p>
|
|
||||||
|
|
||||||
<%= if Aggiedit.Roles.guard?(@current_user, :edit, post) && Aggiedit.Roles.guard?(@current_user, :edit, post) do %>
|
<%= 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><%= 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>
|
<span><%= link "Delete", to: "#", phx_click: "delete", phx_value_id: post.id %></span>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<% end %>
|
||||||
<!--
|
</div>
|
||||||
<div class=>
|
|
||||||
</div>
|
|
||||||
<tr id={"post-#{post.id}"}>
|
|
||||||
<td><%= post.title %></td>
|
|
||||||
<td><%= post.body %></td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
<span></span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
-->
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<%= if @current_user do %>
|
<%= if @current_user do %>
|
||||||
<li class="nav-item active">
|
<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>
|
||||||
<li class="nav-item active">
|
<li class="nav-item active">
|
||||||
<%= link "Log out", to: Routes.user_session_path(@conn, :delete), method: :delete, class: "nav-link" %>
|
<%= link "Log out", to: Routes.user_session_path(@conn, :delete), method: :delete, class: "nav-link" %>
|
||||||
|
Loading…
Reference in New Issue
Block a user