# JavaScript Usage This project minimizes JavaScript usage, preferring pure CSS solutions where possible (e.g., `
` elements for toggles). JavaScript is used only where necessary for payment integrations, real-time updates, and progressive enhancement. ## Philosophy - Prefer pure HTML/CSS over JavaScript - Use `
` elements for toggles instead of JS - External SDKs loaded only when payment method is enabled - No build step - vanilla JS only - No jQuery - all vanilla JavaScript ## Static JavaScript Files Located in `make_post_sell/static/js/`: ### qrcode.min.js - QRious library for QR code generation - Used by: Crypto checkout page - Generates payment QR codes for XMR/DOGE addresses ### custom.js - Markdown preview functionality - Functions: `previewAjax()`, `sendPreview()` - Uses fetch API for AJAX calls to `/markup-editor-preview` ### watch.js - Watch mode continuous playback engine - Used by: `product.j2` when shop has `watch_mode_enabled` - Discovery ring with deterministic content traversal per shop - Crossfade transitions between media (3s, 60 steps) - Countdown overlay (7s) between items - Queue management: add, remove, reorder - Two-phase preload: JSON metadata fetch, then media buffering 30s before end - Recently-played filtering via localStorage (4-hour expiry) - Handles video, audio, and static content (PDFs, images) - Autoplay toggle persisted in localStorage - Ring state (position, direction, history) persisted in localStorage ### sandbox.js - Client-side creative filter engine (IIFE, ~700 lines) - Used by: `base.j2` when shop has `sandbox_mode` enabled - 32 CSS filter presets across 7 categories (basic, warm, cool, dramatic, color, Instagram-style, SVG) - 7 adjustment sliders (brightness, contrast, saturation, hue, blur, sepia, grayscale) - Image export via canvas `toBlob()` (PNG) - Video export via `MediaRecorder` + `captureStream(30fps)` (WebM) - On-demand face detection via MediaPipe Face Mesh (468 landmarks, eye glow, face mask overlays) - Upload-to-bucket: presigned POST to user's S3 bucket via `/u/sandbox/upload` - localStorage persistence: preset, slider values, panel state, filter mode - Exposes `window.sandboxReapply()` for watch.js SPA integration ### signals.js - Anonymous page visit signal collector - Used by: all product/content pages - Collects presence (wall_clock, visible, active), scroll (depth, direction changes), and media playback signals - Sends single JSON beacon (~300 bytes) via `navigator.sendBeacon()` on page unload - No cookies, no IPs, no fingerprints — purely behavioral signals - Viewport width sent for device class derivation (server-side) ### comments.js - AJAX comment submission (progressive enhancement) - Intercepts comment form POST, submits via `fetch()` with `X-Requested-With: XMLHttpRequest` - Server returns JSON (HTTP 201) for AJAX requests - Inserts new comment into DOM without page reload (preserves media playback) - Falls back to normal POST + redirect without JS or on error ### player.js - Pop-out media player with draggable window - Prev/next navigation and keyboard shortcuts - Auto-advance for images/PDFs (60s timer) - Preloads adjacent media for instant switching - Used by: `/random` and `/tv` endpoints ## Inline JavaScript by Template ### base.j2 **Purpose:** Theme switching (dark/light mode) - Runs immediately in `` to prevent flash of wrong theme - Priority: localStorage > user preference > shop default - Exposes `window.setTheme()` for programmatic use ### shop_settings.j2 **Purpose:** Settings page interactions - Crypto wallets toggle (checkbox + localStorage) - Theme preview for shop default theme radio buttons - Note: Payment provider toggles use pure CSS `
` elements ### user_settings.j2 **Purpose:** User theme preference sync - Syncs theme radio buttons with localStorage - Updates localStorage on form submit ### cart_checkout.j2 **Purpose:** Payment processing 1. **PayPal SDK** (`paypal.Buttons()`) - Loads PayPal SDK from `paypal.com` - Creates orders via `POST /paypal/create-order` - Handles approval flow and form submission - Double-click protection flags 2. **Cancel Crypto Quote** (`cancelQuote()`) - Cancels pending crypto payment quotes - Uses fetch API with CSRF token ### crypto_checkout.j2 **Purpose:** Crypto payment monitoring - QR code generation using QRious library - Countdown timer for quote expiry - Status polling via fetch API - Copy-to-clipboard for address/amount - Dynamic UI updates based on payment status - Functions: `disableQuoteButtons()`, `removePaymentElements()`, `replaceButtonsWithInvoiceLink()` ### snippets/stripe.j2 **Purpose:** Stripe card form (macro `new_card()`) - Loads Stripe.js SDK - Creates Payment Element for card input - Handles `stripe.confirmSetup()` flow - Uses vanilla JS with `DOMContentLoaded` ### snippets/analytics.j2 **Purpose:** Analytics tracking (optional) - Plausible Analytics (privacy-focused) - Google Analytics (gtag.js) - Only loaded if shop has configured analytics ### product.j2 **Purpose:** Inline video playback - `playInline()` replaces thumbnail container with `