Skip to content

HTML5 desktop notifications

Okke Tijhuis edited this page Nov 16, 2015 · 1 revision

This example shows how to listen for CSS file changes and show a desktop notification whenever such a change occurs.

Make sure you're using Figwheel 0.5.0+ and a browser that supports the notification API

Project layout

.
├── resources
│   └── public
│       └── css
├── script
├── src
│   ├── dev
│   │   └── sample
│   └── main
│       └── sample

Start script

For more information on the basics of the following script, read Scripting with component.

Note the following:

  • To make Figwheel start a CSS watcher :css-dirs is set.
  • Added src/dev to the source paths. We only want the client script to be executed in the dev build.
  • Our main entry point is set to sample.dev.
(require
 '[figwheel-sidecar.repl-api :as ra]
 '[com.stuartsierra.component :as component])

(def figwheel-config
  {:figwheel-options {:css-dirs ["resources/public/css"]}
   :build-ids ["dev"]
   :all-builds
   [{:id "dev"
     :figwheel true
     :source-paths ["src/main" "src/dev"]
     :compiler {:main "sample.dev"
                :asset-path "out"
                :output-to "resources/public/sample.js"
                :output-dir "resources/public/out"
                :verbose true}}]})

(defrecord Figwheel []
  component/Lifecycle
  (start [config]
    (ra/start-figwheel! config)
    config)
  (stop [config]
    (ra/stop-figwheel!)
    config))

(def system
  (atom
   (component/system-map
    :figwheel (map->Figwheel figwheel-config))))

(defn start []
  (swap! system component/start))

(defn stop []
  (swap! system component/stop))

(defn reload []
  (stop)
  (start))

(defn repl []
  (ra/cljs-repl))

;; Start the components and the repl
(start)
(repl)

Client

The configuration above uses sample.dev as :main, not sample.core. The reason for this being that we need to add some Figwheel specific client code. The clients need a way to listen for the CSS watcher messages. This code should only run inside a dev build. Make sure you require your main application namespace.

The client code adds a new message watcher. It will receive all messages. The CSS watcher uses :css-files-changed messages to signal that a CSS file has changed. This means we need to check if the message name matches :css-files-changed.

The script path is assumed to be src/dev/sample/dev.cljs.

(ns sample.dev
  (:require [figwheel.client :as fig]
            [sample.core]))

(defn create-notification [title msg]
  (js/Notification. title #js {:body msg}))

(defn show-desktop-notification [title msg]
  (if (= js/Notification.permission "granted")
    (create-notification title msg)
    (.requestPermission js/Notification (fn [permission]
                                          (if (= permission "granted")
                                            (create-notification title msg))))))

(fig/add-message-watch
 :css-message-watcher
 (fn [{:keys [msg-name] :as msg}]
   (when (= msg-name :css-files-changed)
     (doseq [file (:files msg)]
       (show-desktop-notification "Figwheel CSS watcher"
                                  (str (:file file) " updated."))))))

Assuming the start script is in script/figwheel.clj you can invoke it as follows:

rlwrap lein run -m clojure.main --init script/figwheel.clj -r

The first time a CSS file is changed you will be asked to allow desktop notifications. Once you allow it a notification will be shown whenever a CSS file changed.