All files / Bandstand/src/components/cues useLickView.ts

21.62% Statements 8/37
100% Branches 0/0
0% Functions 0/2
21.62% Lines 8/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54    1x                       1x 1x 1x 1x 1x 1x                     1x                                              
'use client'
 
import {useEffect, useState} from 'react'
 
/**
 * How licks (notation blocks) are shown on this device: as notation, or as
 * tab. Guitar and bass parts start as tab, everything else (horn lines,
 * melodies) as notation. Each kind has one setting for every lick of that
 * kind on the page -- flipping one flips them all -- remembered per device.
 */
export type LickView = 'notation' | 'tab'
/** "part": written for guitar or bass; "line": anything else */
export type LickKind = 'part' | 'line'
 
const KEYS: Record<LickKind, string> = {
  part: 'ms:lick-view:part',
  line: 'ms:lick-view',
}
const DEFAULT: Record<LickKind, LickView> = {part: 'tab', line: 'notation'}
const EVENT = 'ms:lick-view'
 
function read(kind: LickKind): LickView {
  try {
    const v = window.localStorage.getItem(KEYS[kind])
    return v === 'tab' || v === 'notation' ? v : DEFAULT[kind]
  } catch {
    return DEFAULT[kind]
  }
}
 
export function useLickView(kind: LickKind) {
  const [view, setView] = useState<LickView>(DEFAULT[kind])
  useEffect(() => {
    setView(read(kind))
    const sync = () => setView(read(kind))
    window.addEventListener(EVENT, sync)
    window.addEventListener('storage', sync)
    return () => {
      window.removeEventListener(EVENT, sync)
      window.removeEventListener('storage', sync)
    }
  }, [kind])
  const set = (v: LickView) => {
    try {
      window.localStorage.setItem(KEYS[kind], v)
    } catch {
      // private mode: still switches this page
    }
    setView(v)
    window.dispatchEvent(new Event(EVENT))
  }
  return [view, set] as const
}