UsamaHaide0786

UsamaHaide0786

My chat app using liveViews is not updating every user in same room

I have created a chat app using live views in which whenever user joins a chatroom then all the messages of the chat room displayed to him that are saved in database and if some updates or edit any message it works perfect everyone sees the updated message but sometimes it misses some user screens specially if some leave a chat room open for few hours then the that user stops receiving updates and he need to refresh browser even sometimes browser refresh don’t work
Here is my code in my live view for chat

defmodule FchatappWeb.ChatLive do
  use FchatappWeb, :live_view
  alias Fchatapp.Blog
  alias Fchatapp.Blog.Room
  alias Fchatapp.Repo
  alias Fchatapp.Chats.Message
  import Ecto.Query, only: [from: 2]

  @imp true
  def mount(%{"room" => name}, session, socket) do
    room_data = Repo.get_by(Room, title: name)
    room_data_id = room_data.id

    query =
      from m in Message,
        where: m.room_id == ^room_data_id

    db_messages = Repo.all(query)
    topic = "room:" <> name

    email =
      case session["current_user"] do
        nil ->
          "Anonymous User"

        _ ->
          session["current_user"].email
      end

    anonymous_user =
      case email do
        "Anonymous User" ->
          true

        _ ->
          false
      end

    if connected?(socket) do
      Process.send_after(self(), %{event: "update", room_id: room_data_id}, 5000)
      FchatappWeb.Endpoint.subscribe(topic)
      FchatappWeb.Presence.track(self(), topic, email, %{})
    end

    {:ok,
     assign(socket,
       room: name,
       room_id: room_data.id,
       image: room_data.image_thumb_url,
       country: room_data.country,
       state: room_data.state,
       city: room_data.city,
       description: room_data.description,
       topic: topic,
       user: email,
       anonymous_user: anonymous_user,
       message: "",
       image_public_id: "",
       image_thumb_url: "",
       image_url: "",
       image_secure_url: "",
       img_context: "",
       messages: db_messages,
       user_list: [],
       temporary_assigns: [messages: []]
     )}
  end

  @imp true
  def handle_event(
        "submit_message",
        %{
          "_csrf_token" => _token,
          "chat" => %{
            "message" => message,
            "image_public_id" => image_public_id,
            "image_thumb_url" => image_thumb_url,
            "image_url" => image_url,
            "image_secure_url" => image_secure_url,
            "room_id" => room_id,
            "img_context" => img_context
          }
        },
        socket
      ) do
    message = %{
      uid: UUID.uuid4(),
      content: message,
      user: socket.assigns.user,
      image_public_id: image_public_id,
      image_thumb_url: image_thumb_url,
      image_url: image_url,
      image_secure_url: image_secure_url,
      room_id: room_id,
      img_context: img_context
    }

    case image_url do
      "" ->
        {:ok}

      _ ->
        resp =
          HTTPoison.post(
            "http://localhost:4000/api/create-message",
            message |> Poison.encode!(),
            %{"Content-Type" => "application/json"}
          )
    end

    FchatappWeb.Endpoint.broadcast(socket.assigns.topic, "new-message", message)

    {:noreply,
     assign(socket,
       message: "",
       image_public_id: "",
       image_thumb_url: "",
       image_url: "",
       image_secure_url: ""
     )}
  end

  @imp true
  def handle_event(
        "form_update",
        %{
          "_csrf_token" => _token,
          "chat" => %{
            "message" => message,
            "image_public_id" => image_public_id,
            "image_thumb_url" => image_thumb_url,
            "image_url" => image_url,
            "image_secure_url" => image_secure_url,
            "room_id" => room_id,
            "img_context" => img_context
          }
        },
        socket
      ) do

    {:noreply,
     assign(socket,
       message: message,
       image_public_id: image_public_id,
       image_thumb_url: image_thumb_url,
       image_url: image_url,
       image_secure_url: image_secure_url,
       room_id: room_id,
       img_context: img_context
     )}
  end

  @imp true
  def handle_info(%{event: "new-message", payload: message}, socket) do
    {:noreply, assign(socket, messages: [message])}
  end

  def handle_info(%{event: "update", room_id: id}, socket) do
    Process.send_after(self(), %{event: "update", room_id: id}, 5000)

    query =
      from m in Message,
        where: m.room_id == ^id

    db_messages = Repo.all(query)
    {:noreply, assign(socket, messages: db_messages)}
  end

  def handle_info(%{event: "presence_diff", payload: %{joins: joins, leaves: leaves}}, socket) do
    join_messages =
      joins
      |> Map.keys()
      |> Enum.map(fn username ->
        %{uid: UUID.uuid4(), content: "#{username} Joined!", user: "System"}
      end)

    leave_messages =
      leaves
      |> Map.keys()
      |> Enum.map(fn username ->
        %{uid: UUID.uuid4(), content: "#{username} Left!", user: "System"}
      end)

    user_list =
      FchatappWeb.Presence.list(socket.assigns.topic)
      |> Map.keys()

    {:noreply, assign(socket, user_list: user_list)}
  end

  def display_message(%{uid: id, content: content, user: "System"}) do
    ~E"""
    <p id="<%= id %>"><em><%= content %></em></p>
    """
  end

  def display_message(
        %{
          uid: id,
          content: content,
          user: user,
          image_public_id: image_public_id,
          image_thumb_url: image_thumb_url,
          image_url: image_url,
          image_secure_url: image_secure_url
        } = params
      ) do
    case image_url do
      "" ->
        ~E"""
        <div id="<%= id %>">
        <img src="https://media.istockphoto.com/vectors/emoticon-with-sorry-sign-vector-id1266144552?k=20&m=1266144552&s=170667a&w=0&h=m-3MDOgzYDjsynL729p7G8Pn98PNKLu345LnFwkcZlY=" width="100" height="150"></img>
        <p><em>Image cant be empty</em></p>
        </div>

        """

      _ ->
        ~E"""
        <div id="<%= id %>">
        <div><img src="<%= image_url%>" width="100" height="150"></img>
        <p><strong><%= user%>: </strong><%= content %> </p>
        </div>
        </div>
        """
    end
  end
end

Here is template hidden inputs are coming from an api


<section>

    <div id="header-text">
        <div id="title">
        <p >Currently Chatting In <strong><%= @room %></strong></p>
        <p ><img src="<%= @image %>" alt="no-image"></p>
        <p ><%= @description %></p>
        <button><a href="/">Leave Room</a></button>
        </div>
    </div>
    <br>

    <div id="main">
        <div class="sub-main">
            <div id="chat-container">
                <div id="messages-container" phx-update="append">
                    <%= for message <- @messages do%>
                    <%= display_message(message) %>
                    <% end %>
                </div>
            </div>
            <%= if @anonymous_user do %>
            <p><strong><em>Please login to send messages</em></strong></p>
            <% else %>
            <div id="form-chat">
                <%= f = form_for :chat, "#", id: "chat-form", phx_submit: :submit_message, phx_change: :form_update %>
                <%= text_input f, :message, value: @message, placeholder: "Enter your message..." %>
                <%= hidden_input f, :image_public_id, value: @image_public_id, id: "image_public_id"  %>

                <%= hidden_input f, :image_thumb_url, value: @image_thumb_url, id: "image_thumb_url" %>

                <%= hidden_input f, :image_url, value: @image_url, id: "image_url" %>

                <%= hidden_input f, :image_secure_url, value: @image_secure_url, id: "image_secure_url" %>
                <%= hidden_input f, :room_id, value: @room_id, id: "room_id" %>
                <%= hidden_input f, :img_context, value: @img_context, id: "img_context" %>
                <!-- placeholder for uploaded image -->
                <img
                        id="uploadedimage"
                        src="<%= @image_thumb_url %>">
                </img>
                <button
                        id="upload_widget"
                        class="cloudinary-button" type="button">
                    Upload New Image
                </button>

                </form>
            </div>
            <% end %>
        </div>

    <div id="users">
        <h3>
            Online User
        </h3>
        <%= for user <- @user_list do%>
            <p><%= user %></p>
        <% end %>
    </div>
    </div>


</section>

Thanks in advance

Where Next?

Popular in Questions Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
gonzofish
I’m currently trying to understand how to join three tables using Ecto. All the examples I’ve seen use 2, so maybe I’m just missing somet...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

Other popular topics Top

yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

We're in Beta

About us Mission Statement