Complete search shows this.
If you want to hook up zemer curated playlists endpoint:
Not too much, already built out - I just may have to require login for use
zemer-playlists needs the file data/zemer-playlists.json plus a small harvester step to build its tables from the corpus — none of which is in the release DB. That’s a separate build step.
@ars18
Are you going to be adding it too the database yourself or its staying a separate file?
Staying separate for now, just use API it’s fast
I will just make it that at build it fetches the API and builds a table for it in the database
When will this be deployed? I do not see this change.
Later today
Stay Tuned for...
accounts/ui: login+PIN redesign, parental hardening, usage tracking
Login: redesigned modal — logo badge, Sign in/Sign up segmented toggle, icon
inputs, password reveal, gradient button, success state. PIN set/change/remove
now uses an in-app modal (was browser prompt()/confirm()).
Parental enforcement — fixes several bypasses where the gate ran BEFORE the
artist-flag map / profile loaded, so it silently no-op’d (blocked content
played):
- ensureFilters() loads the artist map + profile before gating in openArtist,
openAlbum, openPlaylist, openSong, doSearch, loadLibrary. - openSong now verifies whitelist + filters + parental BEFORE playback starts
(was starting the iframe then failing to stop it); a real PB.stop() clears the
pending autoplay. Non-whitelisted or blocked songs never play. - Parental re-locks on leaving /parental and on reload (pinOK reset + profile
loaded before render); filtersLocked keys off pin_hash. - Per-filter gate: only allow-female needs an account/PIN; Hide Chassidish and
Audio-only are changeable signed-out. - gate() applied to home / kid-zone / for-you / search / playlist / library.
Usage tracking (feeds the recommendation layer): the play event now fires on
END with real listen time + `qualified`, plus `source` (home/artist/album/
playlist/zemer/search/…) and `client`; search-result clicks emit `click` with
their 0-based rank. Client calls ensure_profile() on login.
fix: expose gate fields + server-mode parity + ensure_profile
“Client reads a field the endpoint never returned” bugs (the class where
kid-lock hid the entire catalog):
- /artists now returns isFemale/isChasid/isKidZone (api.mjs + engine.mjs).
parentalHidesArtist reads isKidZone; without it, !undefined === true hid every
artist under a Kid-Zone lock → nothing loaded. - /artists (server mode) now applies allowChasid — it was silently dropped, so
“Hide Chassidish” did nothing on the Node build (worked in static). - /playlist (server mode) now returns `status` (ok/empty/unavailable) to match
the static engine, so the client shows the right empty state.
accounts-fix.sql: ensure_profile() SECURITY DEFINER RPC (the client calls it on
every login) + re-affirmed signup trigger + backfill, so every user gets a
zemer_user row even if accounts.sql’s trigger was never applied.
ui: move account + Parental Controls from sidebar to the top-right
The account chip (Sign in / Sign up, or the signed-in account) and its menu
(Parental Controls + Sign out) now live in the top-right of the top bar instead
of the bottom of the left sidebar. The dropdown opens downward, right-aligned;
the email label hides under 640px so the chip stays compact on phones.
feat: Zemer-curated playlists (baked at build, served same-origin)
The curated /zemer-playlists live on the Zemer index, not our corpus DB
(the maintainer keeps them API-served). We now fetch them ONCE at build time
and bake the list + per-playlist detail + the SVG covers into dist/data, so
the deployed client reads them same-origin — works behind content filters,
no live cross-origin call in the browser.
- scripts/build-static.mjs: fetch /zemer-playlists (list + each detail + cover)
from ZEMER_API (default search.zemer.io), write dist/data/zemer-playlists.json- dist/data/zemer-playlist/.{json,svg}, rewrite thumbnails to the local
SVG. Best-effort: API down → empty list, section collapses.
- dist/data/zemer-playlist/.{json,svg}, rewrite thumbnails to the local
- client/engine.mjs: serve /zemer-playlists (list + ?id) from the baked files.
- server/api.mjs: Node/dev-server equivalent — proxy + cache the live API
(incl. /zemer-playlists/cover); serve the SPA shell for /zemer-playlists/:id
(but not /zemer-playlists/cover). - server/ui.html: a “Zemer Playlists” rail on Home + a section in the Playlists
tab (zpCard), a detail view (openZemerPlaylist: albums + collapsible songs),
and deep-link routing /zemer-playlists/:id. Tracks are content+parental gated.
Verified: build bakes 3 playlists; Node proxy serves list/detail/cover; UI
renders the rail, detail, cover SVG, and collapse end-to-end (no console errors).
ui: collapse long artist track lists; drop the live-YouTube community shelf
Artist pages listed every song (often hundreds) before the albums, so reaching
an album meant scrolling the whole discography. The Songs and Videos sections
now clamp to the top 6 (by play count) with a “Show all N …” toggle that
expands them in place — albums sit right under the fold. One queue is still
built over the full list, so play indices are unaffected; the clamp is
CSS-only (.rows.clamp hides rows past the 6th).
Also remove the “Community · live from YouTube” section from search results
(Complete Search) per request — the whitelisted categories remain.
accounts: database-enforced parental hard lock (PIN-gated settings)
The soft version let an account write its own zemer_user row via RLS, so a kid
signed in could PATCH the REST API and unlock themselves. This gates the
protected columns at the database:
- REVOKE UPDATE on the row, GRANT UPDATE only on recents; REVOKE SELECT on
pin_hash so the hash can’t be pulled and offline-cracked. - All settings changes go through SECURITY DEFINER RPCs (pc_get / pc_verify /
pc_update / pc_set_pin / pc_clear_pin) that verify a bcrypt PIN first, with a
server-side escalating lockout (30s→…→15m). No client bypass.
Client still needs porting from direct PATCH/select=* to these RPCs.
accounts: enforce parental rules on every feed + wrong-PIN backoff
The parental artist allow/blocklist and the kid_only lock were only applied
in search and detail views. Home, Kid Zone, and For You built their rails
straight from the /home payload, so a locked/allowlisted account still saw
blocked artists there — the “feeds aren’t fully gated” gap called out in the
setup doc.
- Add gate(list): filters any feed (songs/albums/playlists by .artist, artist
cards by .name) through the existing hiddenArtist(), which already folds in
parentalHidesArtist(). Apply it to every rail in loadHome, loadKid, and the
For-You taste feed; await artistByName() first so the gate is actually active
(it no-ops until the artist-flags map is loaded). - filterQS() now sends kidZone=1 for kid_only accounts, so their server feeds
come pre-scoped to kid-safe content instead of being gutted client-side. - Escalating, localStorage-persisted lockout after repeated wrong PIN entries
(30s → 60s → … cap 15m) so a 4-digit PIN can’t be brute-forced. Soft, matching
this branch’s client-side enforcement model.
Signed-out behavior is unchanged: with no profile the gate is a no-op.
Accounts + parental controls
Adds to server/ui.html (self-contained, no SDK):
- Supabase email auth: sign up / in / out, session persistence + token refresh, account chip
- auth modal.
- Cross-device sync: on login, merge local likes → zemer_like (get_my_likes/toggle_like),
filter prefs ↔ zemer_user profile. - Parental Controls screen (/parental): PIN gate (SHA-256 hashed), lock toggle, content
filters, artist allow/blocklist picker from the master list, Kid-Zone-only. - Enforcement lever: changing content filters now REQUIRES an account — signed-out devices
stay on the safe defaults (kol isha on); with a PIN set, filters change only in Parental
Controls. Artist allow/block + kid-only applied via hiddenArtist.
Added Accapella mode for the 3 weeks
We need help categorizing music as Israeli or Not Israeli
if anyone wants to help contribute feel free
Guys I had an arguement with @TripleU and @ars18 and they said that there is no point in open sourcing because people don’t help either way and I said that lets try it
Lets prove them wrong - someone please contribute
#ProveTripleUandArs18Wrong
what makes and artist ‘isreali’? is it based where they live? their accent? citizenship? only if all their songs are in hebrew? it’s a very ambiguous label
its weird because i mark a bunch, then check again and they’re unmarked again
My fault
Claude decided to reset it because it though it was its own testing
But I am reverting that
is this list based on the zemer whitelist? who is kim komrad or joni miller?
They are female so not part of your filtered list



