Use live_toast instead of built-in flash
Precursor for building better notifications
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
@source "../js";
|
||||
@source "../../lib/music_library_web";
|
||||
@source "../../deps/fluxon/**/*.*ex";
|
||||
@source "../../deps/live_toast/lib/**/*.*ex";
|
||||
|
||||
/* A Tailwind plugin that makes "hero-#{ICON}" classes available.
|
||||
The heroicons installation itself is managed by your mix.exs */
|
||||
|
||||
@@ -24,9 +24,11 @@ import topbar from "../vendor/topbar";
|
||||
import { Hooks as FluxonHooks, DOM as FluxonDOM } from "fluxon";
|
||||
import BarcodeScannerHook from "./barcode-scanner";
|
||||
import confetti from "canvas-confetti";
|
||||
import { createLiveToastHook } from "live_toast";
|
||||
|
||||
let Hooks = FluxonHooks;
|
||||
Hooks.BarcodeScanner = BarcodeScannerHook;
|
||||
Hooks.LiveToast = createLiveToastHook();
|
||||
|
||||
let csrfToken = document
|
||||
.querySelector("meta[name='csrf-token']")
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"barcode-detector": "^3.0.0",
|
||||
"canvas-confetti": "^1.9.3"
|
||||
"canvas-confetti": "^1.9.3",
|
||||
"live_toast": "file:../deps/live_toast"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,90 +34,6 @@ defmodule MusicLibraryWeb.CoreComponents do
|
||||
defdelegate separator(assigns), to: Fluxon.Components.Separator
|
||||
defdelegate sheet(assigns), to: Fluxon.Components.Sheet
|
||||
|
||||
@doc """
|
||||
Renders flash notices.
|
||||
|
||||
## Examples
|
||||
|
||||
<.flash kind={:info} flash={@flash} />
|
||||
<.flash kind={:info} phx-mounted={show("#flash")}>Welcome Back!</.flash>
|
||||
"""
|
||||
attr :id, :string, doc: "the optional id of flash container"
|
||||
attr :flash, :map, default: %{}, doc: "the map of flash messages to display"
|
||||
attr :title, :string, default: nil
|
||||
attr :kind, :atom, values: [:info, :warning, :error], doc: "used for styling and flash lookup"
|
||||
attr :rest, :global, doc: "the arbitrary HTML attributes to add to the flash container"
|
||||
|
||||
slot :inner_block, doc: "the optional inner block that renders the flash message"
|
||||
|
||||
def flash(assigns) do
|
||||
assigns = assign_new(assigns, :id, fn -> "flash-#{assigns.kind}" end)
|
||||
|
||||
~H"""
|
||||
<div
|
||||
:if={msg = render_slot(@inner_block) || Phoenix.Flash.get(@flash, @kind)}
|
||||
id={@id}
|
||||
phx-click={JS.push("lv:clear-flash", value: %{key: @kind}) |> hide("##{@id}")}
|
||||
role="alert"
|
||||
class={[
|
||||
"fixed top-2 right-2 mr-2 w-80 sm:w-96 z-50 rounded-md shadow-md p-3 ring-1 ring-zinc-400 border-l-2",
|
||||
@kind == :info &&
|
||||
"border-l-emerald-500 bg-white dark:bg-zinc-700 text-emerald-700 dark:text-emerald-300",
|
||||
@kind == :warning &&
|
||||
"border-l-yellow-500 bg-white dark:bg-zinc-700 text-yellow-900 dark:text-yellow-300",
|
||||
@kind == :error &&
|
||||
"border-l-red-500 bg-white dark:bg-zinc-700 text-red-900 dark:text-red-300"
|
||||
]}
|
||||
{@rest}
|
||||
>
|
||||
<p :if={@title} class="flex items-center gap-1.5 text-sm font-semibold leading-6">
|
||||
<.icon :if={@kind == :info} name="hero-information-circle-mini" class="h-4 w-4" />
|
||||
<.icon :if={@kind == :warning} name="hero-exclamation-circle-mini" class="h-4 w-4" />
|
||||
<.icon :if={@kind == :error} name="hero-exclamation-circle-mini" class="h-4 w-4" />
|
||||
{@title}
|
||||
</p>
|
||||
<p class="mt-2 text-sm leading-5 text-zinc-700 dark:text-zinc-300">{msg}</p>
|
||||
<button type="button" class="group absolute top-1 right-1 p-2" aria-label={gettext("close")}>
|
||||
<.icon
|
||||
name="hero-x-mark-solid"
|
||||
class="text-zinc-700 dark:text-zinc-100 h-5 w-5 opacity-40 group-hover:opacity-70"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
@doc """
|
||||
Shows the flash group with standard titles and content.
|
||||
|
||||
## Examples
|
||||
|
||||
<.flash_group flash={@flash} />
|
||||
"""
|
||||
attr :flash, :map, required: true, doc: "the map of flash messages"
|
||||
attr :id, :string, default: "flash-group", doc: "the optional id of flash container"
|
||||
|
||||
def flash_group(assigns) do
|
||||
~H"""
|
||||
<div id={@id}>
|
||||
<.flash kind={:info} title={gettext("Success!")} flash={@flash} />
|
||||
<.flash kind={:warning} title={gettext("Warning!")} flash={@flash} />
|
||||
<.flash kind={:error} title={gettext("Error!")} flash={@flash} />
|
||||
<.flash
|
||||
id="server-error"
|
||||
kind={:error}
|
||||
title={gettext("Something went wrong!")}
|
||||
phx-disconnected={show(".phx-server-error #server-error")}
|
||||
phx-connected={hide("#server-error")}
|
||||
hidden
|
||||
>
|
||||
{gettext("Hang in there while we get back on track")}
|
||||
<.icon name="hero-arrow-path" class="ml-1 h-3 w-3 animate-spin" />
|
||||
</.flash>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
@doc """
|
||||
Renders a simple form.
|
||||
|
||||
|
||||
@@ -90,7 +90,12 @@
|
||||
</nav>
|
||||
<main class="px-4 py-4 max-sm:pb-20 sm:px-6 lg:px-8">
|
||||
<div class="mx-auto max-w-screen-xl">
|
||||
<.flash_group flash={@flash} />
|
||||
<LiveToast.toast_group
|
||||
flash={@flash}
|
||||
corner={:top_right}
|
||||
connected={assigns[:socket] != nil}
|
||||
toasts_sync={assigns[:toasts_sync]}
|
||||
/>
|
||||
{@inner_content}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<main class="px-4 py-8 max-sm:pb-20 sm:px-6 lg:px-8">
|
||||
<div class="mx-auto max-w-5xl">
|
||||
<.flash_group flash={@flash} />
|
||||
<LiveToast.toast_group
|
||||
flash={@flash}
|
||||
corner={:top_right}
|
||||
connected={assigns[:socket] != nil}
|
||||
toasts_sync={assigns[:toasts_sync]}
|
||||
/>
|
||||
{@inner_content}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -65,6 +65,7 @@ defmodule MusicLibrary.MixProject do
|
||||
depth: 1},
|
||||
{:fluxon, "~> 1.1.0", repo: :fluxon},
|
||||
{:flagmojis, "~> 1.0"},
|
||||
{:live_toast, "~> 0.8.0"},
|
||||
|
||||
# Dev tooling
|
||||
{:phoenix_live_reload, "~> 1.2", only: :dev},
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"},
|
||||
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
|
||||
"live_debugger": {:hex, :live_debugger, "0.2.4", "2e0b02874ca562ba2d8cebb9e024c25c0ae9c1f4ee499135a70814e1dea6183e", [:mix], [{:igniter, ">= 0.5.40 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:phoenix_live_view, "~> 0.20.4 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "bfd0db143be54ccf2872f15bfd2209fbec1083d0b06b81b4cedeecb2fa9ac208"},
|
||||
"live_toast": {:hex, :live_toast, "0.8.0", "d7e24801a9a966d8e48872767ac33c50fc14640ac5272128becfc534fabd99b7", [:mix], [{:ecto, ">= 3.11.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:gettext, ">= 0.26.2", [hex: :gettext, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.7.19", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_live_view, ">= 1.0.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "7e64435131b7731698908d59f7ba9f5092df8a3720814f26edf57e99d97a803c"},
|
||||
"mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"},
|
||||
"mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"},
|
||||
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
|
||||
|
||||
@@ -52,11 +52,6 @@ msgstr ""
|
||||
msgid "Error importing record"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/core_components.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Error!"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/form_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Format"
|
||||
@@ -73,11 +68,6 @@ msgstr ""
|
||||
msgid "Genres"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/core_components.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Hang in there while we get back on track"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/live/collection_live/show.html.heex
|
||||
#: lib/music_library_web/live/wishlist_live/show.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
@@ -186,22 +176,12 @@ msgstr ""
|
||||
msgid "Show"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/core_components.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Something went wrong!"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/layouts/app.html.heex
|
||||
#: lib/music_library_web/live/stats_live/index.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Stats"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/core_components.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Success!"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/hooks/static_assets.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "The application has been updated, please reload."
|
||||
@@ -256,11 +236,6 @@ msgstr ""
|
||||
msgid "You must be logged in to access this page"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/core_components.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "close"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/live/artist_live/show.html.heex
|
||||
#: lib/music_library_web/live/collection_live/show.html.heex
|
||||
#: lib/music_library_web/live/wishlist_live/show.html.heex
|
||||
@@ -805,11 +780,6 @@ msgstr ""
|
||||
msgid "Scrobble disc"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/core_components.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Warning!"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/layouts/app.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "More"
|
||||
|
||||
@@ -52,11 +52,6 @@ msgstr ""
|
||||
msgid "Error importing record"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/core_components.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Error!"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/form_component.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Format"
|
||||
@@ -73,11 +68,6 @@ msgstr ""
|
||||
msgid "Genres"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/core_components.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Hang in there while we get back on track"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/live/collection_live/show.html.heex
|
||||
#: lib/music_library_web/live/wishlist_live/show.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
@@ -186,22 +176,12 @@ msgstr ""
|
||||
msgid "Show"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/core_components.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Something went wrong!"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/layouts/app.html.heex
|
||||
#: lib/music_library_web/live/stats_live/index.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Stats"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/core_components.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Success!"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/hooks/static_assets.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "The application has been updated, please reload."
|
||||
@@ -256,11 +236,6 @@ msgstr ""
|
||||
msgid "You must be logged in to access this page"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/core_components.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "close"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/live/artist_live/show.html.heex
|
||||
#: lib/music_library_web/live/collection_live/show.html.heex
|
||||
#: lib/music_library_web/live/wishlist_live/show.html.heex
|
||||
@@ -805,11 +780,6 @@ msgstr ""
|
||||
msgid "Scrobble disc"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/core_components.ex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Warning!"
|
||||
msgstr ""
|
||||
|
||||
#: lib/music_library_web/components/layouts/app.html.heex
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "More"
|
||||
|
||||
Reference in New Issue
Block a user