A lib enabling dynamic favicons in Phoenix Live View applications.
To show…
…a message counter
…the result of a CI/CD job
…a summary of all monitor statuses
…a spinner while uploading a file
Using a dynamic favicon allows users to view a status without having the page in front.
Basic Operations
set or remove any attribute
add a class name or remove a class name
toggle a class
Special Operations
In addition to these basic operations this library includes some special operations to help with common use cases.
Reset a favicon to its initial value
The initial attribute values of favicons are preserved on the first load of the website and can be restored using reset/0. This is in particular useful to erase all previous changes when a user visits a new page by including reset/0 in the on_mount hook.
Set the value of a placeholder (mimicking Phoenix’s assign)
Common use cases are:
Changing the path of favicons when multiple sizes are defined
Changing a dynamic value within an SVG favicon
Create and restore snapshots
By creating a snapshot of the favicon after multiple operations, you can restore the favicons’ attributes by only sending the snapshots’ name over the wire.
See the Guides page for common use cases. The Example App demonstrates various use cases and includes a ‘debug frame’ which shows the HTML of favicon head elements in real time.
To start this example:
Run git clone https://github.com/BartOtten/phoenix_live_favicon_example
Go inside the folder with cd phoenix_live_favicon_example
v0.1.1
Yes, this is a bugfix release with a breaking change. I doubt remove_attr/3 was used (as nobody reported an issue)
- Breaking: `remove_attr/3` has been replaced by `remove_attr/2`
- Require Phoenix Live Head ~> 0.1.2
By using Phoenix Live Head 0.1.2 we can now safely use reset/1 (and reset_attr/2) in the on_mount hook to set the favicons to their default when navigating to another page. Thanks to @dfalling for leading me to the use case and subsequently the issue.
alias Phx.Live.Favicon
def on_mount(:default, _params, _session, socket) do
{:cont, Favicon.reset(socket)}
end
Now the order of events is preserved, the reset/1 and reset_attr/2 add an event to set the favicons to their initial values, but will dismiss any favicon events (for given attr in case of reset_attr/2) set before.
socket =
socket
| > Favicon.set_class("green") <-- this event will never be send
[...]
socket =
socket
|> Favicon.reset()
|> Favicon.set_attr("href", "/images/fav/fav.png")
I knew it could be done, but did not build it yet: a message counter using SVG! Now I have a working version in the Example App (not published yet). Let’s say it’s better not to mix PNG and SVG favicons as browsers are not fond of switching from one type to another.
Will do as soon as I find out how I can do it for free I already use one instance for Phoenix Localized Routes
While creating the message counter example, I found some inconveniences in using the lib and needing to mix in ‘raw’ Live Head. So……
version 0.2.0-rc.0
A new version has been released as RC on Hex; it powers the updated example page which hopefully will be online soon, so you can all come up with fancier gifs of ‘animated’ favicons!
The new operations snap and restore make it possible to store the result of many operations under a chosen name and restore it at a later time by only sending the snapshot name over the wire.
snap - Takes a snapshot of all attribute values.
restore - Applies a snapshot to selected elements
In the Live Favicon Example application it is used to send all changes required to switch between an dynamic SVG counter and static PNG message-icon once, and toggle the state between them; creating a flashing notification. As it also makes a snapshot of the state before the favicon begins to flash, the icon on the page can be restored to it’s value as soon as the user had read the unread messages.
Use multiple placeholders
You can now use multiple custom named placeholders, instead of only one {dynamic} per attribute.
Fixes
Unstable order of change execution when using multiple queries / libs.
BREAKING
the attribute value of dynamic is now used as name for the target placeholder. As a result, it is not possible anymore to target a specific attribute. Migration is as easy as using different names per attribute when necessary.
TESTERS NEEDED!
This is quite a major release as a lot of logic was rewritten in the underlying lib. However, for most there won’t be breaking changes so the upgrade should be safe.
Please upgrade to the RC version and let me know if you experience any issues (or better: how many issues it solves!)
{:phoenix_live_favicon, "~> 0.2.0-rc.0"}
See also: the diff of Example App and especially how it uses the new snapshots and custom dynamic placeholders.
Changes
No fundamental changes to rc.0 so the post above is accurate. The example app has been updated to use the new 0.2.0.
Better documentation
The README has seen some work too and a few GUIDES were added.
Migration guide
As this is a breaking release due set_dynamic being redefined, you should update your mix.exs file to include:
{:phoenix_live_favicon, "~> 0.2.0"}
When using set_dynamic from 0.1.x you can rewrite them to set_dynamic("dynamic", value). Notice it targets a specific placeholder instead of an attribute. When you used multiple {dynamics} on different attributes, you should rename every dynamic placeholder to be unique. See the docs of set_dynamic/3