Replace the dashboard-only footer link with a "Files" item in the
persistent bottom tab bar (Home/Notes/Help/Settings) on every page, so
it's reachable the same way everywhere instead of only from the
dashboard.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add a shared Jinja icon macro (templates/_icons.html) with 27 Feather-style
stroke SVGs and import it across every live template - tab bars, buttons,
lesson-type/status icons, folder/course icons, and the lesson player's
footer brand mark all now use currentColor SVGs instead of emoji, matching
the app's vector logo instead of rendering inconsistently per platform.
A few icons built dynamically in JS (thumbnail-load fallbacks, toggled
button states) get a small ICON_SVGS constant per file, since JS template
literals can't call the Jinja macro.
Left pure directional glyphs (expand/collapse chevrons, move up/down
arrows, keyboard-shortcut arrows) as plain Unicode - they already render
as monochrome text, matching the existing collapsible-header chevron
pattern rather than the colorful pictographic emoji this was aimed at.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Swap the 📚 emoji in the header for an inline SVG mark - a rounded
square with a play triangle, echoing that this is a video-course
library. Uses var(--accent)/var(--bg-secondary) rather than fixed
colors so it re-colors automatically with whichever of the app's
theme presets is active, same as everything else in the header.
Applied consistently across all 5 templates; the small secondary
footer brand mark (still plain 📚 text) is untouched - this only
replaces the prominent header lockup.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Three visual/structural changes:
- Grid cards without a thumbnail (nearly all real courses in this
library) showed the same generic graduation-cap icon, making the
poster grid hard to visually scan. Replace it with a deterministic
color+initial per course name (same idea as Slack/Google Photos
default avatars), so cards without real cover art still look
distinct from each other.
- Notes/Help/Settings only existed as small footer text links,
meaning a scroll to the bottom of every page to navigate. Add a
persistent bottom tab bar (Home/Notes/Help/Settings, current page
highlighted via a new active_tab context var) to the dashboard,
Notes Hub, Settings, and Help pages. Deliberately left the lesson
page alone - it already has its own fixed-bottom notes panel, and a
second fixed bar there would just eat into an already content-dense
page.
- The no-course dashboard stacked five informational/queue cards
(Library Stats, Next Up, Pick Back Up, Recently Added, Continue
Watching, Recently Viewed) before "Your Courses," so the actual
library browser was the last thing on the page. Move it up to right
after the Surprise Me banner - it was already unconditional, so this
only changes where it renders, not when.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
view_lesson() called update_lesson_progress() with no arguments on
every page load, which defaults completed=False and progress_seconds=0
and silently overwrote whatever was already saved - just opening an
already-watched lesson reset its progress/completed state unless the
client happened to report real values within the next 15 seconds.
Replaced with touch_lesson_accessed(), which only bumps last_accessed.
Also fixes the "Resume from Xs" feature this fed into: it read a value
that was never populated on this route, and even when given a real
one, checked activeMedia.duration synchronously before metadata had
loaded, so it silently never applied. Now waits for loadedmetadata (or
resolves immediately if already available) and defers to an explicit
note-timestamp jump (?t=) when both are present.
Notes Hub gets a live search box filtering by note text, lesson title,
or course name (client-side, no reload), with a "no notes match" state
- useful now that a single category folder can hold dozens of courses'
worth of timestamped notes.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replace the single free-text note per lesson with a list of timestamped
note entries, migrated transparently from the old format. Adds a
floating notes panel on the lesson page with an always-reachable
quick-capture bar (press N to pause and jump in), inline edit/delete,
click-to-seek timestamps, and a live "Saved Xs ago" indicator. Notes
Hub, the study guide export, and the Outline push all updated to
render multiple timestamped notes per lesson.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Templates only, no backend changes:
- Fixed the real bug: JS-generated status/loading text and a few component
styles used hardcoded hex (#007acc, #999/#666, #28a745, #ff6b6b) instead
of the CSS variables the theme system already provides, so they didn't
track the user's chosen theme/accent - most visible on Light or any named
theme other than the default. Added --success/--error to all 5 templates'
:root blocks and replaced every non-:root occurrence. Left the
.lesson-type badge colors and generic UI chrome grays alone (intentional,
not theme-dependent). Verified live by switching to Nord and Light themes.
- Dashboard cards (Library Stats, Next Up, Pick Back Up, Recently Added,
Continue Watching, Recently Viewed) are now collapsible, state remembered
per device via localStorage - the no-course dashboard had grown to 7
stacked cards.
- Course page's three action buttons get consistent compact sizing and
icons instead of a plain stack.
- Library browser and transcript search show shimmering skeleton rows
instead of bare "Loading..."/"Searching..." text while a fetch is in
flight.
- Hover treatment made consistent: transcript results get the same lift
.lesson-item already had, heatmap cells get a GitHub-style hover
scale-up, and Notes Hub links get a background-chip hover.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Six more dashboard features, all built on the per-course progress-file
scanning infrastructure from earlier sessions:
- Notes Hub (/notes): every lesson note across the library in one place,
newest first, reusing the existing /recent/open cross-course jump route.
- Transcript search: opt-in checkbox on the Library search box, searching
inside .srt/.vtt files. Kept cheap by doing a raw substring match as the
filter step and only extracting a snippet for files that actually match.
- Stale course nudges ("Pick Back Up"): courses with progress that haven't
been touched in 14+ days.
- Study guide export: compiles a course's notes into one downloadable
markdown file, section/lesson structure preserved.
- Next Up queue: an ordered, persisted "what to tackle next" list with
up/down reordering and a queue button on every course row.
- Activity heatmap: a 90-day contribution-style calendar in the Library
Stats card.
_scan_library_activity() now does one walk over every course's progress
file per dashboard load; library stats, stale courses, and the heatmap all
derive from that single scan instead of three independent ones.
Also refactored the duplicated lesson-progress-key lookup (used in three
places now) into _resolve_lesson_progress_key(), and flagged a pre-existing
bug found along the way (not fixed here, kept out of scope): subtitle files
never actually attach to a Lesson object, so the video player's caption
track has never had anything to render.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>