github disclosurez/Lumora v6.2
Lumora v6.2

3 hours ago

Lumora v6.2

Catalogue

  • Six-figure providers no longer run the app out of memory. The merged catalogue used to be one resident Channel list - a 300k-item Xtream panel measured ~260 MB, plus a copy during the merge and another while the disk cache was parsed, which killed a TV stick as soon as the provider finished loading. Films and series now live in the Room catalogue (catalog_channels) and are read back as capped poster shelves and 120-card grid pages; only the live list stays resident (~40 MB for 55k channels). Search, detail, version chips, Continue Watching, Trakt/Simkl matching and Discover ownership query the database instead of scanning a list.
  • The first films/series build is a database pass, not a parse. Category rows come from the existing grouping pipeline fed by a keyset-paged cursor; one card per title is picked in SQL (MAX(rank) per duplicate group: own library, then quality, then poster, then provider order), and backup copies sort behind visible ones without leaving the group.
  • A failed refresh no longer destroys the catalogue or postpones the retry. Each ingest writes under a generation token and only deletes the rows it did not see once the fetch completes; a dead provider leaves the previous rows in place, and a failed live fetch keeps the live list already on screen. A load where no source answered no longer stamps the refresh time, and a VOD-only panel (no live channels) stamps it on success instead of refetching its whole catalogue every launch. Provider removal, content-type switches and backup demotion update the database explicitly.
  • The catalogue has its own database file. lumora.db stays the small user-data database (guide, recordings, watch history) and remains eligible for Auto Backup. The rebuildable catalogue - whose stream URLs carry the panel credentials iptv_prefs.xml is excluded for, and which can exceed Auto Backup's 25 MB per-app quota - lives in lumora_catalog.db and is excluded from Auto Backup and device transfer.
  • The old channel cache file is gone. channels_cache.txt / channels_cache_v2.txt are never read again and are deleted on the first load; the one-time refetch after updating replaces them with the database.
  • A cold start paints what is stored, however old it is, and refreshes behind it. The live table is read as soon as the Activity exists so the query and Channel mapping overlap with layout inflation, the storage-invariant prune runs after the first paint instead of before it, and a background refresh no longer re-derives the live grouping and rebuilds the sidebar for every provider that answers - it swaps in once when the whole load is done. A 16k-channel panel went from 5.7 s (11.8 s whenever a cache missed) to ~4 s, and a catalogue past its 24 h TTL opens just as fast: the stored one is on screen while the fetch runs, and only a load where at least one source answered stamps the TTL.
  • The derived cache is actually hit now. The live grouping key hashed the whole resident list, so the anime catalogue appended after the first paint (it rides along as SERIES) gave the same output a second key and overwrote the entry the next cold start needed; sidebar rows built with anime sections did the same to the row cache. The live key now covers only the LIVE rows that pass consumes, and rows built for a plugin-supplied list get their own cache slot, so both variants stay warm. A miss is no longer silent: LumoraPerf logs the stored key beside the computed one.
  • Adding a provider says how big it is, and shows its progress. A banner floats over the app while a catalogue streams in - provider, phase, items and megabytes, with a progress bar - so a six-figure panel is a visible wait instead of a blank screen. Past 50 MB the app says so plainly ("this playlist is extremely large - ask your provider to disable content you do not need"), the size is remembered on the provider (Settings shows "147 MB · very large"), and the end-of-load summary repeats it. The banner carries a Hide button, and the warning line keeps saying what is importing and how far it has got. The banner is deliberately not the status row: that one only owns the screen when nothing else does, which is exactly not the case when a provider is added over a catalogue that is already up.
  • Films and Series open without waiting for each other. The VOD pass used to build Films, then Series, then hand both back - so opening Series after any catalogue change waited for the entire Films build first (29k films measured 23 s before Series even started). It now builds the tab you are looking at first, publishes each tab the moment its category rows are ready, and fills that tab's poster shelves afterwards, so the sidebar and the tab itself appear while the rest is still building. A tab switch no longer blocks behind the other tab either.
  • The previous VOD content stays on screen while a new one builds. The cache is now stale-while-revalidate: a catalogue change or a shaping pref invalidates the key, but the old content is painted first and the rebuild replaces it when it lands, instead of blanking Films and Series for the length of the pass.
  • An import writes in bigger batches and counts rows as they arrive. The catalogue writer commits 2,000 rows per transaction instead of 500 (the table's fifteen indexes make the commit the expensive part: a 300k-item panel used to pay for 600 of them), and the banner's item count now tracks rows received rather than rows a batch happened to commit, so it no longer steps by 500. The catalogue database also opens in WAL mode explicitly, so the UI's reads stay on their own snapshot while an ingest writes.
  • Switching a provider off keeps its catalogue, and switching it back on reuses it. Disabling a provider used to delete its rows, so re-enabling it downloaded the entire catalogue again even minutes later. The rows are parked instead - hidden from every VOD read by a rank sentinel and from the live list by the enabled-source filter - and put back in place when the provider is switched back on, with no network call at all. Only a source with nothing stored is fetched, and that fetch is scoped to it alone.
  • Switching one provider back on no longer rescans the others. Enabling a provider (or flipping one of its TV/Movies/Series gates) called a full catalogue refresh, so an IPTV panel that had nothing to do with the toggle was downloaded again from scratch. The load now takes the source ids it is meant to fetch: only that provider is contacted, and every other source keeps the rows and resident live channels it already had.
  • Removing a provider no longer re-scans the others. Deleting one source forced a full refresh, so the remaining providers' entire catalogues were downloaded again - minutes of scanning and a fresh ingest banner for a removal that touched none of them. A removal now takes the same local path as switching a provider off: its rows leave the database, the resident live list and any playback/preview/Multiview pane from it are torn down, and the screen repaints from what is stored.
  • The stored catalogue is never wiped wholesale. Pruning used to delete every row when no source was enabled - which is what a momentary empty provider list, or switching the last provider off, turned into: a full re-download of everything. An empty keep-list now deletes nothing, and removal still deletes explicitly.
  • Switching a provider off stops what it was playing. A disabled provider's stream URL keeps working - the panel does not revoke it - so the channel on screen, the Live preview and every Multiview pane carried on playing from a source Settings said was off. They are now taken down with it.

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.