defmodule PlausibleWeb.Live.Flash do @moduledoc """ Flash component for LiveViews - works also when embedded within dead views """ use Phoenix.Component alias Phoenix.LiveView.JS alias Phoenix.Flash @flash_timer_assigns %{ success: :clear_flash_success, error: :clear_flash_error } @flash_timer_timeout_ms 5000 defmacro __using__(_opts) do quote do import PlausibleWeb.Live.Flash, only: [put_live_flash: 3, flash_messages: 1] def handle_info({:clear_live_flash, key}, socket) do {:noreply, Phoenix.LiveView.clear_flash(socket, key)} end end end def put_live_flash(socket, key, message) when key in [:success, :error] do timer_key = Map.fetch!(@flash_timer_assigns, key) if flash_timer = socket.assigns[timer_key] do Process.cancel_timer(flash_timer) end flash_timer = Process.send_after( self(), {:clear_live_flash, key}, @flash_timer_timeout_ms ) socket |> Phoenix.LiveView.put_flash(key, message) |> assign(timer_key, flash_timer) end def flash_messages(assigns) do ~H"""
<.flash :if={Flash.get(@flash, :success)} key="success"> <:icon> <.icon_success /> <:title> <%= Flash.get(@flash, :success_title) || "Success!" %> <:message> <%= Flash.get(@flash, :success) %> <.flash :if={Flash.get(@flash, :error)} key="error"> <:icon> <.icon_error /> <:title> <%= Flash.get(@flash, :error_title) || "Error!" %> <:message> <%= Flash.get(@flash, :error) %> <.flash :if={Application.get_env(:plausible, :environment) == "dev"} id="live-view-connection-status" class="hidden" phx-disconnected={JS.show()} phx-connected={JS.hide()} on_close={JS.hide()} > <:icon> <.icon_error /> <:title> Oops, a server blip <:message> Live socket disconnected.
""" end slot(:icon, required: true) slot(:title, require: true) slot(:message, required: true) attr(:key, :string, default: nil) attr(:on_close, :any, default: "lv:clear-flash") attr(:class, :string, default: "") attr(:rest, :global) def flash(assigns) do ~H"""
<%= render_slot(@icon) %>

<%= render_slot(@title) %>

<%= render_slot(@message) %>

<.clear_flash_button on_close={@on_close} key={@key} />
""" end def icon_success(assigns) do ~H"""
""" end def icon_error(assigns) do ~H""" """ end def clear_flash_button(assigns) do ~H""" """ end end