diff --git a/lib/lsg_web/components/component.ex b/lib/lsg_web/components/component.ex index 37d75e3..d504129 100644 --- a/lib/lsg_web/components/component.ex +++ b/lib/lsg_web/components/component.ex @@ -1,40 +1,44 @@ defmodule LSGWeb.Component do use Phoenix.Component @date_time_default_format "%F %H:%M" @date_time_formats %{"time-24-with-seconds" => "%H:%M:%S"} + def naive_date_time_utc(assigns = %{at: nil}) do + "" + end + def naive_date_time_utc(assigns = %{format: format}) do assigns = assign(assigns, :format, Map.get(@date_time_formats, format, format)) ~H""" """ end def naive_date_time_utc(assigns) do naive_date_time_utc(assign(assigns, :format, "%F %H:%M")) end def get_luxon_format("%H:%M:%S"), do: "TIME_24_WITH_SECONDS" def nick(assigns = %{self: false}) do ~H""" <%= @nick %> """ end def nick(assigns = %{self: true}) do ~H""" You """ end end diff --git a/lib/lsg_web/components/event_component.ex b/lib/lsg_web/components/event_component.ex index 3b9cd3b..fa81d19 100644 --- a/lib/lsg_web/components/event_component.ex +++ b/lib/lsg_web/components/event_component.ex @@ -1,36 +1,43 @@ defmodule LSGWeb.EventComponent do use Phoenix.Component + def content(assigns = %{event: %{type: :day_changed}}) do + ~H""" + Day changed: + <%= Date.to_string(@date) %> + """ + end + def content(assigns = %{event: %{type: :quit}}) do ~H""" has quit: <%= @reason %> """ end def content(assigns = %{event: %{type: :part}}) do ~H""" has left: <%= @reason %> """ end def content(assigns = %{event: %{type: :nick}}) do ~H""" <%= @old_nick %> is now known as """ end def content(assigns = %{event: %{type: :join}}) do ~H""" joined """ end end diff --git a/lib/lsg_web/components/message_component.ex b/lib/lsg_web/components/message_component.ex index 2381411..5997754 100644 --- a/lib/lsg_web/components/message_component.ex +++ b/lib/lsg_web/components/message_component.ex @@ -1,10 +1,12 @@ defmodule LSGWeb.MessageComponent do use Phoenix.Component def content(assigns) do ~H""" + +
<%= @message.sender.nick %>
<%= @text %>
""" end end diff --git a/lib/lsg_web/live/chat_live.ex b/lib/lsg_web/live/chat_live.ex index e7a44db..e84d880 100644 --- a/lib/lsg_web/live/chat_live.ex +++ b/lib/lsg_web/live/chat_live.ex @@ -1,100 +1,120 @@ defmodule LSGWeb.ChatLive do use Phoenix.LiveView use Phoenix.HTML require Logger def mount(%{"network" => network, "chan" => chan}, %{"account" => account_id}, socket) do chan = LSGWeb.reformat_chan(chan) connection = IRC.Connection.get_network(network, chan) account = IRC.Account.get(account_id) membership = IRC.Membership.of_account(IRC.Account.get("DRgpD4fLf8PDJMLp8Dtb")) if account && connection && Enum.member?(membership, {connection.network, chan}) do {:ok, _} = Registry.register(IRC.PubSub, "#{connection.network}:events", plugin: __MODULE__) for t <- ["messages", "triggers", "outputs", "events"] do {:ok, _} = Registry.register(IRC.PubSub, "#{connection.network}/#{chan}:#{t}", plugin: __MODULE__) end IRC.PuppetConnection.start(account, connection) users = IRC.UserTrack.channel(connection.network, chan) |> Enum.map(fn(tuple) -> IRC.UserTrack.User.from_tuple(tuple) end) |> Enum.reduce(Map.new, fn(user = %{id: id}, acc) -> Map.put(acc, id, user) end) backlog = case LSG.IRC.BufferPlugin.select_buffer(connection.network, chan) do - {backlog, _} -> Enum.reverse(backlog) + {backlog, _} -> + {backlog, _} = Enum.reduce(backlog, {backlog, nil}, &reduce_contextual_event/2) + Enum.reverse(backlog) _ -> [] end socket = socket |> assign(:connection_id, connection.id) |> assign(:network, connection.network) |> assign(:chan, chan) |> assign(:title, "live") |> assign(:channel, chan) |> assign(:account_id, account.id) |> assign(:backlog, backlog) |> assign(:users, users) |> assign(:counter, 0) {:ok, socket} else {:ok, redirect(socket, to: "/")} end end def handle_event("send", %{"message" => %{"text" => text}}, socket) do account = IRC.Account.get(socket.assigns.account_id) IRC.send_message_as(account, socket.assigns.network, socket.assigns.channel, text, true) {:noreply, assign(socket, :counter, socket.assigns.counter + 1)} end def handle_info({:irc, :event, event = %{type: :join, user_id: id}}, socket) do if user = IRC.UserTrack.lookup(id) do socket = socket |> assign(:users, Map.put(socket.assigns.users, id, user)) - |> assign(:backlog, socket.assigns.backlog ++ [event]) + |> append_to_backlog(event) {:noreply, socket} else {:noreply, socket} end end def handle_info({:irc, :event, event = %{type: :nick, user_id: id, nick: nick}}, socket) do socket = socket |> assign(:users, update_in(socket.assigns.users, [id, :nick], nick)) - |> assign(:backlog, socket.assigns.backlog ++ [event]) + |> append_to_backlog(event) {:noreply, socket} end def handle_info({:irc, :event, event = %{type: :quit, user_id: id}}, socket) do socket = socket |> assign(:users, Map.delete(socket.assigns.users, id)) - |> assign(:backlog, socket.assigns.backlog ++ [event]) + |> append_to_backlog(event) {:noreply, socket} end def handle_info({:irc, :event, event = %{type: :part, user_id: id}}, socket) do socket = socket |> assign(:users, Map.delete(socket.assigns.users, id)) - |> assign(:backlog, socket.assigns.backlog ++ [event]) + |> append_to_backlog(event) {:noreply, socket} end def handle_info({:irc, :trigger, _, message}, socket) do handle_info({:irc, nil, message}, socket) end def handle_info({:irc, :text, message}, socket) do + IO.inspect({:live_message, message}) socket = socket - |> assign(:backlog, socket.assigns.backlog ++ [message]) + |> append_to_backlog(message) {:noreply, socket} end def handle_info(info, socket) do Logger.debug("Unhandled info: #{inspect info}") {:noreply, socket} end + defp append_to_backlog(socket, line) do + {add, _} = reduce_contextual_event(line, {[], List.last(socket.assigns.backlog)}) + assign(socket, :backlog, socket.assigns.backlog ++ add) + end + + defp reduce_contextual_event(line, {acc, nil}) do + {[line | acc], line} + end + defp reduce_contextual_event(line, {acc, last}) do + if NaiveDateTime.to_date(last.at) != NaiveDateTime.to_date(line.at) do + {[%{type: :day_changed, date: NaiveDateTime.to_date(line.at), at: nil}, line | acc], line} + else + {[line | acc], line} + end + + end + end diff --git a/lib/lsg_web/live/chat_live.html.heex b/lib/lsg_web/live/chat_live.html.heex index 717be4f..fc1f582 100644 --- a/lib/lsg_web/live/chat_live.html.heex +++ b/lib/lsg_web/live/chat_live.html.heex @@ -1,94 +1,91 @@

<%= @network %> <%= @chan %>

Disconnected :'(

Oh no error >:(

    <%= for message <- @backlog do %> <%= if is_map(message) && Map.get(message, :__struct__) == IRC.Message do %>
  • - - <%= message.sender.nick %> - - -
  • <% end %> <%= if is_binary(message) do %>
  • <%= message %>
  • <% end %> <%= if is_map(message) && Map.get(message, :type) do %>
  • * * *
  • <% end %> <% end %>
<.form let={f} id={"form-#{@counter}"} for={:message} phx-submit="send" class="w-full px-4 pt-4">
<%= text_input f, :text, class: "focus:ring-indigo-500 focus:border-indigo-500 block w-full border rounded-md pl-4 sm:text-sm border-gray-300", autofocus: true, 'phx-hook': "AutoFocus", autocomplete: "off", placeholder: "Don't be shy, say something…" %> <%= submit content_tag(:span, "Send"), class: "-ml-px relative inline-flex items-center space-x-2 px-4 py-2 border border-gray-300 text-sm font-medium rounded-r-md text-gray-700 bg-gray-50 hover:bg-gray-100 focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500"%>