PageSourceSearch

https://loafy.ai/assets/controllers/journey_variant_controller-204502a4.js

js loafy.ai collected 2026-10-05 12:52:59 UTC 2,190 bytes, 72 lines download raw bytes

1import { Controller } from "@hotwired/stimulus"
2
3// Journey Variant Controller
4// One choice for a journey that has more than one way through it, e.g. the
5// flour of the sandwich bread: wheat and spelt bake one way, rye, einkorn,
6// emmer and gluten-free flours another. Every step renders all of its
7// versions; this shows the chosen one and hides the rest.
8//
9// The choice lives in the URL as ?variant= (a shared link opens on the same
10// flour) and in localStorage per journey (a baker who picked rye yesterday
11// still has rye today). The URL wins over the stored choice.
12export default class extends Controller {
13  static targets = ["option"]
14
15  static values = {
16    journeySlug: String,
17    current: String
18  }
19
20  connect() {
21    this.storageKey = `loafy_journey_${this.journeySlugValue}_variant`
22    const requested = new URL(window.location).searchParams.get("variant")
23    const chosen = [requested, this.stored()].find(id => this.isOption(id))
24    if (chosen) this.apply(chosen)
25  }
26
27  select(event) {
28    event.preventDefault()
29    this.apply(event.currentTarget.dataset.variantId)
30  }
31
32  apply(id) {
33    if (!this.isOption(id)) return
34
35    this.currentValue = id
36    this.optionTargets.forEach(option => {
37      option.setAttribute("aria-pressed", String(option.dataset.variantId === id))
38    })
39    this.element.querySelectorAll("[data-journey-variant]").forEach(version => {
40      version.hidden = version.dataset.journeyVariant !== id
41    })
42
43    this.store(id)
44    const url = new URL(window.location)
45    if (url.searchParams.get("variant") !== id) {
46      url.searchParams.set("variant", id)
47      window.history.replaceState(window.history.state, "", url)
48    }
49  }
50
51  isOption(id) {
52    return Boolean(id) && this.optionTargets.some(option => option.dataset.variantId === id)
53  }
54
55  // Storage can be missing or throw (private mode, blocked site data); the
56  // switch then simply forgets, and the page stays right.
57  stored() {
58    try {
59      return localStorage.getItem(this.storageKey)
60    } catch {
61      return null
62    }
63  }
64
65  store(id) {
66    try {
67      localStorage.setItem(this.storageKey, id)
68    } catch {
69      // nothing to remember it in
70    }
71  }
72}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.