Commit graph

42 commits

Author SHA1 Message Date
KhooLy
28501ff31b Redesign Plugins screen to match Addons screen visuals, rename from Scraper Plugins
Scrapers are now grouped under their owning repository instead of two
separate flat lists, and the screen reuses AddonStoreScreen's visual
language (icon-circle back button, bordered repo cards, icon buttons)
instead of its own bespoke plain-text styling. Adds a refreshRepository
action reusing the existing re-fetch dispatch.
2026-07-20 03:15:39 +03:00
KhooLy
1e776bbb8a Add per-scraper settings UI backed by onSettings() JS export
Wire executePluginScraper's updated scraper_id/scraper_settings_json
params through FluxaCoreUniFfi and PluginRepositoryManager, add
getSettingsLayout() to fetch and parse a scraper's onSettings() field
layout into small UI models, and add a gear-icon-triggered bottom
sheet (PluginScraperSettingsSheet) rendering header/info/text/select/
toggle fields, matching Nuvio's real settings schema.
2026-07-20 02:54:53 +03:00
KhooLy
ec634a13ec Wire Nuvio-compatible plugin scraper runtime into Android app
Implements PluginHttpClient over OkHttp with SSRF guarding (PluginNetGuard),
wires the FetchPluginManifest effect, adds PluginRepositoryManager for
repository/scraper state, folds plugin-scraper streams into
StreamDiscoveryUseCase, and adds a Plugins settings screen.
2026-07-20 02:28:45 +03:00
KhooLy
f0cf10d757 Add an Upcoming home row split from Continue Watching (off by default)
New setting under Settings > Appearance > Home Screen: when enabled,
Continue Watching items whose next episode/season hasn't released yet
move into their own Upcoming row instead of sitting in Continue
Watching with nothing to resume.

Classification runs async per up-next series item (no active playback
progress): HomeContinueWatchingCoordinator resolves the specific
lastVideoId episode via the existing getSeasonEpisodes fetch, checks
its release date through the new isEpisodeReleased FFI call, and
caches the result by id:lastVideoId. Once known, it triggers a
dynamic-rows refresh so the split applies without blocking the
initial Home paint.

HomeCatalogFeedCoordinator/HomeDynamicRowsCoordinator partition the
Continue Watching list into continue_watching/upcoming HomeCategory
rows via the new isUpcoming lambda, gated by
UserProfile.upcomingRowEnabled (resolved through the Rust safe-prefs
struct like every other appearance toggle). HomeCategoryPolicy's
isContinueWatchingCategory()-gated behavior (card layout, action-row
treatment, title passthrough) now also covers the upcoming row so it
renders with the same horizontal episode-card treatment.
2026-07-20 00:06:38 +03:00
KhooLy
0e3d57b7a5 Add Liquid Glass appearance mode for the bottom navigation bar
New opt-in Appearance toggle (default off), mirroring how amoledMode
is wired through UserProfile and both settings data sources. Enabling
it swaps the nav bar's flat fill for a translucent frosted surface
with a soft top-light gradient and a hairline glass-edge border.
2026-07-19 18:59:54 +03:00
KhooLy
7ad3aa9fac Merge IntroDB/AniSkip toggles into one Skip Intro/Outro/Recap setting
Both sources fed the same skip-segments pipeline and were always
toggled together in practice, so collapse them into a single
useSkipSegments flag on SettingsPlaybackUiModel. Both the Android and
Apple settings data sources still write/read the two underlying
useIntroDb/useAniSkip flags in lockstep, so the merge stays UI-level
and existing profiles keep working.
2026-07-19 18:53:35 +03:00
KhooLy
944484323a Add settings toggle to disable Content Warnings overlay
Adds contentWarningsEnabled to the playback settings model, defaulting
to true, and gates both the parents-guide fetch and the overlay
display in PlayerScreen behind it.
2026-07-19 18:48:46 +03:00
KhooLy
35f9c67092 Reorganize Home/Detail appearance settings into drill-down sections
Home Screen and Detail Screen settings now split into dedicated
sub-pages (Hero Banner, Continue Watching, Navigation for Home;
Hero Banner, Episodes for Detail) instead of one long mixed page,
so a specific setting is reachable by name instead of scrolling.

Also removes the dead "Trailer on Hero" toggle in Detail Screen
settings, which persisted a value but was never read by any
consuming code — it just duplicated the real "Trailer on Detail
Hero" setting and caused exactly this kind of navigation confusion.
2026-07-19 15:58:20 +03:00
KhooLy
62d20e23c4 Refine mobile navigation and poster actions 2026-07-18 17:56:43 +03:00
KhooLy
909425202a Improve calendar library and catalog experiences 2026-07-18 16:52:38 +03:00
KhooLy
9a75c888f5 Add continue watching source preference and Nuvio account sync improvements
Adds a per-profile continue-watching source preference (Fluxa/Stremio/
Nuvio/Trakt/Simkl/AniList), a background worker to push playback
progress to Nuvio instead of pushing inline, dedup of mark-watched
pushes against already-watched episodes, and general Nuvio account
import/merge fixes.
2026-07-18 15:02:19 +03:00
KhooLy
b4751da22e Move adjust entry to category headers and keep subtitles visible while adjusting
The adjust entry no longer scrolls with the track lists: each category
header (column label in the two-column card, the tab row in portrait)
carries a small tune icon. Audio's icon opens the inline delay pill
directly; the subtitles icon opens the adjust panel.

The adjust panel now anchors to the top of the screen with a near-zero
scrim so the bottom-center subtitle area stays visible, and while a
slider is being dragged the whole card fades to 15% opacity. A sample
cue styled with the live text/background/outline opacity values renders
at the subtitle position whenever the panel is open, so there is always
something to judge adjustments against.
2026-07-17 17:36:23 +03:00
KhooLy
5b153bfd3b Declutter player settings sheets
The sheets opened with an all-caps title, an instruction sentence, a
panel spanning almost half the screen, and two-line rows where every
speed carried a redundant Slower/Faster label. Titles are now title
case (Audio, Subtitles, Playback speed), the instruction line is gone,
the landscape sheet narrows from 46% to 38% width capped at 400dp,
rows tighten to 46dp with single-line speed entries (only 1x keeps a
Normal label), and mono/stereo channel counts render as words instead
of 1.0/2.0.
2026-07-17 17:07:59 +03:00
KhooLy
bdc4ab6b9a Redesign player controls chrome and sidebar layout
Reworks the player overlay chrome, sidebar shell, settings and
source sidebars, mark-segment sidebar, and mobile dialogs, plus
new dimension/icon tokens and i18n strings for the redesign.
2026-07-17 16:03:54 +03:00
KhooLy
e773f3438b Redesign Settings navigation, IA, and visuals; fix Add-ons UX
Settings:
- Replace the single-level category state with a real back stack
  (lifted into FluxaAppState) so back navigation goes up one level
  instead of always jumping to the hub, with hardware back wired
  through MainActivity.
- Scroll position is now keyed per category instead of shared/leaking
  across pages, and nested pages show their own titles.
- Split Notifications and TMDB feature toggles out of Account into
  their own pages instead of an accordion and an overloaded
  TmdbAccountChanged action bundling unrelated fields.
- Downloads settings page no longer duplicates Library's live download
  list; it links out to it instead.
- Add a lightweight settings search (SettingsSearch.kt) over a static
  index of rows.
- TV renders Settings as a two-pane list-detail layout.
- Introduce SettingsGroupCard and restructure every settings page
  from a flat row list into grouped inset cards, restyle the search
  field and choice-picker dialog to match the app's black/white
  aesthetic instead of default Material styling, and merge the
  redundant avatar/account rows on the hub.
- Add-ons settings page now only launches the real add-ons screen
  directly (dropped the redundant "Manage Add-ons" middle page and
  the torrent preferences that lived there).

Add-ons store:
- Validate pasted manifest URLs by actually fetching them before
  installing, instead of accepting any string that pattern-matched
  as a manifest path; show an inline error on failure and a
  confirmation dialog on success.
- Replace the bare "+" icon button with a labeled Add button.

Also strips emoji baked into a few i18n strings (CloudStream repo/
plugin headers, premiere notification) per project convention.
2026-07-17 05:47:52 +03:00
KhooLy
fc6bc620b3 Move data/player/domain logic into commonMain KMP source sets
Sweeps addon repositories, watchlist/profile storage, Trakt/Nuvio
sync, discovery models, and player policy classes out of Android-only
packages into data/commonMain and player/commonMain, with thin
androidMain wrappers where platform APIs are still required.
2026-07-16 23:00:28 +03:00
KhooLy
bd780396d1 Complete shared KMP and CMP migration 2026-07-16 15:50:35 +03:00
KhooLy
658b3ce3e3 KMP/CMP migration: purge legacy Android screens, route TV through shared FluxaApp
Continue the shared CMP/KMP migration: remove the legacy app/ui/catalog
Screen.kt files now superseded by shared/commonMain equivalents (Detail,
Search, Settings, Login, Profile, Watchlist, AddonStore, and the full
legacy Tv* screen set), and thread a DeviceType through FluxaApp/
FluxaAppHost so Android TV routes Home/Search/Discover/Calendar/Library
through shared destinations instead of falling into the removed legacy
composables (which previously hit an unreachable error() case).

Adds TvCatalogHomeScreen wiring plus new TvSearchScreen/TvDiscoverScreen/
TvCalendarScreen/TvLibraryScreen as thin TV-safe wrappers around the
existing shared screens. Removes the orphaned shared player/PlayerScreen.kt,
which had no call sites since the player stays platform-native by design.
2026-07-16 01:17:27 +03:00
KhooLy
20476761a9 Migrate shared UI and Apple playback to KMP 2026-07-14 18:14:18 +03:00
KhooLy
cda0c17b0a Replace TorrServer namings with Native torrent engine 2026-07-14 16:57:20 +03:00
KhooLy
a9f6e65b36 Migrate shared Apple UI bridges to KMP 2026-07-14 16:55:16 +03:00
KhooLy
46323a5043 Add Home top bar with real content filter, notifications list screen
No logo/wordmark anywhere (per explicit direction) - just a
notification bell and the active profile's avatar top-right, with a
Home/Series/Movies tab row underneath.

The tabs aren't decorative: HomeViewModel already had a working
currentFilter/setFilter("all"/"movie"/"series") mechanism used
internally for billboard filtering, just never exposed through the
shared UI layer. Added CatalogAction.FilterChanged and
CatalogHomeDataSource.setFilter() to wire it through properly -
AndroidCatalogHomeDataSource now threads currentFilter into
orderHomeCategories() too, which already supported a filter param
that was previously always called with the "all" default.

Notification bell opens a new NotificationsScreen, modeled as an
overlay on FluxaAppState (same pattern as the Detail overlay - a
showNotifications flag, openNotifications()/closeNotifications(), no
new FluxaDestination so it doesn't leak into the enum-driven bottom
nav). It reuses CalendarUiState/CalendarDataSource directly - no new
data source - and groups the existing flat release list into Coming
Soon / New / Later sections using kotlinx-datetime (added as a new
shared dependency; date arithmetic on ISO date strings needs real
calendar math, not string comparison, and there's no JVM-only
java.time available in commonMain). Tapping a notification reuses the
existing CalendarAction.ItemSelected handling to open Detail.

Compile-verified on shared commonMain, iosMain, and both Android
flavors. Visual result and date-bucketing logic unverified against a
running app.
2026-07-14 14:54:39 +03:00
KhooLy
00172e9320 Redesign shared Detail screen to match streaming-app reference layouts
Full-bleed tall hero (poster/backdrop) with title, type eyebrow, and
metadata (age rating badge, year, season count or runtime) overlaid
directly on the image via a bottom gradient scrim, matching a
Netflix/HBO Max-style detail layout instead of the earlier flat
sectioned one.

Adds a proper close/back affordance and share icon to the shared
Detail screen for the first time - it previously had no way to
dismiss itself from within the UI. Threaded onBack through
FluxaApp/FluxaAppHost/AppRoutesHost: the in-Home overlay now clears
itself locally (FluxaAppState.clearDetail()), while the standalone
mobile route pops the nav stack via navigateBackSafely - reusing the
same mobileDetailScreen-null guard pattern already established for
onDetailNavigationEvent, so the overlay and route cases don't collide.

Play becomes Resume when there's saved progress (shows "Resume S1 E2"
using the resume episode's season/number when resolvable), with a
Restart button underneath that dispatches the new
DetailAction.Play(fromStart = true) to explicitly bypass resume -
DetailNavigationLogic.forPlay/forStream now take a fromStart flag
that forces progress to 0 regardless of saved position.

Extends DetailUiModel with castNames and ageRating (from MetaDetail,
already fetched, just not exposed to the shared UI model before) and
DetailEpisodeUiModel with runtimeLabel (from Video.episodeRuntime).

Compile-verified on shared commonMain, iosMain, and both Android
flavors. Visual result not verified against the reference images in a
running app - no way to render Compose UI in this environment.
2026-07-14 14:23:28 +03:00
KhooLy
909906fab3 Build real Stremio login for iOS Auth, Keychain-backed session storage
Fixes AppleAuthDataSource: continueWithNuvio/continueWithStremio/
continueWithoutAccount were incorrectly routed through Swift
notifications - Android handles all three as pure local UI-state
transitions (no network), so this matches that instead of adding
unnecessary indirection.

submit() for the Credentials stage now posts a real request that
FluxaAppleAuthStartup.swift picks up: FluxaAppleStremioAuthClient
mirrors StremioService.kt's api.strem.io/api/login and /api/register
endpoints via URLSession, and the resulting session (id/email/authKey)
is persisted through FluxaAppleAuthStore using the Keychain generic-
password API (kSecClassGenericPassword, accessible-after-first-unlock),
not UserDefaults - this is the first credential-bearing data iOS
persists, unlike the existing UserDefaults-backed local stores.

Nuvio login/import is out of scope here: Android's version pulls
profile/addons/library/progress/history/collections through
NuvioAccountImportCoordinator, which needs library and addon-store
integration iOS doesn't have yet. The Nuvio stage transition works
(continueWithNuvio), but submitting Nuvio credentials currently has no
Swift listener - same "reachable but inert" scope already established
for AddonStore.

The error-state message on failed Stremio login is a hardcoded English
string rather than routed through AppStrings, since calling Kotlin's
AppStrings.t() from pure Swift needs framework-export verification I
can't perform without Xcode.

Caveat: this Swift code (Keychain access, URLSession networking) is
unverified - no Xcode/macOS toolchain available in this environment.
Only the Kotlin side (AppleAuthDataSource, all Gradle targets) is
compile-checked. Needs a real Xcode build and device/simulator test
before shipping.
2026-07-14 13:56:30 +03:00
KhooLy
db10acd3b2 Route Screen.Detail through shared CMP Detail screen on Android mobile
Adds season/episode picker and sources list to the shared Detail
composable, switches FluxaAppState's selectedDetail to carry a
DetailRequestUiModel directly (instead of a full CatalogItemUiModel)
so the standalone Screen.Detail route can seed it without going
through a catalog item first, and threads a detailRequest +
onDetailNavigationEvent pair through FluxaAppHost.

AppRoutesHost now builds a DetailRequestUiModel from Screen.Detail and
hands the shared Detail screen's navigation decisions (play a
specific stream vs. go pick sources, based on cs3: id prefixes) back
to Screen.Player / Screen.Sources, reconstructing the full Stream
object via AndroidDetailDataSource.resolveStream() so headers/
subtitles aren't lost. TV still uses the legacy DetailRoute for now.
2026-07-14 13:06:39 +03:00
KhooLy
7b8a5c61bf Fix missing Discover catalogs and add dynamic content types (movie/series/anime)
Diagnosed against NuvioMobile's open-source discover implementation
(same addons, more catalogs visible there). Two real gaps:

1. buildDiscoverCatalogOptions() excluded any catalog requiring an
   extra parameter beyond genre. Nuvio's equivalent (supportsDiscover())
   explicitly whitelists "skip" (pagination) as never blocking a
   catalog even when required — Fluxa's filter didn't, silently
   dropping every catalog that declares skip as required, which is a
   common Stremio addon SDK convention. Added "skip" to the allowed set.

2. The Type filter (movie/series) was hardcoded in the shared Discover
   UI instead of derived from what addons actually expose. Nuvio builds
   its type list from distinct catalog types across installed addons,
   which is why "anime" shows up there. Added a new
   buildDiscoverContentTypes() helper (same extras filter, minus the
   "all"/type restriction), threaded contentTypes through the
   readDiscoverCatalogFilters effect, Rust's DiscoverState (new field,
   needed since the effect completion flows back through the engine's
   own state, not directly to Kotlin), HomeViewModel, and the shared
   DiscoverUiState/DiscoverScreen, with a movie/series fallback so the
   dropdown isn't empty before the first fetch completes.
2026-07-13 22:48:20 +03:00
KhooLy
a57e5f3312 Fix mobile shell reload storm and restore Discover's dropdown/grid/search UI
AppRoutesHost was mounting a fresh FluxaAppHost per Screen navigation,
so every tab switch among Home/Search/Discover/Calendar recreated
CatalogHomeStore and re-triggered CatalogAction.Refresh, which force-
reloads the whole Home catalog over the network regardless of which
tab was actually opened. Hoist the shared shell out of AnimatedContent
so it stays mounted across those four screens and only remounts when
leaving them entirely (Detail/Sources/Player/Settings/etc., same as
before).

Discover regressions from the last pass, now fixed to match native:
- Filter chips replaced with dropdown menus (DropdownMenu/MenuItem)
  matching native's Type/Catalog/Genre picker pattern.
- Grid restored to a fixed 3-column layout instead of adaptive sizing.
- Added the inline search box native's Explore screen has, reusing
  SearchResultRows/SearchResults (now internal, not private) so typing
  in Discover shows grouped search results instead of the filtered
  browse grid, same as native.
2026-07-13 21:12:10 +03:00
KhooLy
3dae079b3f Migrate mobile Search, Discover, and Calendar screens onto shared CMP UI
Wires Screen.Search/Explore/Calendar to FluxaAppHost on mobile, same
pattern as Home. TV keeps using the existing native screens untouched.

To preserve native feature parity in the shared UI:
- Search: per-addon grouped result rows (was a flat grid), a clear
  history action, and a query-specific "no results for X" message with
  a recent-history fallback, matching native's MobileSearchScreen.
- Discover: filter chips are now a scrollable LazyRow instead of a
  plain Row, avoiding the same overflow-wrap bug fixed on Home's row
  headers when there are many genre options.
- Calendar: added month navigation (prev/next + localized month
  title), day-grouped list headers via the existing cross-platform
  localizedShortMonthDay/localizedMonthTitle helpers, replacing the
  flat undated list.

Deliberately not replicated (documented simplification, not a bug):
native's Search and Explore screens each embed a blended search+browse
UX (explore filters shown pre-typing in Search; inline search box in
Explore). Shared keeps Search and Discover as clean separate screens
since both capabilities are still fully reachable via their own tabs.
Also skipped: Explore's list/grid view toggle, swipe-to-change-month
and the day-grid calendar view (list view covers the same data).
2026-07-13 21:02:25 +03:00
KhooLy
45c45b0ce6 Add Apple multiplatform foundation 2026-07-13 03:47:45 +03:00
KhooLy
a1ccbefc96 Add portable locale-aware calendar text formatting to :core
java.text.DateFormatSymbols/SimpleDateFormat are JVM-only, so the
calendar screens' weekday names, month titles, and short dates
couldn't move to KMP as-is. Adds an expect/actual trio in :core
(localizedShortWeekdayNames, localizedMonthTitle, localizedShortMonthDay)
— Android actual keeps the existing DateFormatSymbols/SimpleDateFormat
behavior, iOS actual uses NSDateFormatter/NSCalendar/NSLocale.

MobileCalendarDateUtils.kt's shortWeekdays/monthTitle/
formatCalendarListDate now delegate to these instead of doing the
java.text work directly — same signatures, so all 6 call sites
(TvCalendarScreen + 5 mobile calendar files) are untouched. This is
groundwork only: buildMonthCells/shiftMonth still use java.util.Calendar
and the calendar screens themselves aren't ported — that needs the
screens' JavaCalendar-typed state converted to kotlinx-datetime, a
separate, larger change.

Verified compiling for android, iosArm64, iosSimulatorArm64, and both
app product flavors still build.
2026-07-13 03:14:27 +03:00
KhooLy
b976f28fd1 Convert core module to Kotlin Multiplatform
Phase 0 of the iOS migration: core now targets android, iosArm64, and
iosSimulatorArm64 via a new fluxa.kmp.library convention plugin.
AppStrings and the TTL cache lose their JVM-only dependencies
(org.json, java.time, java.util.concurrent) in favor of
kotlinx-serialization, kotlinx-datetime, and small expect/actual
platform shims, with Locale-returning APIs kept as Android-only
extension functions since only Android UI consumes them today.
2026-07-13 02:30:20 +03:00
KhooLy
35c0c405ac Align mobile trailer and account sync flows 2026-07-12 02:47:24 +03:00
KhooLy
a1e5173a7a Add chapter-based skip toggle, JP audio preference, autoplay countdown, and auto-retry-next-source
- Use Chapters for Skipping: gates the existing chapter-derived skip
  segment fallback (already computed by deriveSkipSegmentsFromChapters)
  behind a new toggle instead of applying it unconditionally. Also
  brought TV's Skip Segments section up to parity with mobile (IntroDB +
  API key, AniSkip, chapter toggle, auto-skip), since TV was missing all
  but auto-skip.
- Japanese audio for anime: overrides the resolved preferred audio
  language to "ja" for anime-genre content when enabled, at the single
  entry point both audio and subtitle track resolution already share.
- Autoplay countdown: the next-episode card now counts down and fires
  automatically, instead of only advancing on click.
- Auto-retry next source: extends the existing Cloudstream-only
  auto-fallback-on-error path to also apply generally when enabled.
2026-07-10 02:43:32 +03:00
KhooLy
a98521bea1 Expose Stremio and Nuvio account entry points from Settings
Both onConnectStremio and MobileNuvioLoginView already existed but had no
UI trigger anywhere in Settings — onConnectStremio was a dead parameter
never invoked, and the Nuvio login view was only reachable from the
initial onboarding screen. Added a Stremio connection tile (TV + mobile)
and a Nuvio import row (mobile only, since TV's login screen has no
Nuvio path) that reuse the existing Screen.Login(startOnNuvio) navigation
already used by onboarding.
2026-07-10 02:29:17 +03:00
KhooLy
42422ea8a5 Add AniList account sync (OAuth2 connect/disconnect)
Mirrors the existing Trakt/MyAnimeList/Simkl connection pattern: a
fluxa://oauth/anilist deep link, authorize-URL launch, token exchange
through a new ExternalOAuthClient.exchangeAnilistCode call, and profile
fields (anilistAccessToken/RefreshToken/TokenExpiresAt) merged via the
existing authExchangeRequested headless effect. Adds a matching
AuthProvider::Anilist arm in fluxa_core's token_merge_plan_json so the
shared Rust merge path recognizes the new provider too.

Connect/disconnect tiles added to both TV and mobile Settings, folded
into the existing multi-provider "Disconnect" action.

Note: app/build.gradle.kts also carries a small pre-existing uncommitted
fix (rustCrateDir path) unrelated to this change, included here only
because it was already sitting in the working tree on the same file.
2026-07-10 02:23:39 +03:00
KhooLy
5a96828bed Add torrent speed/Wi-Fi-only settings rows and thread Wi-Fi-only into the torrent effect
Adds the missing torrentSpeedPreset settings row (the field already
controlled preload size) and a new Wi-Fi-only toggle. The Android-side
gating for Wi-Fi-only lives in TorrentStreamManager.startStream (see the
next commit); this piece wires the active profile's torrentWifiOnly flag
through the startTorrentStream headless effect.

torrentMaxConnections and torrentCachePreset are intentionally left
unexposed: the underlying rqbit torrent engine has no per-torrent
connection-count cap or disk-cache-size knob to back them, so a toggle
for either would be a no-op.
2026-07-10 02:01:50 +03:00
KhooLy
cffda2dad9 Add settings rows for notifications, auto-updates, subtitle shadow, and home hero trailer autoplay
These profile fields (notificationsEnabled, automaticUpdates, subtitleShadow,
trailerOnHomeHeroEnabled/DelaySeconds) already drove real behavior but had no
visible Settings UI on TV or mobile. Also gates the background update-check
loop in MainActivity behind automaticUpdates, and wires a TV "Check for
updates" action mirroring the existing mobile flow.
2026-07-09 23:00:59 +03:00
KhooLy
6fcf675761 Add content descriptions to icon-only buttons
Give back, search, cast, picture-in-picture, external-player, and
calendar month-navigation buttons localized accessibility labels so
TalkBack announces their action. Adds the supporting common.* i18n keys.
2026-07-05 00:14:12 +03:00
KhooLy
56e2697dfa Fill missing and untranslated Turkish i18n strings
Add missing auto.connect key and translate 33 settings, player, and
notification strings that were still showing English in the Turkish locale.
2026-07-05 00:04:52 +03:00
KhooLy
05083b3f0b Improve plugin auto-update: failure reporting, deduplication, separate notification IDs
- Return UpdateReport(updatedPlugins, failedPlugins) from auto-updater so failures
  are tracked separately from successes
- Show a distinct notification when one or more plugins fail to update, using
  separate notification IDs so the success and failure toasts don't stomp each other
- Add installKey() to Plugin for stable deduplication by (name, repositoryUrl) pair;
  use it in isPluginInstalled to avoid duplicate installs on re-run
- Add i18n keys notification.plugins_update_failed_title/body in en-US and tr-TR
2026-07-03 12:52:50 +03:00
KhooLy
adf7700f7d Fix mpv/ExoPlayer audio passthrough, channel layout, AO, and DV track selection
mpv:
- Set ao=audiotrack explicitly so the AudioTrack output is guaranteed
  (avoids openSLES which lacks encoded passthrough)
- Add audio-channels=7.1,5.1,stereo so mpv negotiates multichannel
  instead of defaulting to auto-safe stereo downmix
- Build audio-spdif at init time by querying AudioManager output device
  encodings; only advertises AC3/E-AC3/DTS/DTS-HD/TrueHD formats the
  device actually reports

ExoPlayer:
- Guard setVideoEffects(emptyList()) behind a videoEffectsActive flag:
  only call it when IptPqc2ToneMapEffect was actually installed, never
  on a clean path — the empty-list call triggers the GL VideoFrameProcessor
  pipeline in media3 1.10.1 which tone-maps HDR even for an empty effect list
- detectPreferredVideoMimeType now accepts Context and checks display +
  decoder DV capability first; on fully DV-capable devices it returns
  VIDEO_DOLBY_VISION so DV variant tracks are preferred rather than
  deprioritized behind H.265/H.264
2026-07-03 03:51:49 +03:00
KhooLy
348c4ad4bb Clean up mobile settings visuals and align them with design tokens 2026-07-02 01:15:47 +03:00