Skip to content

Commit

Permalink
feat: add live chat
Browse files Browse the repository at this point in the history
  • Loading branch information
zvonimirr committed Jun 16, 2024
1 parent a435a5d commit 1683535
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 26 deletions.
59 changes: 59 additions & 0 deletions lib/swipex/chat.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
defmodule Swipex.Chat do
def send_message(from, to, content) do
conn = Bolt.Sips.conn()

Bolt.Sips.query(
conn,
"""
MATCH (u1:User {id: $from})
MATCH (u2:User {id: $to})
CREATE (u1)-[:MESSAGE {content: $content, timestamp: $time, from: $from, to: $to}]->(u2)
""",
%{
from: from,
to: to,
content: content,
time: DateTime.utc_now()
}
)
end

def get_messages(from, to) do
conn = Bolt.Sips.conn()

{:ok, %Bolt.Sips.Response{results: sent}} =
Bolt.Sips.Query.query(
conn,
"""
MATCH ()-[sent:MESSAGE { from: $from, to: $to }]-()
RETURN sent
""",
%{from: from, to: to}
)

{:ok, %Bolt.Sips.Response{results: received}} =
Bolt.Sips.Query.query(
conn,
"""
MATCH ()-[received:MESSAGE { from: $to, to: $from }]->()
RETURN received
""",
%{from: from, to: to}
)

sent_messages =
sent
|> Enum.map(&Map.get(&1, "sent"))
|> Enum.uniq_by(&Map.get(&1, :id))
|> Enum.map(&Map.get(&1, :properties))

received_messages =
received
|> Enum.map(&Map.get(&1, "received"))
|> Enum.uniq_by(&Map.get(&1, :id))
|> Enum.map(&Map.get(&1, :properties))

Enum.concat(sent_messages, received_messages)
|> Enum.sort(&(DateTime.compare(Map.get(&1, "timestamp"), Map.get(&2, "timestamp")) != :gt))
end
end
74 changes: 74 additions & 0 deletions lib/swipex_web/live/chat_live.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
defmodule SwipexWeb.ChatLive do
use SwipexWeb, :live_view
alias Phoenix.PubSub

def mount(%{"id" => id}, %{"user_id" => _user_id}, socket) do
case Swipex.User.get_user_by_id(id) do
{:ok, user} ->
PubSub.subscribe(Swipex.PubSub, "swipex")
{:ok, assign(socket, :recipient, user)}

{:error, _} ->
{:ok, socket |> put_flash(:error, "Something went wrong.") |> redirect(to: "/profile")}
end
end

def mount(_params, _session, socket) do
{:ok,
socket
|> put_flash(:error, "You must be logged in to access this page.")
|> redirect(to: "/login")}
end

def handle_event("send", %{"content" => content}, socket) do
case Swipex.Chat.send_message(
socket.assigns.user["id"],
socket.assigns.recipient["id"],
content
) do
{:ok, _} ->
PubSub.broadcast(Swipex.PubSub, "swipex", {:message, socket.assigns.recipient["id"]})
{:noreply, socket |> put_flash(:info, "Message sent.")}

{:error, _} ->
{:noreply, socket |> put_flash(:error, "Failed to send message.")}
end
end

def handle_info({:message, id}, socket) do
if id == socket.assigns.user["id"] do
{:noreply, socket |> put_flash(:info, "You have a new message!")}
else
{:noreply, socket}
end
end

def render(assigns) do
assigns =
assign(
assigns,
:messages,
Swipex.Chat.get_messages(assigns.user["id"], assigns.recipient["id"])
)

~H"""
<h1 class="text-4xl mb-2">Chat with <%= @recipient["name"] %></h1>
<hr />
<div class="flex flex-col mt-4">
<%= for message <- @messages do %>
<div class="flex flex-row mb-2">
<div class={"p-2 rounded-lg #{
if message["from"] == @user["id"], do: "bg-blue-600 text-white ml-auto", else: "bg-gray-200"
}"}>
<%= message["content"] %>
</div>
</div>
<% end %>
<form phx-submit="send" class="flex flex-row gap-2">
<input type="text" name="content" placeholder="Message" class="flex-1" />
<input type="submit" value="Send" class="bg-blue-500 text-white rounded-lg p-2" />
</form>
</div>
"""
end
end
23 changes: 10 additions & 13 deletions lib/swipex_web/live/profile_live.ex
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
defmodule SwipexWeb.ProfileLive do
use SwipexWeb, :live_view
alias Phoenix.PubSub
alias SwipexWeb.ProfileLive.EditForm

def mount(_params, session, socket) do
if Map.has_key?(session, "user_id") do
PubSub.subscribe(Swipex.PubSub, "swipex")
{:ok, socket}
else
{:ok,
socket
|> put_flash(:error, "You must be logged in to access this page.")
|> redirect(to: "/login")}
end
def mount(_params, %{"user_id" => _user_id}, socket) do
PubSub.subscribe(Swipex.PubSub, "swipex")
{:ok, socket}
end

def mount(_params, _session, socket) do
{:ok,
socket
|> put_flash(:error, "You must be logged in to access this page.")
|> redirect(to: "/login")}
end

def handle_event("like", %{"potential-match" => match_id}, socket) do
Expand Down Expand Up @@ -63,7 +62,6 @@ defmodule SwipexWeb.ProfileLive do
<div class="flex flex-col gap-3">
<h1 class="text-4xl"><%= @user["name"] %></h1>
<p>Hey there, <%= @user["name"] %>, this is your profile page.</p>
<hr />
</div>
<%= if @potential_match do %>
Expand Down Expand Up @@ -95,7 +93,6 @@ defmodule SwipexWeb.ProfileLive do
</div>
<% end %>
</div>
<hr />
<div class="mt-3 flex flex-col gap-4">
<h1 class="text-5xl">Your matches</h1>
<div class="flex gap-3">
Expand Down
Empty file.
13 changes: 0 additions & 13 deletions lib/swipex_web/live/profile_live/edit_form.ex

This file was deleted.

1 change: 1 addition & 0 deletions lib/swipex_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ defmodule SwipexWeb.Router do

live_session :default, on_mount: [{SwipexWeb.Profile, :current_user}] do
live "/profile", ProfileLive, :index
live "/chat/:id", ChatLive, :index
end
end

Expand Down

0 comments on commit 1683535

Please sign in to comment.