defmodule RanchTalk.SocketMessageDisplayer do use Kino.JS use Kino.JS.Live @spec new() :: Kino.JS.Live.t() def new() do Kino.JS.Live.new(__MODULE__, []) end @impl true def init(messages, ctx) do {:ok, assign(ctx, messages: messages)} end @impl true def handle_info({:form_message, %{data: data}}, ctx) do data = Map.put(data, :date, DateTime.utc_now()) broadcast_event(ctx, "add_message", data) new_messages = [data | ctx.assigns.messages] {:noreply, assign(ctx, messages: new_messages)} end @impl true def handle_cast({:subscribe_to_form, form}, ctx) do subscribe_to_form(form) {:noreply, ctx} end @impl true def handle_connect(ctx) do IO.inspect(ctx) # subscribe_to_form(ctx.assigns.form) {:ok, ctx.assigns, ctx} end defp subscribe_to_form(form) do Kino.Control.subscribe(form, :form_message) end asset "main.js" do """ var cache = [ '', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' ] function leftPad(str, len, ch) { str = str + '' len = len - str.length if (len <= 0) return str if (!ch && ch !== 0) ch = ' ' ch = ch + '' if (ch === ' ' && len < 10) return cache[len] + str var pad = '' while (true) { if (len & 1) pad += ch len >>= 1 if (len) ch += ch else break } return pad + str } function dateStr(date) { console.log("before str", date) const hours = leftPad(date.getHours().toString(), 2, '0') const minutes = leftPad(date.getMinutes().toString(), 2, '0') const seconds = leftPad(date.getSeconds().toString(), 2, '0') return `${hours}:${minutes}:${seconds}` } export function init(ctx, state) { const header = document.createElement("h1") header.textContent = "Received Messages:" ctx.root.appendChild(header) const messages = document.createElement("ul") messages.style.fontFamily = 'IosevkaLyte, monospace' messages.style.fontSize = '16px' ctx.root.appendChild(messages) ctx.handleEvent("add_message", ({name, message, date}) => { console.log("Raw Date", date) const messageDate = new Date(date) console.log("Message Date", messageDate) const messageEl = document.createElement("li") messageEl.textContent = `${dateStr(messageDate)} ${name}: ${message}` messages.appendChild(messageEl) }) } """ end end