···33## 3.1.0
4455- **Removes usage of the Web Audio API, just uses `<audio>` elements now so that Diffuse can be played in the background on iOS.** _Sadly this also means the equalizer has been removed, but a better volume control has been added instead, one that doesn't move away from the tracks view._
66-- **Added a command palette.**
66+- **Adds a command palette.**
77- Correctly scrobbles repeated tracks with Last.fm
88- Disables single-audio-node mode on Safari & iOS (ie. preloading now works)
99- Fixes Fission integration
1010+- Improves detection of new versions and upgrading in the background (ie. service worker)
1011- Improves launcher design (called Alfred internally)
1112- Improves key bindings
1213- Small UI improvements
+4-8
src/Javascript/Workers/service.js
···66// so it can be used offline.
778899-importScripts("version.js")
1010-1111-129const KEY =
1313- "diffuse-" + self.VERSION
1010+ "diffuse-{{VERSION}}"
141115121616-const exclude =
1313+const EXCLUDE =
1714 [ "_headers"
1815 , "_redirects"
1916 , "CORS"
···252226232724self.addEventListener("activate", event => {
2828- event.waitUntil(self.clients.claim())
2929-3025 // Remove all caches except the one with the currently used `KEY`
3126 caches.keys().then(keys => {
3227 keys.forEach(k => {
···4136 const promise = fetch("tree.json")
4237 .then(response => response.json())
4338 .then(tree => {
4444- const filteredTree = tree.filter(t => !exclude.find(u => u === t))
3939+ const filteredTree = tree.filter(t => !EXCLUDE.find(u => u === t))
4540 const whatToCache = [ href, `${href.replace(/\/+$/, "")}/about/` ].concat(filteredTree)
4641 return caches.open(KEY).then(c => Promise.all(whatToCache.map(x => c.add(x))))
4742 })
4343+ // TODO: Remove?
4844 .then(_ => self.skipWaiting())
49455046 event.waitUntil(promise)
+44-16
src/Javascript/index.js
···2626 location.href = location.href.replace("http://", "https://")
2727 failure("Just a moment, redirecting to HTTPS.")
28282929-// Secure context & Service worker
2929+// Not a secure context
3030} else if (!self.isSecureContext) {
3131 failure(`
3232 This app only works on a <a class="underline" target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#When_is_a_context_considered_secure">secure context</a>, HTTPS & localhost, and modern browsers.
3333 `)
34343535+// Service worker
3536} else if ("serviceWorker" in navigator) {
3636- navigator.serviceWorker.register("service-worker.js").then(
3737- initialise,
3838- err => {
3939- const isFirefox = navigator.userAgent.toLowerCase().includes("firefox")
3737+ window.addEventListener("load", () => {
3838+ navigator.serviceWorker
3939+ .register("service-worker.js")
4040+ .then(initialise)
4141+ .catch(err => {
4242+ const isFirefox = navigator.userAgent.toLowerCase().includes("firefox")
40434141- console.error(err)
4242- return failure(
4343- location.protocol === "https:" || location.hostname === "localhost"
4444- ? "Failed to start the service worker." + (isFirefox ? " Make sure the setting <strong>Delete cookies and site data when Firefox is closed</strong> is off, or Diffuse's domain is added as an exception." : "")
4545- : "Failed to start the service worker, try using HTTPS."
4646- )
4747- }
4848- )
4444+ console.error(err)
4545+ return failure(
4646+ location.protocol === "https:" || location.hostname === "localhost"
4747+ ? "Failed to start the service worker." + (isFirefox ? " Make sure the setting <strong>Delete cookies and site data when Firefox is closed</strong> is off, or Diffuse's domain is added as an exception." : "")
4848+ : "Failed to start the service worker, try using HTTPS."
4949+ )
5050+ })
5151+ })
49525053}
5154···8184 wire.backdrop()
8285 wire.clipboard()
8386 wire.covers()
8787+ wire.serviceWorker(reg)
8488 wire.webnative()
85898690 // Other ports
8791 app.ports.openUrlOnNewPage.subscribe(url => {
8892 window.open(url, "_blank")
8993 })
9090-9191- // Check for service worker updates every hour
9292- setInterval(() => reg.update(), 1 * 1000 * 60 * 60)
9394}
94959596···830831 event.stopPropagation()
831832 }
832833})
834834+835835+836836+837837+// Service worker
838838+// --------------
839839+840840+wire.serviceWorker = async (reg) => {
841841+ if (reg.installing) console.log("🧑✈️ Service worker is installing")
842842+ const initialInstall = reg.installing
843843+844844+ reg.addEventListener("updatefound", () => {
845845+ const newWorker = reg.installing
846846+847847+ // No worker was installed yet, so we'll only want to track the state changes
848848+ if (newWorker !== initialInstall) {
849849+ console.log("🧑✈️ A new version of Diffuse is available")
850850+ }
851851+852852+ newWorker.addEventListener("statechange", (e) => {
853853+ console.log("🧑✈️ Service worker is", e.target.state)
854854+ })
855855+ })
856856+857857+ // Check for service worker updates and every hour after that
858858+ reg.update()
859859+ setInterval(() => reg.update(), 1 * 1000 * 60 * 60)
860860+}
833861834862835863