- Replace ul/li structure with semantic table (thead/tbody)
- Add 6 columns: Ext, Video, Audio, Size, Codecs, Link
- Show "N/A" for missing codec data
- Add 0.5rem spacing between dropdown and description
- Introduced `native_player_storyboard` setting with default disabled.
- Updated templates to conditionally load the storyboard preview script only for native players.
- Added descriptive comments for the new setting and template blocks.
- Use `ast.Constant` as primary node for Python 3.8+
- Maintain backward compatibility with `ast.Num`, `ast.Str`, and `ast.NameConstant`
- Prevent crashes on Python 3.12 where legacy nodes were removed
- Add safe handling via `try/except AttributeError`
Replace UU-uploads playlist workaround (proto field 104) with direct
requests to the channel Videos tab API (tab="videos"), aligning with
Invidious content-type handling. This restores proper continuation
tokens and stable pagination (~30 videos per page).
Update display logic:
- Show channel total upload count as an upper-bound while continuation
tokens exist.
- On final page, display exact fetched video count.
- Ensure page number never falls below current page (fix page reset to "1").
Maintain separate handling:
- Shorts and streams tabs continue using tab-specific continuation tokens.
Add test:
- TestChannelCtokenV5::test_include_shorts_false_adds_filter
Fixes issue where channels with many Shorts (e.g., Celine Dept) showed
only a few videos and broken pagination under "no shorts" sorting.
- Use glob lookup to find playlist files even with trailing spaces in filenames
- Sanitize lines (strip whitespace) before JSON parsing to ignore trailing spaces/empty lines
- Handle JSONDecodeError gracefully to prevent 500 errors from corrupt entries
- Return empty list on FileNotFoundError in read_playlist instead of crashing
- Extract _find_playlist_path and _parse_playlist_lines helpers for reuse
- Auto-select "Original" audio track by default in both native and Plyr HLS players
- Fix native HLS audio selector to use numeric indices instead of string matching
- Robustly detect "original" track by checking both `name` and `lang` attributes
- Fix audio track change handler to correctly switch between available tracks
- Add continuation_token_cache to store ctokens between page requests
- Use cached ctoken for page 2+ instead of generating fresh tokens
- Switch shorts/streams to Next/Previous buttons (no page numbers)
- Show "N+ videos" indicator when more pages are available
- Fix UnboundLocalError when page_call was undefined for shorts/streams
The issue was that YouTube's InnerTube API requires continuation tokens
for pagination on shorts/streams tabs, but the code was generating a new
ctoken each time, always returning the same 30 videos.