github LumoraPlayer/Lumora v7.3
Lumora v7.3

56 minutes ago

Lumora v7.3

Search

  • Actors and actresses are searchable, with their series and films one press away. Search matched catalogue titles and the guide only, so a query naming a performer came back empty - the person page already existed behind a cast face, but had no door of its own. Search now also asks TMDB's people index and ranks matching performers alongside local titles (a catalogue title wins a tie), with their portrait, a "Known for" line and a PERSON badge; picking one opens the biography and filmography, opening on series or films according to the active filter (or what the person is best known for), and Back returns to the search session. Requires the same TMDB key Discover uses.

Player

  • The end of a series lands on its poster instead of the Series tab. When the last episode ended, an episode started without a series-page context - a Continue Watching/Next Up tile that direct-played, a download, a queue restored after the context was cleared - had no return target, so closing dropped the viewer on the Series tab. The end-of-playback return now resolves the finished episode's show (resident first, then the catalogue database) and opens its detail page with the season and Play button where they were.

Sync

  • A removal on one device now sticks on the others instead of being pushed back to Trakt. Watched sync and Trakt's resume/Up Next lists were both pull-only by design, so un-watching or taking a show off Continue Watching on one TV left the mark on the other; the other device then saw Trakt missing it and its next push (or the next play) put it straight back. The pulls now remember which items they had already confirmed on Trakt and treat one of those disappearing as a removal: the watched mark, its per-copy resume entry and the completed-trail stub are cleared here too, so the next push cannot resurrect it. The same reconciliation runs against /sync/playback, and Trakt's dropped-show list is now read as well as written, so taking a series off Up Next on one device hides it on every device (and Restore removed Up Next un-drops it on the account). Marks this device never saw on Trakt are still never removed - a local-only history is not evidence of anything. The watched pull also walks every page now instead of only the first 100, and asks for the episode breakdown the 2026 Trakt API requires, so a large history is actually complete before any removal is inferred from it.

Catalogue

  • Films now get the same personal row as Series, and a film can be put on Next Up. The Films poster led with Continue Watching alone and had no watchlist: a film could only be starred, and "Next Up" was structurally series-only. A bookmark beside the star on a film's detail page now adds it to Next Up, which appears as a labelled section on the Films personal row alongside Continue Watching and Favourites (with matching sidebar and Home Next Up entries). A hold on the personal row removes the film from whichever of those lists it is actually in, and the watchlist travels in backups.
  • Next Up no longer repeats a show that is already in Continue Watching. A half-watched episode is a Continue Watching entry; offering the same show's next episode on Next Up as well put one title in two rows that mean opposite things. Next Up now drops any show with an in-progress episode in Continue Watching, on both the Series tab and Home, matching across provider ids and title spellings.
  • Continue Watching and Next Up tiles open the show, with the show's poster. An episode tile whose series sat outside the bounded preview set - a media server's Next Up entry for a show no shelf happened to list, or a completed trail that never entered it - was left as a bare episode: episode still, a label with no show name the resolver could match, and a click that direct-played that one episode. Decoration and the click path now resolve the parent from the catalogue database (once per show, cached with the catalogue and rebuilt when it lands), Jellyfin and Plex episode rows carry the show's own artwork, and Home's Next Up row goes through the same decoration as the Series tab. Both rows now land on the series page with its next episode cued instead of playing the tile outright.
  • A film can now be marked watched from its detail page. A green check beside Play uses the same watched mark as the poster tick and the episode rows. Pressing it marks the title seen - writing the shared title key read by every provider's copy and reporting it to Trakt, Simkl and any media server holding the film - and pressing it again un-marks it. The play label, Continue Watching and the poster behind the page follow immediately.
  • A fresh open shows "Loading…" again instead of a black screen. Clearing the startup row as soon as a usable cache existed left a cold start with nothing on screen while the catalogue was read (seconds on a TV stick), which read as a crash. The row now stays until the cached catalogue has actually painted, and a silently suppressed background refresh leaves it alone; once content is up, cached refreshes still narrate nothing.
  • Watched films now carry a green tick on their poster. The Films grid, its shelves, Home, Search and Discover all draw the same corner check when the title is already watched, matching the episode rows' watched mark. The tick is bind-time state, so the lightweight shelf refreshes rebind the rows after a watched toggle instead of leaving the old state on screen.
  • A refresh with a catalogue already cached imports silently. The "Importing…" card, the connecting status and the post-transfer "Loading…" row now appear only when there is nothing usable on screen yet. If a catalogue is already in memory, in Room or in the flat RAM cache - including after a provider edit or re-add, which skips the cached paint - the import stays in the background over the content the user can watch. Opening Films or Series during it still pulls that half forward; it just does not bring the card back.
  • An existing Films/Series cache can no longer crash the Series tab after a provider import. The 7.2 screen snapshot gained the grouped "For You" row, whose section model was not kept for Gson and did not invalidate the older snapshot shape. Reading such a cached section back could leave its item list null, and the shelf binder called isEmpty() on it - a crash on the first Series paint that a normal import was enough to trigger. The snapshot format is now versioned past that shape, the section model is kept alongside the other snapshot models, and both the cache loader and the shelf binder treat a missing section list as an empty group instead of dereferencing it. The cache is rebuilt once on the next launch.

Stability

  • Watched-state reads no longer wait behind a sync write. A Trakt/Simkl pull rewrites the watched-marks file while holding the store's lock, and the new poster ticks read a mark on every bind - scrolling during a sync could therefore stall each row behind a large disk write. The store now publishes an immutable snapshot for reads and only takes the write lock to load, mutate a copy and persist it; poster binding reads the published set without a lock.
  • A damaged Films/Series snapshot can no longer crash the first paint on a shelf field. Gson can leave ContentShelf.items, matchIds, channelIds, or a section's items null even though they are declared non-null. The shelf binder, the "See all" path, the shelf pin/hide actions and the snapshot validator now use safe accessors for those fields, and the validator rejects a snapshot with any incomplete shelf instead of letting it through to the binder.
  • A catalogue refresh during a VOD row build no longer turns a stale index into a crash. DbChannelList cached its row count but fetched rows live, so a provider import that removed or added rows made get(index) fall through to extras[index - storedCount] with a negative or out-of-range index. A missing row now re-resolves the DB/extras boundary against the live count and falls back to a readable slot instead of throwing.
  • A missing DownloadManager or update-cursor column is now handled instead of throwing. Cursor.getColumnIndex can return -1; the Downloads status poll and the self-update checks now verify each index before reading and treat "unknown" as "not complete/failed" rather than passing -1 to getInt/getString.
  • Downloads now have a stable key even when the provider left the item id blank. A blank Channel.id made every such item collide in DownloadStore and handed Media3 an empty DownloadRequest id. The download path uses Channel.downloadId() - the id, or the URL as the existing app-wide fallback - and refuses an item with neither.

Installation

Download the APK below and install on your Android TV, Fire TV Stick, or phone.

Don't miss a new Lumora release

NewReleases is sending notifications on new releases.