feat(chat): add auth logic for room memberships
This commit is contained in:
parent
d3253bd900
commit
9755dc2b9e
@ -29,6 +29,12 @@ defmodule Slax.Chat do
|
||||
Repo.insert!(%RoomMembership{room: room, user: user})
|
||||
end
|
||||
|
||||
def joined?(%Room{} = room, %User{} = user) do
|
||||
Repo.exists?(
|
||||
from rm in RoomMembership, where: rm.room_id == ^room.id and rm.user_id == ^user.id
|
||||
)
|
||||
end
|
||||
|
||||
def change_room(room, attrs \\ %{}) do
|
||||
Room.changeset(room, attrs)
|
||||
end
|
||||
@ -47,6 +53,13 @@ defmodule Slax.Chat do
|
||||
Repo.all(query)
|
||||
end
|
||||
|
||||
def list_joined_rooms(%User{} = user) do
|
||||
user
|
||||
|> Repo.preload(:rooms)
|
||||
|> Map.fetch!(:rooms)
|
||||
|> Enum.sort_by(& &1.name)
|
||||
end
|
||||
|
||||
def list_messages_in_room(%Room{id: room_id}) do
|
||||
query =
|
||||
from(m in Message,
|
||||
|
@ -65,6 +65,7 @@ defmodule SlaxWeb.ChatRoomLive do
|
||||
<h1 class="text-sm font-bold leading-none">
|
||||
#<%= @room.name %>
|
||||
<.link
|
||||
:if={@joined?}
|
||||
class="font-normal text-xs text-blue-600 hover:text-blue-700"
|
||||
navigate={~p"/rooms/#{@room}/edit"}
|
||||
>
|
||||
@ -135,7 +136,7 @@ defmodule SlaxWeb.ChatRoomLive do
|
||||
timezone={@timezone}
|
||||
/>
|
||||
</div>
|
||||
<div class="h-12 bg-white px-4 pb-4">
|
||||
<div :if={@joined?} class="h-12 bg-white px-4 pb-4">
|
||||
<.form
|
||||
id="new-message-form"
|
||||
for={@new_message_form}
|
||||
@ -158,13 +159,41 @@ defmodule SlaxWeb.ChatRoomLive do
|
||||
</button>
|
||||
</.form>
|
||||
</div>
|
||||
<div
|
||||
:if={!@joined?}
|
||||
class="flex justify-around mx-5 mb-5 p-6 bg-slate-100 border-slate-300 border rounded-lg"
|
||||
>
|
||||
<div class="max-w-3-xl text-center">
|
||||
<div class="mb-4">
|
||||
<h1 class="text-xl font-semibold"><%= @room.name %></h1>
|
||||
<p :if={@room.topic} class="text-sm mt-1 text-gray-600"><%= @room.topic %></p>
|
||||
</div>
|
||||
<div class="flex items-center justify-around">
|
||||
<buttom
|
||||
phx-click="join-room"
|
||||
class="px-4 py-2 bg-green-600 text-white rounded hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500"
|
||||
>
|
||||
Join Room
|
||||
</buttom>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<.link
|
||||
navigate={~p"/rooms"}
|
||||
href="#"
|
||||
class="text-sm text-slate-500 underline hover:text-slate-600"
|
||||
>
|
||||
Back to All Rooms
|
||||
</.link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
@impl Phoenix.LiveView
|
||||
def mount(_params, _session, socket) do
|
||||
rooms = Chat.list_rooms()
|
||||
rooms = Chat.list_joined_rooms(socket.assigns.current_user)
|
||||
users = Accounts.list_users()
|
||||
|
||||
timezone = get_connect_params(socket)["timezone"]
|
||||
@ -206,7 +235,12 @@ defmodule SlaxWeb.ChatRoomLive do
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> assign(hide_topic?: false, page_title: "# #{room.name}", room: room)
|
||||
|> assign(
|
||||
hide_topic?: false,
|
||||
joined?: Chat.joined?(room, socket.assigns.current_user),
|
||||
page_title: "# #{room.name}",
|
||||
room: room
|
||||
)
|
||||
|> stream(:messages, messages, reset: true)
|
||||
|> assign_message_form(Chat.change_message(%Message{}))
|
||||
|> push_event("scroll_messages_to_bottom", %{})}
|
||||
@ -228,12 +262,16 @@ defmodule SlaxWeb.ChatRoomLive do
|
||||
%{current_user: user, room: room} = socket.assigns
|
||||
|
||||
socket =
|
||||
case Chat.create_message(room, user, message_params) do
|
||||
{:ok, _message} ->
|
||||
assign_message_form(socket, Chat.change_message(%Message{}))
|
||||
if Chat.joined?(room, user) do
|
||||
case Chat.create_message(room, user, message_params) do
|
||||
{:ok, _message} ->
|
||||
assign_message_form(socket, Chat.change_message(%Message{}))
|
||||
|
||||
{:error, changeset} ->
|
||||
assign_message_form(socket, changeset)
|
||||
{:error, changeset} ->
|
||||
assign_message_form(socket, changeset)
|
||||
end
|
||||
else
|
||||
socket
|
||||
end
|
||||
|
||||
{:noreply, socket}
|
||||
@ -246,6 +284,16 @@ defmodule SlaxWeb.ChatRoomLive do
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
@impl Phoenix.LiveView
|
||||
def handle_event("join-room", _, socket) do
|
||||
current_user = socket.assigns.current_user
|
||||
room = socket.assigns.room
|
||||
Chat.join_room!(room, current_user)
|
||||
Chat.subscribe_to_room(room)
|
||||
socket = assign(socket, joined?: true, rooms: Chat.list_joined_rooms(current_user))
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
@impl Phoenix.LiveView
|
||||
def handle_info({:new_message, message}, socket) do
|
||||
socket =
|
||||
|
@ -33,12 +33,19 @@ defmodule SlaxWeb.ChatRoomLive.Edit do
|
||||
@impl Phoenix.LiveView
|
||||
def mount(%{"id" => id}, _session, socket) do
|
||||
room = Chat.get_room!(id)
|
||||
changeset = Chat.change_room(room)
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(page_title: "Edit chat room", room: room)
|
||||
|> assign_form(changeset)
|
||||
if Chat.joined?(room, socket.assigns.current_user) do
|
||||
changeset = Chat.change_room(room)
|
||||
|
||||
socket
|
||||
|> assign(page_title: "Edit chat room", room: room)
|
||||
|> assign_form(changeset)
|
||||
else
|
||||
socket
|
||||
|> put_flash(:error, "Permission denied")
|
||||
|> push_navigate(to: ~p"/")
|
||||
end
|
||||
|
||||
{:ok, socket}
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user