Commit graph

693 commits

Author SHA1 Message Date
fe237ba350 Document capability-driven presentation practice in CLAUDE.md. 2026-02-07 16:40:04 -05:00
4b8d2aa4d3 Fix watch mode sticky video and media overflow
Change section.content overflow-x from auto to clip so position:sticky
works through it. Add min-width:0 on watch-left to prevent grid blowout.
Add overflow:hidden on sticky product-images to contain media.
2026-02-07 16:36:26 -05:00
819c0d630a Fix sticky video by wrapping left column in watch-left container
position: sticky only works within the containing block. In the grid
layout, each named area (images, description, comments) was its own
containing block, so the video had nowhere to stick. Wrapping all
left-column content in a single div gives the video a tall parent
to stick within while scrolling.
2026-02-07 15:24:06 -05:00
bc4858c58a Add YouTube-style watch mode with sticky video, autoplay, and related content
Shop owners can enable watch mode in settings to get: direct video autoplay
with muted fallback, sticky video player while scrolling, and a stemming-powered
"Up Next" related content sidebar. Degrades gracefully per capability.
2026-02-07 14:57:37 -05:00
68089dff5b Add AJAX comment submission to preserve media playback
Comments now submit via fetch() when JS is available, returning JSON
instead of triggering a full page reload that kills video/audio playback.
Falls back to the existing POST+redirect when JS is disabled.
2026-02-07 11:19:58 -05:00
timehexon
2ae2863a4c Replace "AI" with "machine learning" in CLAUDE.md
Machine learning is what we grow. "AI" is forbidden in all
permacomputer discourse, marketing, & documentation.
2026-02-02 19:55:59 +00:00
726cf6eebb Add shop setting to toggle product/content date visibility
Remove border-top from date metadata styling. Add show_dates boolean
to Shop model (default on) with radio buttons in Branding Settings
to show or hide created/updated dates on product and content pages.
2026-02-01 13:47:05 -05:00
875183d201 Add created/updated dates to product and content pages
Show subtle date metadata at the bottom of the description section
with muted text and a light border separator. Only shows "Updated"
when it differs from the created date.
2026-01-31 14:01:27 -05:00
1eca7a3145 Fix content.j2 thumbnail handling - remove play overlay from non-videos
- Fix broken image when content has no thumbnail1
- Remove play button overlay from images/GIFs (only videos get it)
- Non-video content now opens in new window on click
2026-01-25 10:25:55 -05:00
bbc03b0c6d Add template syntax validation tests
Validates all 51 Jinja2 templates can be parsed without syntax errors.
Includes specific tests for key templates: base, product, content, cart,
checkout, shop, invoice, billing, crypto_checkout, home, product_edit,
user_settings, and user_purchases.

Catches issues like mismatched {% if %}/{% endif %} blocks before deployment.
2026-01-22 12:48:50 -05:00
4f43aa7104 Fix content.j2 template - remove extra endif causing syntax error 2026-01-22 12:24:12 -05:00
ded0941839 Fix video thumbnail container CSS - support div element not just a 2026-01-22 12:04:43 -05:00
d254147362 Simplify inline video - use direct URLs, no /player/ endpoint
- Pass video URL directly to playInline() function
- No more fetching from JSON endpoint
- No-JS fallback opens video URL directly in new tab
- Play Preview button links directly to video file
- Removed all /player/ route dependencies from templates

Much simpler: click thumbnail → swap to video element with that URL

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-22 12:02:55 -05:00
57a5f83b73 Replace pop-up player with inline video on thumbnail click
Simple approach:
- Click thumbnail → swap it for an inline video element
- Video has native browser controls (including PiP button)
- No JavaScript fallback → opens /player/{id} in new tab
- Removed all pop-up window code

The native browser video controls already have a PiP button,
so no need for custom PiP implementation.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-22 11:32:17 -05:00
34ee5a9eeb Replace broken PiP API with small floating pop-out window
Native PiP API (requestPictureInPicture) not available in user's browser.
Instead, open a small pop-out window (480x320) that:
- Is movable (drag the window)
- Is resizable (resize=yes)
- Stays open when browsing main site
- Has prev/next controls (from player.j2)
- Auto-advances when video ends (from player.js)
- Positioned in bottom-right corner of screen

This is more reliable than trying to use browser APIs that may not
be available or work differently across browsers.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-22 11:24:28 -05:00
6ec2a97f34 Add PiP support to content.j2 template (was only in product.j2) 2026-01-22 10:09:12 -05:00
453334f3e4 Change thumbnail click to open PiP directly instead of pop-up 2026-01-22 09:35:56 -05:00
d7e70e9d24 Move PiP button to separate text area to avoid click conflicts 2026-01-22 09:35:13 -05:00
53a21e721b Fix PiP button click propagation to parent link 2026-01-22 09:34:42 -05:00
5d5398921a Remove URL expiration warning - data is already downloaded 2026-01-22 09:01:43 -05:00
428edc3b21 Update help text for PiP button 2026-01-22 08:58:01 -05:00
7a2aabcd6e Switch to native PiP with Media Session API for prev/next controls
Use native browser PiP instead of Document PiP:
- Native PiP has right-click "always on top" option that actually works
- Media Session API adds prev/next track buttons to PiP controls
- Video stays in PiP when navigating between tracks
- Auto-advances to next video when current one ends

Key features:
- Creates hidden video element for PiP playback
- requestPictureInPicture() for native browser PiP
- navigator.mediaSession for prev/next track handlers
- Updates MediaMetadata with current title
- Stays in PiP mode during navigation

User can right-click PiP window and select "Always on top" for
true OS-level always-on-top behavior.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-22 08:57:43 -05:00
3153a98dff Add JSON API endpoint for direct Document PiP mode
Major improvements to Picture-in-Picture experience:

1. New JSON endpoint /player/{product_id}/json returns:
   - videoUrl: presigned S3 URL
   - title: product title
   - prevProductId/nextProductId: navigation data
   - mediaType: video/audio/image

2. Direct PiP from product page:
   - Click 📺 PiP button on product page
   - Opens Document PiP directly (no pop-up window first)
   - Navigation stays within PiP (no page reloads needed)

3. In-PiP navigation:
   - Prev/Next buttons load new video in same PiP window
   - Video auto-advances when finished (stays in PiP)
   - No page navigation - pure PiP experience

4. Better error handling:
   - JSON endpoint returns proper error messages
   - Fallback to pop-up window if Document PiP fails

This creates a true floating video player experience where users
can browse videos entirely within the PiP window.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-22 08:47:44 -05:00
54deee7fe8 Add direct PiP button on product page bypassing pop-up window
Add 📺 PiP button overlay on video thumbnails that opens Document PiP
directly from the product page without opening pop-up window first.

Features:
- PiP button positioned at top-right of video thumbnail
- Fetches video URL from /player/{product_id} endpoint
- Opens Document PiP window with video + prev/next controls
- Navigates to /product/{id} pages (not /player/{id})
- Auto-advances to next product when video ends
- Falls back to pop-up window if Document PiP unsupported
- Comprehensive console logging for debugging

User flow now:
1. Product page with video thumbnail
2. Click ▶ play overlay -> pop-out window (existing behavior)
3. Click 📺 PiP button -> directly to Picture-in-Picture mode

This eliminates the need to open pop-up then click PiP button.

Requires Chrome 111+ or Edge 111+ for Document PiP support.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-22 08:06:19 -05:00
9fc9c71410 Add comprehensive debugging for Document PiP implementation
Debug logging added to diagnose why Document PiP isn't working:
- Log Document PiP API availability on page load
- Log browser user agent for compatibility checking
- Log when togglePip is called and which path is taken
- Log video dimensions and calculated aspect ratio
- Alert user if Document PiP fails with error details
- Alert user if browser doesn't support Document PiP
- Log all fallback PiP operations

This will help identify:
- Browser compatibility issues (needs Chrome/Edge 111+)
- Video metadata loading issues
- API permission errors
- Which PiP mode is actually being used

User should check browser console when clicking PiP button to see
which path is taken and any error messages.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-21 13:55:06 -05:00
2258385cf4 Implement Document Picture-in-Picture with prev/next navigation
Replace basic PiP with Document Picture-in-Picture API that provides:
- Custom navigation controls (Prev/Next buttons) in PiP window
- Automatic aspect ratio calculation from video dimensions
- True OS-level always-on-top (no window.focus() polling needed)
- Window is movable by default (browser feature)
- Syncs playback between main window and PiP
- Auto-navigates to next video when current ends
- Product title displayed in PiP controls
- Fallback to regular PiP for unsupported browsers

Technical details:
- Window sized to video aspect ratio (640px wide, height calculated)
- Controls bar at bottom with prev/next navigation
- Pauses main window video when PiP is active
- Syncs seek position and play/pause state bidirectionally
- Closes PiP window on toggle or window close

Document PiP is supported in Chrome/Edge 111+ and provides the best
experience with custom UI controls AND true always-on-top behavior.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-21 13:05:37 -05:00
d244617554 Add native Picture-in-Picture support and debug ended event
Picture-in-Picture (PiP) improvements:
- Add native browser PiP button for videos (P key or 📺 button)
- PiP has true OS-level always-on-top when you right-click and select "Keep on top"
- PiP works on mobile and desktop with browser's native implementation
- Button shows on mobile (PiP is useful on mobile devices)
- Active state toggles button text between "📺 PiP" and "📺 Exit PiP"

Debug 'ended' event not firing:
- Add explicit ended event listener with console logging
- Log when media starts playing
- Log playback progress every 5 seconds
- This will help identify why auto-advance isn't working

The native PiP API provides better always-on-top than our window.focus()
approach because it's implemented at the OS level by the browser.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-21 12:49:44 -05:00
741004b2d2 Improve mobile player controls and remove fullscreen button
Mobile improvements:
- Controls auto-hide after 3 seconds on page load
- Tap player to show/hide controls (instant hide or show with 3s auto-hide)
- Tapping outside controls grid hides them immediately
- Mobile autoplay fix: start muted, unmute after 100ms

Button changes:
- Remove fullscreen button (not needed for pop-out windows)
- Page button now always opens in new tab (simplified logic)
- Remove F key shortcut for fullscreen

Desktop behavior unchanged (hover to show controls).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-21 12:40:42 -05:00
c6ea5f7f4b Add comprehensive documentation for parallel test execution system
Documents the 16.7x test speedup achieved through pytest-xdist:
- Explains per-worker database isolation strategy
- Details SQLite WAL mode configuration for concurrency
- Describes automatic worker distribution and load balancing
- Covers implementation challenges and solutions
- Provides performance metrics and hardware requirements
- Includes best practices for parallel-safe tests

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-21 12:25:41 -05:00
6d40232fe4 Fix Decimal serialization in subTest for pytest-xdist
The parallel test execution failed on 4 tests because pytest-xdist's
execnet cannot serialize Decimal objects when sending test results
between workers.

Solution: Convert Decimal objects to strings in subTest() parameters.
The Decimal values are still used for actual test logic, but the
subTest labels now use string representations.

Fixed tests:
- test_sweep_restocking_fee_fee_amount_calculation
- test_doge_expected_amount_precision_always_rounds_up
- test_xmr_expected_amount_precision_always_rounds_up
- test_fee_calculations_always_round_up

This is a common pytest-xdist limitation with non-serializable types.
2026-01-21 12:13:36 -05:00
af4b70a160 Fix parallel test execution with isolated per-worker databases
The previous parallel test attempt failed because all workers were trying
to use the same SQLite database file, causing locking errors.

Solution:
- Created conftest.py to configure pytest-xdist workers
- Each worker gets a unique database file (test_make_post_sell_gw0.sqlite, etc.)
- Enabled SQLite WAL (Write-Ahead Logging) mode for better concurrency
- WAL allows multiple readers while a writer is active
- Modified test.ini to use $TEST_DATABASE_PATH environment variable
- Automatic cleanup of worker databases after test completion

Benefits:
- True isolation between test workers
- No database locking conflicts
- Tests can run fully in parallel
- Expected test time reduction from 30min to ~5-10min

Each worker's database is completely isolated, preventing the SQLite
"database is locked" errors that plagued the previous attempt.
2026-01-21 12:07:16 -05:00
012014a20c Add parallel test execution with pytest-xdist
The test suite was taking 30 minutes to run sequentially. With 434 tests,
parallel execution should significantly reduce CI time.

Changes:
- Add pytest-xdist to requirements-test.txt
- Update Makefile test target to use 'pytest -n auto'
- Auto mode automatically uses number of CPU cores available

Expected improvements:
- Unit tests and model tests can run fully in parallel
- Integration tests with isolated databases can run in parallel
- Overall test time should reduce to ~5-10 minutes on multi-core CI

Note: Crypto RPC tests may still be a bottleneck if they hit shared
wallet daemons, but most other tests should parallelize well.
2026-01-21 11:57:46 -05:00
5ee3d1efdd Fix test: PDF is now a supported media type (document)
The test_unsupported_extensions test was failing because we added PDF
support to the media player. PDF now returns 'document' from
get_media_type() instead of None.

Changes:
- Import DOCUMENT_EXTENSIONS constant
- Add test_document_extensions() test
- Remove 'pdf' from unsupported extensions list
- Add DOCUMENT_EXTENSIONS to lowercase validation test
2026-01-21 11:45:46 -05:00
af8da71c9a Replace PiP mode with draggable pop-out window
The native browser Picture-in-Picture mode had limitations:
- Couldn't stay on top of all windows (terminals went over it)
- No user control over drag/resize
- Browser-controlled positioning

Changes:
- Simplified openMediaPlayer() to always use pop-out window
- Pop-out window is draggable and resizable by user
- Always-on-top toggle uses window.focus() for better control
- Removed PiP button and togglePip() function
- Removed keyboard shortcut for PiP (P key)
- Cleaned up unused helper functions (preloadNextMedia, loadMedia)
- Reorganized player controls (3x3 grid)

The pop-out window gives users full control over positioning and sizing.
2026-01-21 11:24:56 -05:00
9f895f17e0 Add /random and /tv endpoints for media playback
- /random: Redirects to a random public media item from the shop
- /tv: Full-screen TV mode that autoplays media in sequence
  - Starts with a random media item
  - Shows controls on hover (Random, Exit, Fullscreen)
  - Keyboard shortcuts: C for random, ESC for exit, F for fullscreen
  - Auto-enters fullscreen on load
  - Embeds player in iframe for seamless integration
2026-01-21 11:14:07 -05:00
4dea196297 Fix Firefox unresponsive script issue for images and PDFs
- Detect images/PDFs early and open window directly
- Avoid creating hidden elements and doing DOM manipulation for static content
- Only use PiP/floating player for video/audio
- Eliminates Firefox 'script unresponsive' dialog on image navigation
- Much faster response time for images and PDFs
2026-01-21 11:02:26 -05:00
574ea8c6a2 Add aggressive preloading of next video/audio for instant playback
- Preload next media immediately after current starts (high priority)
- Preload previous media after 2 second delay (lower priority)
- Uses hidden video/audio elements with preload='auto'
- Works in pop-out player, PiP mode, and floating audio player
- Browser caches preloaded media for instant playback on auto-advance
- Previous uses preload='metadata' to save bandwidth
- Cleans up preloaded elements when navigating

Next video loads instantly when auto-advance triggers, creating seamless TV-like experience.
2026-01-21 11:00:21 -05:00
2dc817e3d1 Add auto-advance to next media by default
- Videos/audio: auto-advance when media ends
- Images: auto-advance after 60 seconds
- PDFs: auto-advance after 60 seconds, cancelled if user scrolls
- Detect scroll via wheel/scroll events to cancel auto-advance
- Works in PiP mode, pop-out player, and floating audio player
- Seamless playlist-like experience through all media in shop
2026-01-21 10:56:17 -05:00
f0b23ec0ff Add parent page navigation and PDF support
- PiP now controls parent page: clicking prev/next in PiP navigates the parent page URL
- Add 'Go to Page' button (G key) to open current product page
- Add PDF support: renders PDFs in iframe, opens in pop-out (not PiP)
- PDFs and images fall back to pop-out player window
- Pass product URLs through playerData for navigation
- Audio gets small floating player, video gets PiP, PDFs get window
2026-01-21 10:51:36 -05:00
962a89c3a6 Add mobile support and responsive player controls
- Mobile devices open player in new tab (better than PiP)
- Add playsInline attribute for iOS autoplay support
- Responsive controls: hide PiP/auto-resize/always-on-top on mobile
- Implement togglePip function for desktop PiP button
- Optimize button sizes and spacing for touch screens
- Detect mobile via user agent and fallback gracefully
2026-01-21 10:47:57 -05:00
a6c76456d4 Fix PiP navigation to update video source instead of page navigation
- Prev/next in PiP now loads new video source dynamically
- Keeps PiP window open during navigation
- Updates playerData to maintain prev/next chain
- No page navigation, seamless media switching
2026-01-21 10:45:05 -05:00
dcbfd10101 Add native Picture-in-Picture mode with Media Session API
- Click video enters native browser PiP mode directly
- Uses Media Session API to add prev/next track buttons to PiP
- Falls back to small floating player if PiP not supported
- Cleaner than pop-out window, truly floats over all apps
2026-01-21 10:44:01 -05:00
a93d5e457f Redesign controls: centered 3-column grid with play/pause
- Center all controls in screen with dark background panel
- 3-column CSS Grid layout:
  Row 1: Prev | Play/Pause | Next
  Row 2: Always On Top | Fullscreen | Auto-Resize
- Add play/pause toggle button (space key)
- Make always-on-top more aggressive (250ms focus interval)
- Update play/pause icon based on media state
- Larger, more prominent navigation buttons
2026-01-21 10:41:25 -05:00
55fe55041f Ensure media always maintains aspect ratio during manual resize
Add max-width/height constraints and object-position to guarantee aspect ratio is preserved when user manually resizes the window
2026-01-21 10:37:44 -05:00
45ebe5c0ae Fix fullscreen to maintain aspect ratio
Request fullscreen on player container instead of document root to ensure media maintains aspect ratio with object-fit: contain
2026-01-21 10:35:53 -05:00
54e9303912 Fix auto-resize with minimum constraints and responsive controls
- Add minimum window size (600x400) to prevent controls from breaking
- Make button labels more compact (Full, On Top, Resize)
- Add responsive CSS for small windows (stack controls vertically)
- Fix auto-resize scaling to maintain aspect ratio with minimums
- Reduce button padding and gaps for better fit
2026-01-21 10:35:41 -05:00
d3047a7c0c Add pop-out media player with autoplay and navigation controls
Enables an immersive viewing experience for video, audio, and images through a dedicated player window. The player automatically resizes to match media dimensions, supports keyboard navigation, and includes toggles for always-on-top and auto-resize behavior. Features include:

- Pop-out window with autoplay for video/audio/images
- Dynamic window sizing based on media aspect ratio (320px to HD)
- Navigation controls for browsing shop's public media
- Always-on-top toggle (persisted to localStorage)
- Auto-resize toggle (persisted to localStorage)
- Fullscreen support
- Keyboard shortcuts (arrows, ESC, F, T, R)
- Feature flag for easy enable/disable (default: enabled)
- Products use preview file, content uses product file
- Only public products (visibility == 1)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-21 10:06:06 -05:00
82327c1d0b Fix sitemap date format - use YYYY-MM-DD for sitemaps, proper ISO 8601 for Atom 2026-01-11 09:42:05 -05:00
3dfbac6f3e Add sitemap, RSS/Atom feeds, and Google site verification for shops
- Add /sitemap.xml, /rss.xml, /atom.xml, /feed.xml routes
- Include only public products and content (visibility=1)
- Update robots.txt to include sitemap reference for shops
- Add google_site_verification column to shop model
- Add verification code input in shop integration settings
- Render verification meta tag on shop homepage
- Update CLAUDE.md with migration ID generation requirement
2026-01-11 08:52:38 -05:00
7ced344cb0 Update setup.py 2025-12-29 15:40:34 +00:00