Repository navigation
Part 1 engine browsing UI - #8
morpheasgr wants to merge 51 commits into
Conversation
Browsing:
- Add shared listing parser (sites/listing.rs) that merges every anchor
linking to the same video, so titles come from title/aria-label/alt
instead of quality badges ("1080p"), noscript markup or nothing.
Fixes XVIDEOS/xHamster titles and XNXX/YouPorn cards being dropped.
- RedGifs: browse via the v2 API with a cached temporary token (the
site is a JS app, so HTML scraping never returned results); gif
lookups are now authenticated and return direct MP4 URLs.
- ThisVid: scrape search/tag listings directly (yt-dlp has no search
extractor for it).
- Chaturbate: use the username as the card title and strip tag markup
from room subjects.
- Surface yt-dlp browse errors and Reddit login requirement instead of
silently returning empty pages.
Cookies:
- New in-app login browser (cookie_login.rs): desktop opens a separate
webview window and reads cookies via cookies_for_url; Android uses a
new CookieBrowserPlugin Kotlin overlay (full-screen WebView +
CookieManager). Captured cookies (incl. HttpOnly) are saved as
Netscape through the existing vault path.
- "Log in with browser" button in Settings -> Cookies and on
cookie-required site pages; cookie site picker lists all sites.
- Vault: treat #HttpOnly_ lines as cookies, not comments.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The APK stored .so files uncompressed with extractNativeLibs=false (AGP default), so YoutubeDL.init / FFmpeg.init could not unpack libpython.zip.so / libffmpeg.zip.so and every yt-dlp/ffmpeg call failed with "not initialized". - patch-android-ytdlp (.ps1/.sh): set jniLibs.useLegacyPackaging = true - validate-android-build: fail when it is missing - YtDlpPlugin: include the init exception in "not initialized" errors - Settings hint + mobile-android troubleshooting entry Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n init With native libs now extracted, YoutubeDL.init / FFmpeg.init get past the early failure and run commons-compress / commons-io / Jackson code that R8 had renamed in release builds, crashing the app at launch. - proguard overlay + patch scripts: keep org.apache.commons.compress, org.apache.commons.io and com.fasterxml.jackson (added to existing projects too) - YtDlpPlugin: catch Throwable (LinkageError etc.) and give the plugin scope a CoroutineExceptionHandler so init failures are reported instead of killing the process Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Backend
- BrowseQuery.filters (sort / period / duration / quality option ids)
threaded through the browse command, LAN API query params and the
browse cache key; SiteInfo.browse_options advertises what each site
supports. Unknown ids are dropped before they reach a URL.
- SiteAdapter::browse_options / list_categories, list_site_categories
command + GET /api/sites/{id}/categories (6 h in-memory cache).
- Shared category-index parser (sites/listing.rs) and with_query helper.
- Per-site support, verified against live filter menus:
PornHub (o/t/min_duration/max_duration/hd), XVIDEOS (sort/datef/durf/
quality), XNXX (path segments), xHamster (search query params,
category path sorts), YouPorn (/search/<sort>/), Eporner (API order),
ThotHub/ThisVid (KVS sort_by), Reddit (hot/new/top/rising + t),
RedGifs (order). Categories for PornHub, XVIDEOS, XNXX, xHamster,
YouPorn, Eporner, ThisVid and Chaturbate (top hashtags).
- Fixes: ThotHub page 2+ repeated page 1 (from_videos / from paging),
XNXX pages were off by one, xHamster category paging, PornHub
category names were scraped as video counts (now parsed from the
embedded JSON catalog).
Frontend
- BrowseFilterBar: site sort/filter selects (reload from page 1) plus
on-device text (-exclude) and length filters over loaded results.
- SiteCategoryBrowser on site hubs; useSiteInfo hook for live options.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The site hub (/browse/$site) holding the category browser had no entry point. Selecting a site chip now shows a "<Site> categories" button. siteHasCategories() falls back to a static id list when the backend site list (with browse_options) is unavailable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
R8 stripped YtDlpPlugin$Args / $MediaArgs / $KeepAliveArgs / $ResumeArgs to empty shells (no fields, no constructors), so Tauri's Jackson parseArgs failed with "Cannot construct instance of YtDlpPlugin$Args (no Creators ...)" and every on-device download and stream resolve broke. Keep com.archhive.app.**Args, and add the rule to already-patched projects in patch-android-ytdlp.ps1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- PornHub retired /categories/<slug> (404 -> "browse failed"). Resolve slugs to numeric c= ids from the live catalog (straight / gay / lesbian, 12 h cache; gay slugs carry a -gay suffix) and fall back to search. Trans uses the main index: /transgender/video* now 404s. - PornHub listings scope to the result grid (#videoSearchResult, #videoCategory, ul.search-video-thumbs) so header "hottest" / recommended dropdowns no longer lead results; skip playlist "Play All" links (pkey=). - PornhubCategoryBrowser is now a picker: a category opens the browse page (sort / filters / infinite scroll) with ?orientation= in the URL; the browse cache key includes orientation. - Browse page loads page 1 on open instead of waiting for "Browse". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Phones never host LAN: ensure_lan_server / regenerate_lan_server refuse on mobile (they would bind 0.0.0.0). The on-device loopback server reports "loopback": true / "lan": false in /api/health and no longer advertises the phone's Wi-Fi IP; the status chip says "(on-device)" instead of "(open)". - sites::throttle: >=1 s between requests to the same host, and after a 429 a cooldown (Retry-After or 60 s) that fails fast with a clear "rate limiting" error instead of hammering the site. - Trending: 10-minute session cache shared by /browse and /feed with in-flight de-duplication (Feed scraped every trending site twice per visit); pull-to-refresh clears it. - PornHub playback tries yt-dlp first (what works for downloads on-device), then the page extractor on mobile; both via the Referer loopback proxy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- IdentifyDialog / EnrichDialog / performer StashDB actions showed a generic "Query failed": Tauri rejects with a string, not an Error, so the backend message was dropped. Fall back to String(e). - StashDB answers a missing/invalid ApiKey with HTTP 200 + GraphQL "not authorized", not 401; map it to a clear API-key message. - Select Scene.release_date (Scene.date is deprecated on StashDB) and retry with `date` on boxes that do not know release_date. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…essage Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- sceneMediaUrl / sceneThumbUrl / fileStreamUrl no longer require settings.lan_enabled on the phone: the 127.0.0.1 loopback server always runs there, but the flag can still read false while it starts (e.g. first launch after reinstall), leaving library files with no playable URL. - Scene player shows why playback failed (probes the stream: missing file, outside the library folder, server unreachable, unsupported format) with an "Open with system player" button, instead of a silent black box. - SceneContextMenu: bottom sheet on phones (large targets, padded above the system navigation bar); the desktop popup is clamped inside the window. "Open in Explorer" is hidden on phones. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fe rename - Release APKs shipped usesCleartextTraffic=false: patch-android-lan.ps1 tested for any "true" (only the debug build type sets it) instead of a remaining "false". The WebView could not reach the 127.0.0.1 media server, so library playback, thumbnails and the PornHub Referer proxy all failed. The validator now fails on a remaining "false". - "Open with default app" / "Open with system player" on Android go through a new YtDlpPlugin.openFile (ACTION_VIEW + FileProvider content:// URI); the opener plugin's open_path did nothing there. FileProvider roots overlay adds app-private dirs. - Rename file to match title: error when the file is missing, never overwrite an existing file, move the <stem>.jpg thumbnail sidecar too. - Library rename / regenerate thumbnail / open actions show their result or error as a toast instead of failing silently. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Tag/category indexes are no longer capped (XVIDEOS ~2,000 tags, XNXX 2,000, xHamster 655 were cut to the 300-400 most popular, hiding most rare / late-alphabet tags). - Combined tags: a Tag/Category slug of `a,b` intersects tags where the site supports it, verified live: XVIDEOS /tags/a+b (up to 5; tag pages ignore sort/filters, so filtered queries use the word search) and PornHub /video/incategories/a/b (exactly 2, straight only). Other sites and larger selections run as a word search; BrowseOptions.combine_tags advertises the exact limit. - Tag browser: A–Z / most-videos order and a Combine mode (select tags, "Browse N together"), also in the PornHub category picker. - Browse page: tag autocomplete from the site's tag index, and a note when a combination falls back to word search. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
XVIDEOS' /tags page only lists the overall top ~2,000 tags; the full
index is split by first character (/tags/09, /tags/a … /tags/z, up to
2,000 each, ~50k tags). BrowseOptions.category_groups exposes those
sections; SiteAdapter::list_category_group fetches one on demand, and
list_site_categories(site, group) caches it in memory (6 h) and on disk
(<data>/tag-index, 7 days).
- Tag browser: "Popular · 0-9 · A … Z" tabs.
- Browse page autocomplete loads only the group for the tag being typed
and suggests the 50 most-used prefix matches, including after a comma
for combined tags ("milf, zo" -> "milf,zombie-sex").
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
XVIDEOS has ~38 categories (/c/<Name>-<id>, listed on the home page) separate from its tags. They are now a "Categories" group in the tag browser. Category pages take sort / length / quality as path segments (/c/s:uploaddate/d:10-20min/q:hd/Femdom-235) and page as /<n-1>; the filter bar applies to them. Verified live that categories cannot be combined with tags or searches in one URL (c= and tag= are ignored, /c/X/tags/Y 404s), so Combine is hidden on the Categories tab and a combined category slug falls back to a word search on the names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Eporner's HTML listings take category filters in the URL, verified live: /tag/<query>/[<page>/][<sort>/]?include=a,b&exclude=c (page must come before the sort segment; the reverse redirects to page 1), also on /cat/<slug>/. The API used for plain browsing has no such filter, so requests with include/exclude use the HTML listing (new parser; slugs validated to [a-z0-9-]). - BrowseFilters gains include / exclude (comma-separated category slugs; part of the cache key and LAN query params); BrowseOptions.include_exclude advertises support. - Browse page: "Categories" panel for such sites — tap a category to require it, again to exclude, again to clear; taps are committed after a short pause so several taps trigger one reload. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/cats/ lists the 86 categories plus the top 500 tags; /cats/A/ … /cats/Z/
list 500 tags each (no further paging), almost none of them on /cats/.
They are now category groups ("Tags", A … Z) in the tag browser and feed
autocomplete; the main tab is labelled "Categories" for Eporner.
Tags open their exact /tag/<slug>/ page (HTML listing, with sort, paging
and category include/exclude) instead of an API word search. Tag slugs
are case-sensitive (czech-ouQ9EM84 works, lowercased 404s), so they are
not lowercased. Verified that ?include= only accepts categories, not tags.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The categories page only lists 655 categories and ~200 tags; its page
data links an A–Z tag index at /categories-0, /categories-a … -z (up to
2,000 tags each, no further paging), ~30k tags in total. These are now
category groups ("0-9", A … Z) in the tag browser and feed autocomplete.
Single tags open their /tags/<slug> listing (sort/HD as path segments
and /<page>, like categories) instead of a word search; combined tags
search with xHamster's own '+' form.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
XNXX tags are search terms (/tags/<t> redirects to /search/<t>), but it
has the same per-letter index as XVIDEOS (/tags/09, /tags/a … /tags/z,
up to 2,000 each). Added as category groups ("0-9", A … Z) with their
own parser; tag browsing keeps the hyphenated /search/<tag> form XNXX's
own tag links use (it ranks differently from /search/a+b).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/tag-combining.md records the live-verified URL schemes: XVIDEOS tag intersection (/tags/a+b, up to 5, no filters), PornHub two-category intersection (/video/incategories/a/b, straight only), Eporner search/tag + category include/exclude, and the sites that only support word search (xHamster, XNXX, others), with how the app maps each one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ThisVid: one category + one tag is a strict intersection (/categories/X/?tag=Y or /tags/Y/?category=X; verified on result pages), only one tag, search + category is not strict. YouPorn: no strict combination; porntags are search aliases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/categories/<c>/?tag=<t> is a strict category ∩ tag listing (verified on result pages); it pages and sorts. BrowseFilters.tag carries the tag (validated to [a-z0-9-]; part of the cache key and LAN params) and BrowseOptions.category_tag_filter enables a "Narrow by tag" box on category pages, with autocomplete from ThisVid's tag index (/tags/?section=a … z, now also A–Z tabs in its tag browser). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Checked against result videos' own tag lists: XVIDEOS tag pages are a keyword search over titles and tags. /tags/petite-brunette lists more videos than petite or brunette alone and none of the sampled results carried that tag; /tags/milf+anal and /tags/a+b+c results were missing tags. combine_tags is now 0 for XVIDEOS (combined tags run /?k=...), the /tags/a+b URL path is removed, and the docs are corrected. Also re-verified the remaining strict claims on result pages: PornHub /video/incategories/a/b (10/10) and Eporner include/exclude (13/13). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PornHub searches take one required category (filter_category=<id>) and up to 10 excluded ones (exclude_category=<id>-<id>, dash-separated as the site's own UI sends them); category listings take only the excludes. Verified strict on result video pages. BrowseOptions gains max_include / max_exclude / exclude_only_kinds so the Categories panel enforces the per-site limits; docs updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The picker showed a 55-entry built-in list unless "Refresh counts" was tapped; it now loads PornHub's live catalog per orientation (111 straight, 53 gay, 73 lesbian), cached for the session, with the built-in list only as an offline fallback. Trans has no index of its own (/transgender/categories is a 404) and trans categories used to open the straight /video?c= listing. The Trans tab now lists the straight catalog, each entry browsing <category> ∩ Transgender (/video/incategories/<x>/transgender), with "All trans" (c=83) on top. Gay pairs intersect too (/gay/video/incategories/a/b). Category pairs without a page (404) fall back to a word search. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The categories page also links 17 spoken-language listings (/language/<name>, same grid, paging and sort as categories). The picker's Straight tab shows them as a Languages row; `language-<name>` slugs browse /language/<name>. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Saved searches store the listing's sort / filters (new saved_searches.filters
JSON column, MIGRATION_020); checks run the saved listing instead of the
site defaults, and a filtered page is a different saved search from the
unfiltered one.
- Opening a saved search passes its orientation and filters (browse route
search params now carry the filter keys) and no longer pre-encodes the
slug, which double-encoded combined slugs ("milf,anal").
- Save / remove failures show a toast instead of failing silently; browse
errors show Tauri's string rejections instead of "Browse failed".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Replace <datalist> autocomplete (browse tag box, ThisVid "Narrow by tag") with SuggestInput: an in-page list anchored under the input, ~6 rows then scrolling, closed on pick / blur / Escape. Android WebView drew datalist as a native popup that could cover the screen and overlap the keyboard. - Replace the sideways-scrolling site chips and the separate site dropdown with SitePicker: one large button opening a grid of big site tiles (bottom sheet on phones, dialog on desktop) with search, Auto-detect and a "Needs cookies" hint. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bundle each site's best published icon (apple-touch / largest favicon, normalised to 128×128 PNG, 144 KB total) in public/site-icons and show it in the site picker. ThotHub and ThisVid only publish 16–32px icons, so they and plugin sites keep the coloured initial badge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Phones (<768px): one-row header (back, site icon + name, kind, save), full-width search, and a Filters button with an active-filter count and summary chips. Orientation, sort/date/length/quality, the text filter, category include/exclude, tag narrowing and "hide watched" (now a switch) move into a bottom sheet. Desktop keeps the controls inline. - Results use two columns on phones with larger thumbnails; Info/Download become small icon buttons on the thumbnail (SceneCard compactActions) instead of a full-width button row, and the duration badge sits in the corner. - Queuing a download shows a toast. - Extract BottomSheet (ui/bottom-sheet) and reuse it in SitePicker. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Categories (site hub): - Compact header (back, site icon, name); the "Advanced browse" and "Browse by" cards merge into one chip row. - SiteCategoryBrowser / PornhubCategoryBrowser drop the nested card and inner scroll box; sections become full-width tabs and the A–Z pages a letter grid instead of a sideways strip; PornHub rows are 48px tall with checkboxes in Combine mode. - Combine mode shows a floating CombineBar above the bottom navigation with the picks and "Browse", so it never scrolls out of reach. Library → Scenes: - Smaller header with icon buttons; search sits next to a Filters button that opens a "Sort & filter" sheet (sort, quick filters, duration/size) on phones; 2-column grid in portrait. Downloads: - Bulk import moves behind an "Add URLs" button (bottom sheet, opened automatically for shared links) on phones; bulk actions scroll in one row; rows show the site icon, a two-line title and a percentage next to a thicker progress bar, plus a swipe hint. "Clear completed" is renamed "Clear finished" (it also removes failed/cancelled jobs). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ource URLs - Fullscreen: Tauri's Android WebView (wry) cancels HTML5 fullscreen in onShowCustomView, so the native button never worked. New usePlayerFullscreen hook: HTML Fullscreen API where it works; in the Android app the player container covers the screen and a new setImmersive plugin command (set_player_fullscreen) hides the system bars and locks landscape for wide video. The back button / Escape exit. HlsVideoPlayer gets its own fullscreen button and hides the dead native one; ScenePlayerDialog's button and double-tap use the same hook. - YouPorn: stream URLs go through the loopback media proxy on the phone (site Referer + browser UA, like the downloader), as PornHub's already do. - Source URLs in the browse player and the browse Info dialog are links that open in the system browser; ExtLink only links http(s) URLs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Eporner's CDN redirects requests with a foreign Referer (the WebView's http://tauri.localhost/) to a placeholder clip ("only available on eporner.com", static.eporner.com/na.mp4). Stream URLs now go through the loopback media proxy with https://www.eporner.com/ as Referer (verified: real video instead of the 642 KB placeholder). - The proxy attached PornHub cookies for any Referer it didn't recognise; it now matches the Referer host exactly and attaches no cookies for unknown sites. Eporner added to the known sites. Unit-tested. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nails KVS get_file links only work inside the session that loaded the video page; from yt-dlp's session or the WebView they redirect to placeholder clips (ThisVid processing.mp4, ThotHub fu.mp4). - New extractors::thothub::resolve_kvs_stream: loads the page in a fresh cookie session (plus imported cookies), decodes the best get_file URL and follows it in that session to the signed CDN URL. Placeholders, bot-check pages (Cloudflare) and pages without a player now give specific errors instead of "could not extract". - ThisVid uses it (the CDN URL plays directly); ThotHub uses it and plays through the loopback proxy, since its mirror refuses the WebView Referer. - ThotHub listing thumbnails are hotlink-protected (403 unless the Referer is ThotHub): rewritten through the loopback proxy on the phone. - KVS quality pick: an unlabelled main video_url ranks as standard quality, so ThisVid no longer plays its 240p alternate. - Proxy cookie mapping knows thethothub.com and thisvid.com. Verified live: ThisVid resolves to the real CDN video; ThotHub stream and thumbnail return video/mp4 and image/jpeg through the proxy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
xHamster renders only the first ~7 result cards with <img> and duration markup; the rest are filled in client-side from the window.initials JSON, so most results had no thumbnail or duration. The tube parser now walks that JSON (any object with a /videos/ pageURL) and fills missing thumbnails, durations and titles by page URL. Verified live: search (pages 1 and 2), category and tag listings return 46/46 items with thumbnails and durations (was 7/46). Unit-tested. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
About half of ThotHub's results are private videos (<div class="item
private">): their pages have no player unless you are a logged-in member,
which looked like playback "working once and then failing". Listing cards
now get a 🔒 title prefix and a "private" tag ("-private" in Filter results
hides them), and the resolver reports "This is a private ThotHub video —
only logged-in members can watch it" instead of a generic failure.
Verified live: of 24 search results the 12 flagged private are exactly the
ones whose pages have no player; the public ones resolve and play.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uses ThotHub failed on the phone with a bare "error sending request for url". ThotHub (Cloudflare) publishes IPv6 addresses (ThisVid doesn't); networks that resolve but cannot route IPv6, or break HTTP/2, fail this way while browsers and yt-dlp fall back silently. - SiteContext::fetch_with_headers and the KVS resolver retry a transport failure (connect / timeout / request) once on a fallback client bound to IPv4 (0.0.0.0) and limited to HTTP/1.1; the KVS resolver then keeps using the client that worked for get_file. - AppError::Http now appends reqwest's source chain, e.g. "…: client error (Connect): tcp connect error: Connection refused", so reports say whether DNS, connect, TLS or a timeout failed. Unit-tested. Verified: the fallback client fetches thethothub.com over IPv4/HTTP/1.1; ThotHub and ThisVid still resolve through the backend. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The dashboard treated every phone without a Remote LAN host as "needs setup": it showed "Connect to your desktop ArcHive" and skipped loading scenes, downloads and stats entirely (all zeros), although phones run their own on-device engine by default. Setup is now only required in browser mode or when Remote LAN is selected without a host. The engine banner says "On-device engine" on phones instead of "Local desktop engine". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It read "Local (Desktop)" on Android although the engine runs on the phone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Standalone (YouTube + direct links only) predates the on-device yt-dlp engine and is a subset of Local now. It is no longer offered in Settings → Engine or the first-run wizard; saved "standalone" values migrate to "local" (settings store rehydration, device settings sync, and the mobile backend bootstrap). The enum value stays for old settings. - The Desktop settings tab (tray, hotkey, window behaviour) was gated on having a local backend, which phones have too; it now requires the desktop app shell (new RuntimeCapabilities.desktopShell). Unit-tested. - Wizard copy: Remote LAN no longer claims to be "best for phones". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ints on touch
- Saved searches overflowed the right edge on phones: grid items default
to their content width, so a long name plus the "checked …" date pushed
the auto-queue / check / delete buttons off-screen. Rows can now shrink
(min-w-0, grid-cols-1); the name truncates with the status on a second
line. Recent-search rows truncate long queries the same way.
- Recent searches get a "✕ Clear" button (same style as the filter bar's
Reset) that wipes the list.
- Keyboard-shortcut badges ("Ctrl 1" …) are hidden on touch-only devices
(pointer: coarse); phones in landscape get the desktop sidebar and
showed them.
Verified at 393×852 and 852×393 with touch emulation: no horizontal
overflow, no visible shortcut badges.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
yt-dlp -J returns no tags, models or channel for XVIDEOS / XNXX, fails on some PornHub pages and hands back a hotlink-protected ThotHub thumbnail. Read those pages directly (sites/details.rs), falling back to yt-dlp when nothing useful is found. The dialog now keeps the listing thumbnail, hides a broken image, shows string errors, and says when a site lists nothing; the LAN endpoint returns the error text instead of an empty 500. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two-column grid on phones with compact card actions, site tiles with icons, a search field with clear button, and a LIVE badge with viewer count on cam cards. Cards no longer repeat the title as the channel line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Switching to Downloads (or any tab) and back returned Browse to its start page. The shell now remembers each tab's last URL and scroll position for the session: a tab button, nav swipe or shortcut returns there (the browse results cache restores the loaded pages), tapping the active tab goes to its start page, and tapping it there scrolls to top. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
After a 429 the app refused every request to the host for the whole Retry-After (up to 15 minutes, or until restart) without asking the site again, so it kept saying "rate limited" while the site already worked in a browser. Now one probe request goes through every 15 seconds, a successful response ends the cooldown, Retry-After is capped at 5 minutes, and the message says the pause is ArcHive's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Sorry @morpheasgr, your pull request is larger than the review limit of 150,000 diff characters |
|
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (1 file)
Previous Review Summaries (2 snapshots, latest commit b45ef0b)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit b45ef0b)Status: No Issues Found | Recommendation: Merge Files Reviewed (27 files)
Previous review (commit 5602c4c)Status: No Issues Found | Recommendation: Merge Files Reviewed (changed files)
Reviewed by free · Input: 91.2K · Output: 4K · Cached: 568.2K |
|
If you decide to merge this I'll open a pull request for the part2 branch :) you can take a look at my fork. |
The web conflict editor kept only this branch's side of each conflict, which dropped main's new CookieHarvestPoll / TermuxStatus types (CI typecheck failure), its Termux and cookie-capture plugin registration and its ThotHub login-required handling. This restores main's side: - lib.rs registers both the cookie login and main's cookie harvest / Termux bridge plugins; types.ts has both sets of types. - ThotHub keeps the session-aware KVS resolver, now also reporting login-required pages, and falls back to yt-dlp on Android too (as main does) unless the page is gated, private or bot-checked. - docs keep both cookie flows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"No player on this page - the video may be private" contains the word private but is not a verdict; match the resolver's whole verdict phrases instead, so such pages still fall back to yt-dlp. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Developed and tested on an arm64 Android phone (release APK) and the desktop LAN backend.
About 3,000 of this diff's lines are line-ending churn (CRLF → LF) in
models.rs,migrations.rs,error.rsandsites/adapters/mod.rs; viewing the diff with whitespace hidden removes them.Engine: phones run their own engine
initializes in release APKs: native libs are extracted (
useLegacyPackaging), andcommons-compress, commons-io and Jackson are kept from R8. Init failures are reported instead
of crashing the app.
engine. Saved "standalone" settings migrate to Local (settings store, device sync, mobile
bootstrap); the enum value stays for old settings.
for a desktop host or shows all zeros without one. Remote LAN remains optional.
the on-device server is loopback-only and no longer advertises the phone's Wi-Fi IP. Library
playback uses that loopback server even while
lan_enabledstill reads false.(
RuntimeCapabilities.desktopShell), not on phones.Browsing
window.initials; RedGifs on the v2 API.xHamster, Eporner and ThisVid, plus the live PornHub category catalog (trans/gay pairs,
"Language in videos").
docs/tag-combining.mdrecords what each site really combines (verified live).
returns none.
Playback and network
per site.
out a blind cooldown.
Mobile UI
touch.
StashDB
Android build
Testing
cargo test --lib: 178 passedbun run lint,bun run format:check,tsc --noEmit: clean🤖 Generated with Claude Code