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})
|
Repo.insert!(%RoomMembership{room: room, user: user})
|
||||||
end
|
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
|
def change_room(room, attrs \\ %{}) do
|
||||||
Room.changeset(room, attrs)
|
Room.changeset(room, attrs)
|
||||||
end
|
end
|
||||||
@ -47,6 +53,13 @@ defmodule Slax.Chat do
|
|||||||
Repo.all(query)
|
Repo.all(query)
|
||||||
end
|
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
|
def list_messages_in_room(%Room{id: room_id}) do
|
||||||
query =
|
query =
|
||||||
from(m in Message,
|
from(m in Message,
|
||||||
|
@ -65,6 +65,7 @@ defmodule SlaxWeb.ChatRoomLive do
|
|||||||
<h1 class="text-sm font-bold leading-none">
|
<h1 class="text-sm font-bold leading-none">
|
||||||
#<%= @room.name %>
|
#<%= @room.name %>
|
||||||
<.link
|
<.link
|
||||||
|
:if={@joined?}
|
||||||
class="font-normal text-xs text-blue-600 hover:text-blue-700"
|
class="font-normal text-xs text-blue-600 hover:text-blue-700"
|
||||||
navigate={~p"/rooms/#{@room}/edit"}
|
navigate={~p"/rooms/#{@room}/edit"}
|
||||||
>
|
>
|
||||||
@ -135,7 +136,7 @@ defmodule SlaxWeb.ChatRoomLive do
|
|||||||
timezone={@timezone}
|
timezone={@timezone}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="h-12 bg-white px-4 pb-4">
|
<div :if={@joined?} class="h-12 bg-white px-4 pb-4">
|
||||||
<.form
|
<.form
|
||||||
id="new-message-form"
|
id="new-message-form"
|
||||||
for={@new_message_form}
|
for={@new_message_form}
|
||||||
@ -158,13 +159,41 @@ defmodule SlaxWeb.ChatRoomLive do
|
|||||||
</button>
|
</button>
|
||||||
</.form>
|
</.form>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl Phoenix.LiveView
|
@impl Phoenix.LiveView
|
||||||
def mount(_params, _session, socket) do
|
def mount(_params, _session, socket) do
|
||||||
rooms = Chat.list_rooms()
|
rooms = Chat.list_joined_rooms(socket.assigns.current_user)
|
||||||
users = Accounts.list_users()
|
users = Accounts.list_users()
|
||||||
|
|
||||||
timezone = get_connect_params(socket)["timezone"]
|
timezone = get_connect_params(socket)["timezone"]
|
||||||
@ -206,7 +235,12 @@ defmodule SlaxWeb.ChatRoomLive do
|
|||||||
|
|
||||||
{:noreply,
|
{:noreply,
|
||||||
socket
|
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)
|
|> stream(:messages, messages, reset: true)
|
||||||
|> assign_message_form(Chat.change_message(%Message{}))
|
|> assign_message_form(Chat.change_message(%Message{}))
|
||||||
|> push_event("scroll_messages_to_bottom", %{})}
|
|> push_event("scroll_messages_to_bottom", %{})}
|
||||||
@ -228,12 +262,16 @@ defmodule SlaxWeb.ChatRoomLive do
|
|||||||
%{current_user: user, room: room} = socket.assigns
|
%{current_user: user, room: room} = socket.assigns
|
||||||
|
|
||||||
socket =
|
socket =
|
||||||
case Chat.create_message(room, user, message_params) do
|
if Chat.joined?(room, user) do
|
||||||
{:ok, _message} ->
|
case Chat.create_message(room, user, message_params) do
|
||||||
assign_message_form(socket, Chat.change_message(%Message{}))
|
{:ok, _message} ->
|
||||||
|
assign_message_form(socket, Chat.change_message(%Message{}))
|
||||||
|
|
||||||
{:error, changeset} ->
|
{:error, changeset} ->
|
||||||
assign_message_form(socket, changeset)
|
assign_message_form(socket, changeset)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
socket
|
||||||
end
|
end
|
||||||
|
|
||||||
{:noreply, socket}
|
{:noreply, socket}
|
||||||
@ -246,6 +284,16 @@ defmodule SlaxWeb.ChatRoomLive do
|
|||||||
{:noreply, socket}
|
{:noreply, socket}
|
||||||
end
|
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
|
@impl Phoenix.LiveView
|
||||||
def handle_info({:new_message, message}, socket) do
|
def handle_info({:new_message, message}, socket) do
|
||||||
socket =
|
socket =
|
||||||
|
@ -33,12 +33,19 @@ defmodule SlaxWeb.ChatRoomLive.Edit do
|
|||||||
@impl Phoenix.LiveView
|
@impl Phoenix.LiveView
|
||||||
def mount(%{"id" => id}, _session, socket) do
|
def mount(%{"id" => id}, _session, socket) do
|
||||||
room = Chat.get_room!(id)
|
room = Chat.get_room!(id)
|
||||||
changeset = Chat.change_room(room)
|
|
||||||
|
|
||||||
socket =
|
socket =
|
||||||
socket
|
if Chat.joined?(room, socket.assigns.current_user) do
|
||||||
|> assign(page_title: "Edit chat room", room: room)
|
changeset = Chat.change_room(room)
|
||||||
|> assign_form(changeset)
|
|
||||||
|
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}
|
{:ok, socket}
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user