BartOtten

BartOtten

Phoenix Live Favicon - Favicon manipulation for Phoenix Live

Phoenix Live Favicon

Favicon manipulation for Phoenix Live


Example

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.

Documentation

Visit the documentation of Phx.Live.Favicon module for the full list of operations.

Guides and Example

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.

Example App Preview

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
  • Install dependencies with mix deps.get
  • Start Phoenix endpoint with mix phx.server or inside IEx with iex -S mix phx.server

Links

Hex
Hexdocs
Github
Changelog
Search forum for tag

Most Liked

BartOtten

BartOtten

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.

Phoenix Live Favicon - Message Counter

BartOtten

BartOtten

Will do as soon as I find out how I can do it for free :wink: 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!

Features

Create and restore snapshots

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.

BartOtten

BartOtten

Release 0.2.0 (changelog)

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

BartOtten

BartOtten

Release 1.0

The lib version has been bumped to 1.0.0 in order to reflect stability. Please update your dep in mix.exs.

{:phoenix_live_favicon, "~> 1.0"}

outlog

outlog

looks great! - what does the browser support like nowadays?

Where Next?

Popular in Announcing Top

kip
ex_cldr provides localisation and internationalisation support based upon the data from the Unicode CLDR project. Unicode released CLDR ...
395 12072 119
New
zachdaniel
:smiling_face_with_sunglasses: New package usage_rules released! Just place a usage-rules.md file in your package and users can sync it t...
#ai
New
mikehostetler
I’m falling in love with the Req Plugin pattern. It has limits, but when it works - it’s good. I ported over my Tesla based Fly Machines...
New
rodloboz
I’ve started working on a new library to run SQL queries and do basic business intelligence. Think “Blazer for Elixir.” Currently it fe...
New
mikehostetler
LLM DB - LLM Model Metadata Package This package was extracted out of the ReqLLM project. LLM DB is a model metadata catalog with fast, ...
New
garrison
Hobbes is a scalable, fault-tolerant transactional record store written in Elixir. Hobbes is designed to be: Scalable - Hobbes can sha...
New
brainlid
LangChain is short for Language Chain. An LLM, or Large Language Model, is the “Language” part. This library makes it easier for Elixir a...
New
fuelen
Hey folks! Want to present a toolkit for writing command-line user interfaces. It provides a convenient interface for colorizing text...
New
sodapopcan
I’ve heard that if you’re not embarrassed by v1 of your product Vim plugin then you’ve released too late. I’ve been sitting on this the ...
New
rodloboz
Sifter is a a query filtering library for Ecto. It lets frontend apps send human-readable query strings like: "elixir phoenix status:pu...
New

Other popular topics Top

jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement