From 2d83df8b32bff7f0028923bb5b64dc0b55f20d03 Mon Sep 17 00:00:00 2001 From: Jordan Bracco Date: Tue, 20 Dec 2022 00:21:54 +0000 Subject: Nola rename: The Big Move, Refs T77 --- lib/nola_web/live/chat_live.ex | 120 ++++++++++++++++++++++++++++++++++ lib/nola_web/live/chat_live.html.heex | 91 ++++++++++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 lib/nola_web/live/chat_live.ex create mode 100644 lib/nola_web/live/chat_live.html.heex (limited to 'lib/nola_web/live') diff --git a/lib/nola_web/live/chat_live.ex b/lib/nola_web/live/chat_live.ex new file mode 100644 index 0000000..276b362 --- /dev/null +++ b/lib/nola_web/live/chat_live.ex @@ -0,0 +1,120 @@ +defmodule NolaWeb.ChatLive do + use Phoenix.LiveView + use Phoenix.HTML + require Logger + + def mount(%{"network" => network, "chan" => chan}, %{"account" => account_id}, socket) do + chan = NolaWeb.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 Nola.IRC.BufferPlugin.select_buffer(connection.network, chan) do + {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)) + |> 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)) + |> 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)) + |> 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)) + |> 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 + |> 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/nola_web/live/chat_live.html.heex b/lib/nola_web/live/chat_live.html.heex new file mode 100644 index 0000000..29cd6a1 --- /dev/null +++ b/lib/nola_web/live/chat_live.html.heex @@ -0,0 +1,91 @@ +
+ +
+
+

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

+ +
+
+ +
+ +
+

+ Disconnected :'( +

+

+ Oh no error >:( +

+ +
    + <%= for message <- @backlog do %> + <%= if is_map(message) && Map.get(message, :__struct__) == IRC.Message do %> +
  • + +
  • + <% 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"%> +
+
+ +
-- cgit v1.2.3