Repository navigation
Fix/crashes history jackett - #1
Merged
Merged
Conversation
Crashes
- History tab: rebuilding the list freed the focused row (after leaving the
player, Remove or Clear) while borealis still pointed at it, both as the
current focus and in its focus stack. Rebuild now waits until the tab is
the top activity, parks the focus and hands it back to the same position.
The deferred rebuild no longer captures a raw `this`.
- Jackett tab: Retry / Configure Jackett freed themselves through refresh()
while focused. Focus is parked on the search bar first.
Jackett
- Every result was downloaded to one shared cache.bin_jackett.torrent, so
History resumed whichever torrent played last. Each link now gets its own
file under /jackett/ (FNV-1a of the link).
- Indexer links that redirect to a magnet: URI failed with "Protocol not
supported". New http::downloadTorrent() reads the Location header and
returns the magnet, which is then resolved and played (or saved).
- The search log line no longer includes the API key.
- JackettView was never freed (one leak per tab visit); the tab owns it now,
and async callbacks check the alive flag.
Engine
- Magnet metadata: when trackers returned peers but none served the
metadata, the fetch failed without asking the DHT ("peer 80/80 0%",
upstream issue #3). A DHT round with untried peers now follows.
- torrent_announce() stops the remaining announces once the peer list is
full instead of waiting for every slow tracker.
Other
- History: periodic saves run off the UI thread; find() returns a copy
instead of a pointer into the shared list; load() falls back to the .tmp
left by an interrupted save.
- Updater points at Langegen/NX-torrent-player (it would replace the fork
with an upstream build); the release-by-tag URL is configurable too.
- File pickers prefix the folder when two videos share a name (season
packs: "Season 1/E01.mkv" vs "Season 2/E01.mkv").
Builds clean; offline pctest cases pass. Not yet tested on a console.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… cleanup CI - .github/workflows/build.yml: offline engine tests, then the .nro in the devkitpro/devkita64 image, on every pull request. A vX.Y.Z tag also opens a draft release with the .nro attached; publishing stays manual because the in-app updater offers the latest published release to everyone. The tag must match VERSION_* in CMakeLists.txt, or a build would keep offering itself as an update (or never update again). - Version bumped to 0.5.1. Tests - pctest/test_suite.c no longer touches the network: udp_announce() and dht_find_peers() are mocked at link time, and a mock peer on loopback serves the metadata over BEP 10/9, so peer.c runs as on the console. Six tests, including the DHT round after stale tracker peers (upstream #3) and the announce stopping once the peer list is full. Disabling the DHT fallback makes test 5 fail. - pctest/run_tests.sh builds and runs them (gcc + libcurl only). App / engine - Jackett: the per-link .torrent files under /jackett/ are pruned at startup when no history entry points at them; nothing else ever removed them. - Default trackers: dropped openbittorrent, exodus.desync, explodie and moeking (gone from ngosang/trackerslist), added open.tracker.cl. The engine's list and the two magnet lists in the app now match. - History dates: no change needed. libnx sets TZ from the console's time zone at startup, so localtime() is local; noted where the date is formatted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ussian UI Direct links - Stremio streams that are plain http(s) URLs (debrid and the like) now play instead of being marked "unsupported". - The Switch's FFmpeg is built without the https protocol (only http, tls, tcp, ...), so mpv opens http:// and HLS over it itself, and an https:// URL is played as nxhttps:// through engine/httpsrc.c: curl with the app's CA bundle, 4 MiB Range requests, redirect shortcut, retries, cancel. - Player: a no-engine path (loading screen, open errors shown with their reason, ZR panel, watch-state sync); buffering and seeking already went through mpv. HLS over https is not supported yet. TorrServer (Options -> Network) - With a server address set, magnets, .torrent files from the SD card (turned into a magnet) and Jackett results are streamed by TorrServer and played as HTTP. Without a file index the server's file list picks the largest video. History keeps the torrent as the source. Proxy (Options -> Network) - HTTP or SOCKS proxy for the app's requests and https playback; hosts on the local network (RFC 1918, .local, bare names) always go direct. FFmpeg's http:// path takes an http proxy only. Russian UI - app/i18n_ru.cpp: all 332 strings (every tr() literal, the language and colour labels, engine errors). Space Grotesk has no Cyrillic, so in Russian the UI uses the system font throughout: new borealis local patch SwitchFontLoader::useBundledFont (VENDORED.md). Tests - pctest/test_httpsrc.c: range reads against a mock HTTP server (chunk boundaries, seeks, no-range servers, redirect, retry, cancel). - pctest/test_net.cpp: TorrServer URLs and file choice, local-host bypass. - 17 offline tests in all; run_tests.sh builds the three suites. Also: http::get takes a timeout; http.hpp includes <cstdint>; CLAUDE.md notes the missing https protocol and the font constraint. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ck-ups Home tab (app/home.cpp), first in the header and the default on startup - A hero banner for the top trending title: backdrop darkened from the left, title, meta line, synopsis, "Watch" and "Details". - "Continue watching" from the local history as 16:9 cards with progress. - Poster rows: popular now, popular films / shows, in cinemas, top rated films / shows; each row loads on its own. - "-" searches TMDB (films and shows on a results page). - Without a TMDB key: a note on where to get and enter one. Title card (app/card.cpp) - Full-screen backdrop shaded left and bottom, poster, title, chips (TMDB rating, year, genres, runtime or seasons/episodes), synopsis, cast, "Watch" and "Torrents"; for a series a season switcher (buttons and L/R, focus parked before the strip is rebuilt) and the season's episodes. - Opens at once from the list data, fills in from the details. - Sources: the Stremio addons by IMDb id when signed in (existing film and episode screens), otherwise a Jackett search by title (+ year / SxxEyy). TMDB client (app/tmdb.cpp, app/content.hpp) - Trending, popular, top rated, now playing, multi search, details with external_ids and credits, seasons; in the UI language. - v3 key or v4 token, from Options -> Network or the build (-DTMDB_API_KEY, CI secret TMDB_API_KEY); the API address can be a mirror; goes through the proxy. - Answers cached on the SD card (lists 6 h, details 3 days); offline, any cached copy is used. - json::topLevel / json::object: TMDB nests "name" (created_by, genres, crew) ahead of the title's own. Shared widgets (app/widgets.*) - FadeStrip and TopRoundedImage moved out of stremio.cpp unchanged; new shade box, poster and wide cards, chips, action buttons. - Jackett: openJackettSearch() opens the search screen on a query. - Poster memory: borealis' refcounted LRU texture cache already bounds it; rows use TMDB's w185 posters. Also: Russian strings for all of it; Options -> Network -> TMDB (key, address, test, clear cache); pctest/test_tmdb.cpp (6 tests on trimmed real answers, 23 offline tests in all). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uild Sources screen (roadmap phase 3: app/sources.cpp, app/release.cpp) - A film's or an episode's releases from Jackett (localized and original title, the year for a film) and the Stremio account's stream addons (by IMDb id), deduplicated, in one list. - Release names parsed into quality, source, codec, HDR / Dolby Vision, 10-bit, voice-overs (dub, MVO, DVO, AVO, studios), group, and the seasons / episodes held (S01E06, 1x06, "Сезон: 1, Серии: 1-8 из 8", ...). Other seasons / episodes and cam rips are hidden; the rest ranked for a Switch (1080p H.264 over 4K HEVC HDR and remuxes, seeds, size); "best choice". - Filters: quality, voice-over, source, picture (HDR), tracker; X cycles the order. - A season pack opens on the episode's file (release::matchEpisode); the voice and group picked for a show rank first next time. - app/torrent_play.cpp: the Jackett tab's play flow, shared and extended with the episode match, artwork and watch context. Library (roadmap phase 4: app/library.cpp, app/bookmarks.cpp) - Bookmarks: Watching / Planned / Completed / Dropped, from the card or Y on a poster; a Bookmarks tab; export / import of library-export.json. - Progress per film and per episode in library.json, tied to the title, not the file. "Continue watching" on Home resumes in one press (X removes); the card's main button says "Continue S1 E5" / "Watch S1 E6". - "Next episode" at the end of an episode works without Stremio: from the same season pack when the last one came from it, else its sources. Catalog - Layout after the roadmap mock-ups: header Home / Movies / Shows / Bookmarks / History, Stremio / Local / Jackett behind one "Sources" button, "Search" on the right; compact hero; pill buttons; smaller cards; A "Open", Y bookmark, X remove hints. The L/R "View" keys exist only on Stremio's tab. - Collections: every row's heading and its "See all" tile open a paged grid (app/collection.cpp). - Search screen (app/search.cpp): search bar, kind / genre / year / order filters, genre tiles; TMDB discover without text, search with it. - IMDb rating (from Cinemeta) on the card and the hero. - borealis' footer words in the app's language: Platform::APP_LOCALE_DEFAULT, plus i18n/ru|fr/hints.json (upstream only had an unread brls.json). PC build (for checking the UI without a console) - build-pc.bat / run-pc.bat, compat/ headers, CMake and source guards for a desktop (MinGW) build with libmpv from pc_deps/. Tests: pctest/test_release.cpp, test_library.cpp, TMDB queries; 34 offline tests in all. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Card: a "More like this" row of TMDB recommendations under the seasons (fetched with the details, no extra request; A opens that card, Y bookmarks). The poster with those two actions is shared now (catalogPoster) by the home rows, collections and the card. - Player: when the history has a file as finished but the Stremio account has a position, ask "Resume playback?" with it instead of seeking there silently; with nothing to offer, start from the beginning. - Translated: the loading screen's metadata / peers / pieces / speed line, the "unsupported" and "link" source labels. The ZR panel stays English on purpose (it is diagnostics for bug reports). - The "no sources" hint names Jackett first. - Version 0.6.0. Tests: a film's recommendations parsed without leaking into its own fields. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Jackett is the app's main source, but the sources screen waited for every
request -- each Stremio addon included -- before it listed anything, so one
slow addon held back results Jackett had already returned.
- The list is built as soon as all Jackett queries are in; the addons' results
are folded in as each one answers ("searching addons..." in the subtitle
meanwhile). Without Jackett it waits for the addons, as before.
- A rebuild keeps the focus on the same release (by its dedup key) instead of
dropping it on the filter row -- X on a row no longer loses the place either.
- Results that land while the player or a dialog is on top wait until the
screen is on top again: freeing the row that opened it would leave a
dangling pointer in borealis' focus stack (the History crash).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Setup (app/setup.cpp) - On a start with no Jackett address, once: a screen with the server URL, the API key and "Check and save", which also counts the indexers; "Skip" or B is an answer too (config.json: jackettSetupAsked). Later changes are in Options -> Jackett as before. TMDB (the key ships in the build) and the proxy (optional) are not asked. Errors (app/jackett_diag.cpp, pure, tested) - curl's and Jackett's failures sorted into what to do about them: a bad URL, a name that does not resolve, nothing listening (Jackett not running, wrong port / network), a timeout, a certificate, a rejected API key (401 / 403 / "Invalid API key"), something that is not Jackett's API (a login page, a 404), no indexers, every indexer failing. Each is one sentence with the next step, in the UI language; the sources screen, the Jackett tab and the connection test all show it. - The connection test now reports "Jackett works. Indexers: N" and how many failed, instead of a bare "Connection successful!". - A typed address is made usable: "192.168.1.5" becomes http://192.168.1.5:9117; spaces and a trailing "/" go. - http::get can report the HTTP status (optional argument). Tests: pctest/test_jackett.cpp (4 groups); 7 offline suites in all. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A scripted run of the PC build (app/autotest.cpp, NX_AUTOTEST=script):
the app presses buttons, opens screens, plays a link and saves screenshots
and view-tree dumps itself; input goes straight into borealis, never through
the desktop. A frame-end hook in borealis (VENDORED.md #7) is where the
frame is read back. Not compiled for the console.
What it found, fixed
- Sources: a search for a show also finds other titles ("Fallout" ->
Mission.Impossible.Fallout.2018 ranked "best choice"). release::titleMatches
(the name or one of its " / " parts starts with the local or original
title) and release::yearsIn hide other titles, a film's other years and,
for a show, same-named films from before it began -- only once some
release does match, so an odd spelling never empties the list.
- Ranking: "H 264" / "x 265" with spaces read as codecs; Ukrainian-only
audio ranks below the rest in a Russian UI. The first listing puts the
focus on the best choice, so A plays it.
- Sizes over 2 GB wrapped (json::integer was `long`, 32-bit on Windows) and
went missing: 64-bit now.
- Selected pills (quality filters, seasons, search filters) never showed
as selected: setPillActive painted over the accent.
- Card: the title from TMDB's details (it kept whatever opened it); poster
and backdrop filled in when the opener had none; when the details fail,
say so and let Watch / Torrents search by title (it said "Still loading"
forever); L/R season hints only for a show.
- Focus: empty strips no longer take it (a 0x0 frame held it on the card);
a collection opens with the first poster focused; a genre tile in search
hands it to the first result.
- No empty title bar over the card, sources, collection and setup screens;
Options values and list pickers in the accent instead of borealis' cyan;
accent text readable on the dark field (accentText).
- Sources menu: Jackett first, nothing marked when none is open.
- Jacred mirrors (ru.jac.black): no "Indexers" list is a working server,
not "no indexers"; a typed public name keeps port 80; nginx's own 403 is
"the server refused", not "wrong key". The setup says Jacred works too.
- TMDB: one retry on a failed request.
- Engine errors translated in the metadata dialog; more of them in ru.
Anime
- "Anime" in the header next to Movies and Shows: popular / new / top
anime series, anime films, and genre rows (TMDB discover: animation,
original language ja).
- Search: Movies / Shows / Anime; anime text search keeps anime results only.
Tests: release title matching, years, codecs, language order; json 64-bit
sizes; Jacred answers. 7 offline suites pass; .nro and PC build clean.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- app/workers.cpp: four threads for the network, High before Low priority.
brls::async ran every task on one thread with a half-second nap between
batches: a card's details waited behind the home screen's posters, and the
two Jackett queries of a sources search ran one after the other. TMDB,
Jackett, TorrServer, magnet metadata and the Stremio reads are on it now;
images go Low; history / library writes and Stremio pushes stay ordered on
brls::async. The same poster asked for twice downloads once, and every
cache file is written whole and then renamed.
- Release sizes: checked against ru.jac.black's own sizeName -- right after
the 64-bit json fix (5.3 GB had shown as 922 MB, 2-4 GB as nothing).
Shown with a decimal under 100 GB and in the UI language ("14.3 ГБ").
- Ranking: seeders count up to ~30 (they stopped at ~13: 19 seeds ranked
like 286).
- History: the source badge in the UI language.
- autotest: the D-pad itself (DLEFT/DRIGHT...), for the player's seek.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ui::paintField / ui::FieldFrame: the Stremio tab's gradient (the accent's tint at the top right to black, or to white in the light theme) behind every tab and screen -- home, catalog, search, sources, collections, setup, Options -- instead of borealis' flat grey. The strips' edge fades already blended into this gradient (tabBgAt) and now match it. - Card: the backdrop and its shades run on under the footer, no grey bar (dark theme; the light one keeps its light footer for the dark hints). - Light theme: buttons on artwork keep white text and their fill (setTextColor resets the fill, so it goes first); success text and "best choice" in a green that reads on white (theme::textGood); the Options sidebar a veil over the field. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Settings: the Jackett, TorrServer, TMDB and update-check buttons are relabelled from a background answer that can come half a minute later; switching the Options sidebar meanwhile freed the button first. They check an alive flag now (AsyncButton). - Watch on a card: without a Stremio account the IMDb id is not needed (Jackett searches by title), so the sources open straight away instead of after the details request. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Torrents" on a show's card opens the season's releases with no episode. Picking a file from a pack there recorded the progress against the show as if it were a film: no episode marked watched, no "next episode". - release::episodeOfFile: which episode a torrent file is, by its name or folders (S01E06, "Сезон 1/Серия 2", "10. ..."), the pack's season when the name gives none. Tested. - The file picker uses it for a catalog show: the player gets that episode's watch context (sources' episodeHint), so progress, the episode mark, Continue and "next episode" follow. - The picker stays under the player: the next episode closes it too. - Version 0.6.1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.