feat: state sync, Dante's circles, smoke themes, admin mode, generative artwork#5
Open
rmzi wants to merge 18 commits into
Open
feat: state sync, Dante's circles, smoke themes, admin mode, generative artwork#5rmzi wants to merge 18 commits into
rmzi wants to merge 18 commits into
Conversation
- Creates lambda-sync.tf with Lambda function, Function URL, IAM role, and S3 policy scoped to sync/ prefix - Adds sync-lambda origin and /sync/* cache behavior (no-cache, first in order) to CloudFront distribution - Outputs sync_lambda_url for reference after apply Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- events.js: add sync modal (openSyncModal/closeSyncModal/setupSyncModalHandlers), wire stateSyncBtn click handler, auto-pull on load if credentials exist - player.js: call debouncedPush() after saveFavoriteTracks() in toggleFavorite() - tracks.js: call debouncedPush() after each saveHeardTracks() call - pwa.js: isTrackCached() now checks both SW Cache API and state.cachedTracks (IndexedDB) - ui.js: stateSyncBtn always shown (not gated behind secret mode) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- S3 GetObject returns AccessDenied instead of NoSuchKey without ListBucket - Lambda Function URL needs lambda:InvokeFunction permission - CORS set to allow all origins (CloudFront handles restriction) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- CloudFront custom error responses intercept 404/403, returning HTML
instead of JSON. Lambda now returns 200 with {found:false} or {error:...}
- Sync button was hidden until secret mode; now shown on init for all users
- Fixed escaped \! characters in sync.js that broke the obfuscator
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move #state-sync-btn from search header to secondary-controls bar; always visible like share-btn (no hidden class) - Replace sync modal with browser prompt() for username/password; delete openSyncModal, closeSyncModal, setupSyncModalHandlers and all modal HTML/CSS - Sync playHistory and historyIndex in serializeState/mergeState; add savePlayHistory/loadPlayHistory to storage.js and wire them into player.js (on push, prev, fwd navigation) and startPlayer - Clean up elements.js (remove 9 modal element refs), ui.js (remove stateSyncBtn show logic), and main.css (remove sync modal styles) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Sync button now lives in secondary controls (with share, fav, browse) - Always visible, no secret mode gate - Uses browser prompt() instead of custom modal — much simpler - First click: prompts for username/password, syncs, saves credentials - Subsequent clicks: syncs immediately (force sync) - Play history (playHistory + historyIndex) now persisted to localStorage and synced across devices (keep longer history on merge) - Removed ~200 lines of modal HTML/CSS/JS Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New modules (sync.js, crypto.js) were missing from the service worker's SHELL_ASSETS list, so the old cached events.js (without sync handler) was being served via stale-while-revalidate. Bumping to shell-v2 forces a full reinstall. Also passthrough /sync/* API requests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add profile screen: username, listen time, tracks heard, favorites, last played, sync status with remediation, debug panel - Replace sync button with profile icon (person silhouette) in player - Add listen stats tracking: totalListenSeconds, totalUniqueHeard, lastPlayedAt — accumulated on play/pause/end, persisted + synced - Enter screen: returning users see "WELCOME BACK" + username, new users see credential inputs with "CONNECT" button - Stats merge strategy: max() for counters, most-recent for timestamps - Debug-in-UI skill for visual debug during development - Bump SW shell cache to v3 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix Lambda SyntaxError from escaped \\! in index.mjs (bash heredoc artifact) - Move enter-content lower (bottom: 20vh) with z-index: 11 above title logo so credential inputs aren't obscured - Profile heard stat now uses heardTracks.size (same as player %) instead of totalUniqueHeard (which can exceed catalog size after full cycles) Addresses: #7 items 1, 2, 4 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…, generative artwork
Smoke background: layered radial-gradient pseudo-elements with CSS custom
properties (--smoke-1/2/3) driven by the circle system. Reduced-motion
media query disables animation.
Dante's Circles: 9 unlockable smoke color themes tied to totalUniqueHeard
milestones (0→100). Auto-applies on advancement with a subtle profile icon
pulse. Users can manually switch between unlocked circles on the profile
screen. Circle state persists locally and syncs across devices (highest
circle wins on merge).
Profile screen rework: unconnected users see stats + inline credential
form ("SYNC ACROSS DEVICES"), replacing the prompt() flow. Connected
users see stats + sync status + circle progress marks.
Cash rain: 150 bills across 5 size tiers with parallax depth (tiny/far
to huge/close), weighted distribution, per-tier opacity and fall speed.
Generative artwork: canvas-based animated placeholder for tracks without
cover art. Deterministic blobs derived from track metadata hash — each
track gets a unique visual identity. Long-press download and click-to-
search gestures moved from <img> to container for compatibility.
Enter screen: stripped to just ENTER button — no credential inputs, no
greeting. Music starts immediately.
Theme config: site.md frontmatter now supports theme.circles overrides
for per-instance circle colors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Activates when synced as "rmzi": auto-unlocks secret mode and all circles (totalUniqueHeard=999), shows a persistent green-on-black debug strip at the bottom of every screen, and a slide-up action menu for testing heard counts, cash rain, force sync, and secret mode toggle. Deactivates cleanly on disconnect. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Admin user is now set via `admin: rmzi` in site.md frontmatter, passed through build-config.js to SITE.admin, and checked in events.js instead of hardcoded string comparison. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
site.md stores admin username in plaintext (private repo), but build-config.js now hashes it with SHA-256 before writing to site.config.js. Runtime checks use Web Crypto to hash the entered username and compare against the stored hash. The admin username never appears in the shipped JS bundle. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace inline credential form on profile screen with a proper modal dialog. Triggered by "SYNC ACROSS DEVICES" button. Includes input validation (max 20 chars, required fields, no spaces in username), live character counts, error/success feedback, and Enter key submit. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
sync/prefix in existing tracks bucket) + CloudFront behavior. No DynamoDB, no API Gateway, no CognitototalUniqueHeardmilestones (0→100). CSS custom property driven (--smoke-1/2/3), persisted and syncedprefers-reduced-motionsite.mdfrontmatterTest plan
prefers-reduced-motiondisables smoke animation🤖 Generated with Claude Code