gitoriaLog in with ident

tracker

All repositories: gitoria

ReadmeCodePull requestsReleasesTicketsSettings
Commitd8b12d67d8b12d67tracker#27 (mission 060): short ids for movies, series and persons — old 702 kept (data/old-short-ids.json), new random [a-z0-9]{5} unique across both, claimed at creation, background backfill (resumes), shown under poster/photo, /<shortId> → 301; gate 259, tests/realdata-060*, README + STATUSmred8b12d67/components/mymovies.hl

2.9 KB

  1. // components/mymovies.hl — `/my/movies` (tracker.worldapi.org#13): every MOVIE the signed-in user follows, the one
  2. // followed last on top — the architect: "/my/movies = the movies you follow, like /my/shows". A row: the small poster, the
  3. // title with its year linking to the movie's page (`/shows/<slug>`: movies share the show page and its Follow button).
  4. // Read-only like /my/shows, the same row look (the my-show-row tags/classes in styles.hl). Reused: `followsOfUser`,
  5. // `insertByFollowDesc` (follows.hl), `showById`, `posterUrlOf`, `titleWithYear` (shows.hl).
  6. // mission 058 (tracker#24): a movie watched on its page (watch `movie:<id>`, watches.hl) shows the solid check in its row,
  7. // and the count line says how many of them are watched ("3 movies · 1 watched"). One scan of the user's watches (watchedSet).
  8. parent './main.hl'
  9. import { appTitle } from '../project.hl'
  10. import { userIdOfSession } from '../users.hl'
  11. import { followsOfUser, insertByFollowDesc } from '../follows.hl'
  12. import { showById, posterUrlOf, titleWithYear } from '../shows.hl'
  13. import { watchesOfUser, watchedSet } from '../watches.hl'
  14. // static: an mpackdb-backed helper must be `static` (hybriel#115/#116)
  15. static watchedCountOf = (rows) => {
  16. let n = 0
  17. for (r of rows) { if (r.watched) { n = n + 1 } }
  18. return n
  19. }
  20. static myMoviesRowsOf = (userId) => {
  21. if (userId == null) { return [] }
  22. let watched = watchedSet(watchesOfUser(userId))
  23. let out = []
  24. for (f of followsOfUser(userId)) {
  25. let show = showById(f.show)
  26. if (show != null && show.type == 'movie') {
  27. out = insertByFollowDesc(out, {
  28. id = show.id title = titleWithYear(show) href = '/shows/' + show.urlSegment
  29. posterUrl = posterUrlOf(show) followedAt = f.at != null ? f.at : 0
  30. watched = watched['movie:' + show.id] == true
  31. })
  32. }
  33. }
  34. return out
  35. }
  36. session = null
  37. userId = userIdOfSession(session)
  38. signedIn = userId != null
  39. // a plain copy of userId for `rows` (mission 047: session sync, see components/show.hl `me`)
  40. me = userId
  41. rows = signedIn ? myMoviesRowsOf(me) : []
  42. hasRows = rows.length > 0
  43. noRows = !hasRows
  44. countText = rows.length + (rows.length == 1 ? ' movie' : ' movies') + ' · ' + watchedCountOf(rows) + ' watched'
  45. emptyText = signedIn ? 'You follow no movies yet.' : 'Sign in to see the movies you follow.'
  46. __title = 'My movies — ' + appTitle
  47. View {
  48. myMoviesPage {
  49. h1 { "My movies" }
  50. if (noRows) { p { class = "muted" emptyText } }
  51. if (hasRows) {
  52. p { class = "muted list-count" id = "mymovies-count" countText }
  53. myShowsRows {
  54. for (row of rows) {
  55. myShowRow {
  56. img { class = "myshow-poster" src = row.posterUrl alt = row.title }
  57. a { class = "myshow-title" href = row.href row.title }
  58. if (row.watched) {
  59. myMovieWatched { class = "checkicon solid" title = "Watched"
  60. svg { viewBox = "0 0 24 24" width = "22" height = "22" "aria-hidden" = "true"
  61. circle { cx = "12" cy = "12" r = "10" }
  62. path { d = "M7 12.5 L10.5 16 L17 8.5" }
  63. }
  64. }
  65. }
  66. }
  67. }
  68. }
  69. }
  70. }
  71. }

Branches

Latest commits

  • d8b12d67tracker#27 (mission 060): short ids for movies, series and persons — old 702 kept (data/old-short-ids.json), new random [a-z0-9]{5} unique across both, claimed at creation, background backfill (resumes), shown under poster/photo, /<shortId> → 301; gate 259, tests/realdata-060*, README + STATUSmre
  • f14db671tracker#22-#25 (mission 058): episode air dates, season check = all episodes watched, movie watched check (+ /my/movies count), /genres/<genre> pages (movies + series, newest first, paginated); gate 238, tests/realdata-058.mjs, README + STATUSmre
  • 1704ec45tracker#17 (mission 057): season caret down/up, skeleton rows while a season loads, sessionless showSeasonEpisodes face (no page re-mount), client-only close; gate 214, tests/realdata-057.mjs, README + STATUSmre
  • f2fe3e36mission 056: README + STATUS (merge, fixes, Hybriel 8590df63, real-data check), tests/realdata-056.mjs, tools/check-public-slugs.hlmre
  • f40c250emission 056: re-vendor hybriel master 8590df63 (#121, #122); an adult title's page is Not found for non-followers; gate: leave the page before stopping the servermre
  • 2b7fdd6cmission 056: signed-out header one row on phones ("Log in", nowrap), backfill skips adult titles' posters, gate checksmre
  • 2c53d5efMerge branch 't16-person' (tracker#16 person pages) into main; filmography shows only public titles (054 adult flag), gate race fix (backfill start line)mre
  • c171227emission 054: hide adult/unknown titles from the public lists and the search; in-app adult-flag backfill (TMDB details + poster per title, resumes), gate + real-data proofmre
  • 139fafd8tracker#16: short bio (4 lines, click = all), real-data check script, README + STATUSmre
  • 93be9476tracker#16: person pages /person/<slug> with the filmography fetched from TMDB on the first visit (step by step), gatemre
  • 47a3cae6STATUS: mission 053 merge commit idsmre
  • dcc5eecaMerge branch 't14-search'mre
  • 03edc783Merge branch 't15-tvmaze'mre
  • 71b46345tracker#15: numbering check by date or title, placeholder titles in other languages, docs + real-data proofmre
  • 6bb2daf1tracker#13: homepage (tiles, intro, latest movies/shows), /shows, /movies/page/N, /my/movies; lists cached in memorymre
  • b8bd1157tracker#14: README + STATUS (search, real-data numbers, gate, merge notes)mre
  • 65c694a8tracker#14: search — header magnifier, /search/<text> (in-memory word-prefix index over titles + people), Fetch from web (TMDB search/multi, ours left out), Add = import via syncShow; gate +25 checks, real-data scriptmre
  • 34f2c15btracker#15: TVmaze merge in the sync (gaps only: new episodes/seasons, empty titles/air dates; numbering check), fake TVmaze episodes + gatemre
  • cbdc4ea7tracker#12: link icons TMDB/IMDb/TVDB/TVmaze; sync fills missing ids (TVmaze lookup); movies fetched via /movie/mre
  • b105bcd8tracker#11: Hybriel master ff51cf46 (checks no longer vanish), mobile-first styles, carets, follow button, sign-in modal, inverted check, orange castmre