1import { Controller } from "@hotwired/stimulus" 2 3// The used-offers table on the edition page, folded behind its summary bar. 4// Both tables are server-rendered, so opening one costs no request. 5// 6// Whether it's open is remembered â someone shopping second-hand is shopping 7// second-hand for the whole session â and re-applied after a morph. That last 8// part is the reason this isn't a <details>: prices stream in live on this 9// page, and every refresh re-renders the panel with the server's default 10// (closed), which would snap it shut mid-read. 11const STORAGE_KEY = "tbdb:used-prices" 12 13export default class extends Controller { 14 static targets = ["panel", "label"] 15 16 connect() { 17 this.reapply = () => this.show(this.remembered) 18 document.addEventListener("turbo:morph", this.reapply) 19 this.show(this.remembered) 20 } 21 22 disconnect() { 23 document.removeEventListener("turbo:morph", this.reapply) 24 } 25 26 toggle() { 27 if (!this.hasPanelTarget) return 28 29 const open = this.panelTarget.hidden 30 this.show(open) 31 32 try { 33 localStorage.setItem(STORAGE_KEY, String(open)) 34 } catch { 35 // Private mode / storage disabled â the toggle still works, it just 36 // won't be remembered. 37 } 38 } 39 40 show(open) { 41 if (!this.hasPanelTarget) return 42 43 this.panelTarget.hidden = !open 44 if (this.hasLabelTarget) { 45 this.labelTarget.textContent = open ? "Hide used prices" : "Show used prices" 46 } 47 } 48 49 get remembered() { 50 try { 51 return localStorage.getItem(STORAGE_KEY) === "true" 52 } catch { 53 return false 54 } 55 } 56}
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.