Commit graph

47 commits

Author SHA1 Message Date
BARTHES Mathéo
7d2e24b4ab
Merge branch 'movixcorp:main' into main 2026-06-13 17:06:36 +02:00
BARTHES Mathéo
e7a3f8a59a
Merge pull request #1 from Mathr81/claude/ios-unsigned-build-action-4er0o3
Add Picture-in-Picture, Media Session, Debug Console, and Cast improvements
2026-06-13 17:06:13 +02:00
Movix
d32f23074b Settings url update 2026-06-13 16:13:00 +02:00
Movix
62ee5dc226 Extension and Userscript Movix[.]golf update 2026-06-13 16:11:53 +02:00
Claude
641542fdca
feat(pip): boutons de contrôle PiP Android + masquage barre params; clarif limite auto-PiP iOS
- Android PiP : boutons lecture/pause + plein écran dans la fenêtre flottante
  (RemoteAction via BroadcastReceiver, icône play/pause synchronisée à l'état).
- Android PiP : masque la barre de paramètres (MiniPill/toolbar) et le padding
  status bar pendant le mode PiP via onPictureInPictureModeChanged → JS.
- iOS auto-PiP : commentaire clarifiant la limitation WebKit (inline/MSE non
  supporté, seul fullscreen→background déclenche l'auto-PiP).
2026-06-13 12:59:40 +00:00
Claude
eb9a8b5592
iOS Cast : démarrer la découverte pour déclencher la permission Réseau local
Symptôme : le picker Cast s'ouvre et « cherche » mais ne trouve aucun
Chromecast, et l'app n'apparaît même pas dans Réglages → Réseau local
(la popup de permission iOS ne s'affiche jamais).

Cause : le SDK Google Cast ne lance la découverte réseau automatiquement
QUE lorsqu'un GCKUICastButton est affiché pour la première fois. Movix
ouvre le picker programmatiquement (presentCastDialog) sans jamais
instancier de cast button → la découverte ne démarre jamais → aucun scan
Bonjour → iOS ne déclenche jamais la popup « Réseau local » → aucun
appareil trouvé. Les clés Info.plist (NSLocalNetworkUsageDescription,
NSBonjourServices) sont nécessaires mais ne suffisent pas : il faut
réellement tenter un accès réseau local pour que la popup apparaisse.

Correctif : startDiscoveryIfNeeded() lance explicitement
discoveryManager.startDiscovery() (passiveScan = false, idempotent),
appelé depuis isSupported() (au chargement de la page en mode Chromecast),
showPicker() et loadMedia(). Le scan Bonjour fait alors apparaître la
popup de permission et pré-remplit la liste d'appareils.

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-13 11:16:14 +00:00
Claude
a8daa92478
PiP : auto-PiP iOS natif + fix tactile + fix overlay Android
iOS — auto-PiP & gel du tactile :
Le bouton PiP du lecteur fonctionne parfaitement (la lecture continue en
arrière-plan). Le problème n'était QUE l'auto-entrée en quittant l'app.
Mon injection webkitSetPresentationMode sur applicationWillResignActive:
échouait (pas de user-gesture) ET laissait une présentation PiP à moitié
engagée → plus aucun tactile au retour dans l'app.

Solution : attribut WebKit natif video.autoPictureInPicture = true (posé
dans media-session.ts). WebKit bascule la vidéo en PiP tout seul au
passage en arrière-plan, par le même chemin que le bouton (qui marche).
Suppression de toute l'injection manuelle :
- AppDelegate.mm : retrait des overrides applicationWillResignActive: /
  applicationDidBecomeActive: et du helper findWKWebViewIn:
- BrowserScreen.tsx : retrait du handler AppState 'inactive' + imports
  AppState / isVideoPlayingRef devenus inutiles

Android — overlay PiP au lieu du film :
android-pip-shim : requestPictureInPicture() ne résout PLUS sa promesse.
En PiP Web le lecteur détache la vidéo et affiche un overlay "lecture en
PiP". Sur Android le PiP capture la WebView entière, donc cet overlay
masquait le film. En laissant la promesse en suspens, le lecteur garde la
vidéo inline → le PiP de l'Activity capture bien le film.

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-13 10:32:53 +00:00
Claude
47ebc3921b
iOS : corriger le crash au démarrage (super non implémenté)
RCTAppDelegate hérite de UIResponder et n'implémente NI
applicationWillResignActive: NI applicationDidBecomeActive: (ce sont
des méthodes optionnelles du protocole UIApplicationDelegate).

Mes overrides appelaient [super ...] aveuglément, ce qui envoyait un
sélecteur non reconnu dans la chaîne RCTAppDelegate → UIResponder →
NSObject → "unrecognized selector sent to instance" → crash.

applicationDidBecomeActive: étant appelé à CHAQUE lancement, l'app
crashait systématiquement au démarrage, avant même l'init de React
Native (donc avant la popup DNS).

Correctif : n'appeler [super ...] que si la super-classe répond
réellement au sélecteur (instancesRespondToSelector:_cmd), pour rester
compatible si une future version de RN ajoute ces méthodes.

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-13 09:46:48 +00:00
Claude
f7bf9e34dc
iOS AppDelegate : corriger le crash au démarrage sur iPad
Le SDK Google Cast déclenche un dialogue de permission réseau local
dès le lancement, ce qui provoque applicationWillResignActive: et
applicationDidBecomeActive: avant que React Native ait fini son init.

Corrections :
- applicationWillResignActive: : vérifier isViewLoaded avant d'accéder
  à rootViewController.view (évite de forcer viewDidLoad sur un VC
  non initialisé) ; vérifier webView.URL != nil (évite evaluateJavaScript
  sur un WKWebView sans page chargée)
- Passer un bloc non-nil à evaluateJavaScript:completionHandler: (évite
  un bug connu sur certaines versions d'iOS avec handler nil)
- applicationDidBecomeActive: : sauter la réinitialisation des gestes
  lors du premier appel au démarrage (_gestureResetSkipFirstActivation)
  pour ne l'exécuter que lors des retours depuis l'arrière-plan

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-12 15:03:24 +00:00
Claude
83aab6be05
iOS : immersive mode, notification touch fix, PiP timing fix
Quatre correctifs iOS demandés :

1. Mode immersif pendant la lecture vidéo
   - Barre de statut masquée (StatusBar.setHidden) quand une vidéo joue,
     restaurée à la pause / ouverture des paramètres.
   - BrowserToolbar et MiniPill masqués pendant la lecture (paddingTop = 0
     pour que la vidéo couvre tout l'écran, notch compris).
   - UIViewControllerBasedStatusBarAppearance = false garantit que le
     masquage s'applique aussi en mode plein-écran WebView (fix bouton FS).

2. PiP — injection native avant la suspension JS
   - applicationWillResignActive: trouve le WKWebView via findWKWebViewIn:
     et appelle directement evaluateJavaScript:, sans passer par le bridge
     React Native. Plus rapide et plus fiable que le chemin AppState/inactive.
   - Script PiP corrigé : webkitSetPresentationMode (synchrone) en premier,
     requestPictureInPicture (async Promise) uniquement en fallback.

3. Touch freeze après notification center
   - applicationDidBecomeActive: toggle userInteractionEnabled NO→YES avec
     50 ms de délai pour réinitialiser les gesture recognizers WKWebView
     bloqués après le glissement du centre de notifications.

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-12 13:25:03 +00:00
Claude
8eb6c087ed
fix(ios): raise Podfile platform to 15.1 for google-cast-sdk
CocoaPods rejected google-cast-sdk 4.8.4 because it requires iOS 15.0 while
the Podfile platform resolved to RN's default min_ios_version_supported (13.4).
The app target already deploys to iOS 15.6, so pinning the pod platform to
15.1 satisfies the Cast SDK requirement without reducing real device support.

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-12 11:20:28 +00:00
Claude
b791ad0c38
feat: real Chromecast on iOS + fix Android in-app PiP button
Android PiP button fix:
- The Android System WebView does not implement the Web Picture-in-Picture
  API, so the Movix player's PiP button showed "browser doesn't support PiP".
- New android-pip-shim.ts injects a PiP Web API shim (Android only):
  document.pictureInPictureEnabled = true + HTMLVideoElement.requestPictureInPicture
  override that routes to native Activity PiP via an ENTER_PIP bridge message.
- bridge.ts handles ENTER_PIP → PipModule.enterPipNow()
- PipModule.enterPipNow() + MainActivity.enterPipNow() trigger enterPictureInPictureMode
- iOS keeps native WebKit PiP (shim is Android-only)

Chromecast on iOS (now actually wired into the build):
- Podfile: pod 'google-cast-sdk', '~> 4.8.4' — since 4.8.4 the SDK ships as a
  static framework bundling Protobuf, so NO use_frameworks! is needed (compatible
  with the default RN static-library setup). Previous attempt used a non-existent
  pod name (google-cast-sdk-no-arc) which broke `pod install`.
- CastModule.swift rewritten to mirror the Android CastModule exactly: pending-load
  + presentCastDialog picker flow, GCKSessionManagerListener emitting
  CAST_SESSION_STARTED/RESUMED/ENDED/FAILED with {deviceName, durationSec, error},
  loadMedia/stop/getCurrentDeviceName/getCurrentPositionSec/getSessionState.
  All Cast API guarded by #if canImport(GoogleCast) so it compiles with or
  without the pod (degrades to isSupported=false).
- project.pbxproj: registered CastModule.swift + CastModule.m in the MovixApp
  target's Sources phase and wired SWIFT_OBJC_BRIDGING_HEADER (first Swift in the
  app target) — done via the xcodeproj gem so the project graph stays valid.
- Bridging header now imports RCTEventEmitter.h.
- AppDelegate.mm: GCKCastContext initialized via setSharedInstanceWithOptions:
  (correct ObjC selector) with the Default Media Receiver app ID.
- Info.plist: NSLocalNetworkUsageDescription + NSBonjourServices
  (_googlecast._tcp, _CC1AD845._googlecast._tcp) required for device discovery
  on iOS 14+.

The existing iOS-settings cast toggle (AirPlay vs Chromecast) now drives a real
Chromecast path: in Chromecast mode the cast shim is injected and the native iOS
CastModule responds supported=true.

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-12 11:17:53 +00:00
Claude
e1d3106b77
fix: remove non-existent google-cast-sdk-no-arc pod from Podfile
The pod `google-cast-sdk-no-arc` does not exist on CocoaPods. The real
variant is `google-cast-sdk-no-bluetooth`. Replaced with a commented-out
line for manual opt-in, since the SDK also requires `use_frameworks!
:linkage => :static` which conflicts with the default RN static library
setup. CastModule.swift already compiles cleanly without the pod via
`#if canImport(GoogleCast)` guards (isSupported returns false).

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-12 10:48:55 +00:00
Claude
1d12f98717
feat: native-quality video experience — PiP, wake lock, Chromecast iOS, config cache
Group A — PiP (iOS + Android):
- iOS: AppState 'inactive' injects requestPictureInPicture() from native side
  while WKWebView is still alive (fixes visibilitychange race with JS suspension)
- Expose isVideoPlayingRef + onMediaPlayback callback from BrowserScreen → bridge
- BridgeMessageOptions added to bridge.ts for cross-platform onMediaPlayback hook
- Android 12+ (API 31): setAutoEnterEnabled(true) via updatePipParams() called
  reactively from PipModule.setVideoPlaying() → covers all backgrounding scenarios
  (home button, swipe, screen timeout, power button), not just onUserLeaveHint

Group B — Wake Lock:
- navigator.wakeLock.request('screen') acquired on play, released on pause
- Re-acquired on visibilitychange return if video still playing
- visibilitychange now manages timer + wake lock only (PiP handled natively)
- window.__movixActiveVideo exposed for AppState PiP injection script

Group C — Chromecast on iOS:
- useBrowserUIPrefs: castMode: 'airplay' | 'chromecast' (iOS only, default airplay)
- SettingsScreen: iOS-only "Casting" section with AirPlay/Chromecast toggle
- inject.ts: AirPlay mode skips cast shim → site shows native AirPlay button;
  Chromecast mode injects shim → iOS CastModule handles Chromecast routing
- cast.ts: removed Platform.OS !== 'android' guard (iOS CastModule can respond)
- New ios/Movix/Cast/CastModule.swift + CastModule.m (mirrors Android CastModule)
  with #if canImport(GoogleCast) guards — compiles with or without SDK
- Podfile: pod 'google-cast-sdk-no-arc' (~> 4.8)
- AppDelegate: GCKCastContext initialized with DEFAULT_MEDIA_RECEIVER_APP_ID

Group D — Address config cache:
- AddressContext loads AsyncStorage cache immediately → near-instant start
- Fresh fetch runs in background, updates cache on success
- Offline resilience: stays on cache silently if network fails

Group E — WebView quality:
- IconLock SVG added to ToolbarIcons (Material Design lock path)
- BrowserToolbar: 🔒 emoji replaced with <IconLock> SVG component
- WebViewBrowser: setSupportMultipleWindows={false} + onOpenWindow={() => {}}
  to block window.open() popup ads

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-12 10:34:05 +00:00
Claude
57883ec041
fix(ios): auto-PiP on app background via visibilitychange
autoPictureInPicture only works with native <video src> playback — not
with MSE (HLS.js). Add a 'visibilitychange' listener that calls
requestPictureInPicture() when the document becomes hidden while a
video is playing. iOS 16+/iPadOS 16+ exempts this event from the
user-gesture requirement, and requestPictureInPicture() works fine with
MSE (same API the player's own PiP button uses).

Falls back to webkitSetPresentationMode('picture-in-picture') if the
Promise is rejected (iOS < 16) or if the standard API is absent.

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-11 18:52:15 +00:00
Claude
37ee5a85c7
feat(app): native media experience — lock screen artwork, background PiP
Make playback feel native on iOS (and Android) by leveraging OS media
features instead of leaving everything to the WebView default.

Media Session (cross-platform, src/injection/media-session.ts):
- The Movix web player never populates navigator.mediaSession, so the
  lock screen / Control Center / notification only showed a bare title.
- Inject a script that sets mediaSession.metadata with the movie title
  and artwork (video poster → og:image → icon → /movix.png fallback),
  wires play/pause/seek action handlers to the active <video>, and keeps
  positionState in sync for the scrubber.
- Hooked on the capture-phase 'play' event so it follows SPA navigation
  (episode/movie changes) without re-injection.
- Sets video.autoPictureInPicture / disablePictureInPicture=false to arm
  iOS auto-PiP, and relays play/pause to native (MEDIA_PLAYBACK message).

iOS background audio + PiP:
- AppDelegate.mm: configure AVAudioSession (.playback / .moviePlayback)
  so audio and Picture-in-Picture keep running when the app is
  backgrounded or the screen locks. Without this WKWebView stops the
  video on background.
- WebViewBrowser: allowsPictureInPictureMediaPlayback +
  allowsAirPlayForMediaPlayback. Combined with autoPictureInPicture, the
  video floats in PiP when leaving the app instead of stopping.

Android PiP:
- Manifest: supportsPictureInPicture + resizeableActivity on MainActivity.
- MainActivity.onUserLeaveHint() enters PiP (16:9) when a video is
  playing; playing-state is tracked via the new PipModule, fed from the
  Media Session script through the bridge.
- New PipModule/PipPackage registered in MainApplication.

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-11 18:28:39 +00:00
Claude
3a6114f1c4
fix(ios): show AirPlay picker instantly without waiting for loadedmetadata
HLSPlayer's startAirPlay() destroys HLS.js (MSE is incompatible with
AirPlay), sets video.src to the native HLS URL, then awaits a
'loadedmetadata' event before calling webkitShowPlaybackTargetPicker().
Buffering the remote manifest takes several seconds, causing the picker
to appear with a noticeable delay.

webkitShowPlaybackTargetPicker() does not require the video to have
loaded metadata — it only needs a src and user-gesture context. We
inject a patch into the WebView that fires a synthetic 'loadedmetadata'
event via setTimeout(0) as soon as video.load() is called on an
AirPlay-configured element with a real (non-blob) source URL. This
resolves the web player's awaited Promise immediately, so the picker
appears without the multi-second buffering wait.

The patch is guarded by webkitShowPlaybackTargetPicker availability so
it only activates on iOS WKWebView, and is a no-op if real metadata
arrives first (readyState < 1 check).

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-11 17:35:06 +00:00
Claude
5f35a0fc67
fix(app): proxy off must make the extension undetectable
Disabling "Proxy intégré" still left the userscript injected, so it ran
exposePageApi() which sets __MOVIX_EXTENSION_INSTALLED / hasMovixUserscript
/ dataset.movixExtension and fires movix-extension-loaded. The site (e.g.
movix.golf/extension) kept reporting "extension détectée et active" and
routed its requests through the proxy bridge — which then failed.

Fix: when proxyEnabled is false, don't inject the userscript at all. The
site no longer detects the extension and falls back to its own network
path. Bridge runtime + cast shim stay injected (debug console capture +
Chromecast).

Removes the now-dead direct-XHR fallback and the __MOVIX_PROXY_ENABLED
flag from the bridge runtime. Updates the settings hint to match.

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-11 17:02:36 +00:00
Claude
fcb9a12c25
feat(app): debug console, edge-flush MiniPill, toggle proxy intégré
Three settings/UX improvements for the mobile WebView app:

1. Console de debug (Réglages → Débogage)
   - New in-memory log buffer (services/debugLog.ts, 500-entry rotation)
   - installConsoleCapture() patches console.* on the RN side at startup
   - bridge-runtime forwards WebView console.* via new CONSOLE_LOG message
   - bridge.ts routes CONSOLE_LOG → pushLog(source: 'web')
   - DebugConsole.tsx: full-screen modal, level filters, auto-scroll,
     share-as-text. Opened from a new "Débogage" settings section.

2. MiniPill flush to screen edge
   - Was floating at insets.bottom + 8 (~1cm gap on devices with a home
     indicator). Now pinned to bottom: 0, thinner, with hitSlop to keep
     the tap target generous.

3. Toggle "Proxy intégré"
   - New proxyEnabled pref (useBrowserUIPrefs, default true, persisted)
   - Switch replaces the static "Actif" badge in the Extension section
   - When off, GM_xmlhttpRequest runs directly in the WebView (in-page
     XMLHttpRequest, page cookies, subject to CORS) instead of routing
     through the native fetch bridge — helps sources the proxy breaks
   - inject.ts injects window.__MOVIX_PROXY_ENABLED; WebView remounts on
     toggle via key change so the new mode applies on reload

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-11 16:39:48 +00:00
Claude
9d2341ded0
feat(ios): iPad universal support - TARGETED_DEVICE_FAMILY 1 → 1,2
TARGETED_DEVICE_FAMILY was set to 1 (iPhone only), causing the app to
run in iPhone compatibility mode on iPad (small centered window).
Set to "1,2" (Universal) in both Debug and Release build configs.

Also add UISupportedInterfaceOrientations~ipad in Info.plist to declare
all four orientations for iPad (including PortraitUpsideDown which is
supported on iPad but not on modern iPhones).

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-11 16:05:04 +00:00
Claude
9cf3ea79cf
ci: add Android APK build job
New build_android job running on ubuntu-latest:
- setup-java@v4 with JDK 17 (Temurin) matching compileOptions
- npm ci + build:userscript (same as iOS job)
- Gradle cache keyed on wrapper + root/app build.gradle hashes
- ./gradlew assembleRelease --no-daemon
- Artifact: Movix-Android-<version>, retention 30 days

Both jobs now triggered independently via workflow_dispatch booleans
(build_ios / build_android, both default true).
APK is debug-signed (falls back to signingConfigs.debug when no
keystore.properties) — suitable for sideloading.

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-11 15:22:39 +00:00
Claude
6563874ee2
ci: fix Metro UnableToResolveError - generate userscript before build
src/injection/userscript-source.ts is .gitignored (generated from
userscript/movix.user.js). Metro bundler fails at bundle phase with
UnableToResolveError when it tries to import ./userscript-source.
Add `npm run build:userscript` step after npm ci to generate the file.

Also: pipe xcodebuild through tee to save raw log + use ${PIPESTATUS[0]}
for correct exit code propagation. Upload raw log as artifact on failure
to expose the full error without xcpretty truncation.

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-11 13:53:46 +00:00
Claude
902d8b4f75
ci: improve iOS unsigned build action for MovixApp rename
- Fix workspace/scheme/app names: Movix → MovixApp (upstream rename)
- Add ruby/setup-ruby with CocoaPods 1.16.2 pinned (matches Podfile.lock)
- Switch npm install → npm ci (faster, uses package-lock.json)
- Cache node_modules keyed on package-lock.json hash
- Add xcpretty for readable xcodebuild output
- Add ONLY_ACTIVE_ARCH=NO for Release (builds all architectures)
- Add set -eo pipefail for reliable error propagation
- Read version from version.json and embed in artifact name
- Add retention-days: 30 on uploaded artifact
- Add job timeout-minutes: 60

https://claude.ai/code/session_01X52sah6aUu3ou26uJWHgzr
2026-06-11 13:37:40 +00:00
Claude
6ace48f36d
Sync: merge upstream movixcorp/MovixOpenSource (20 commits - iOS fixes, app icon, runtime fixes, extensions update) 2026-06-11 13:35:34 +00:00
Movix
990a5163a2 Maj des adresses extension, userscript et PreMid 2026-05-30 17:07:05 +02:00
MysticSaba
4d60772001
Merge pull request #10 from MathieuVce/feat/ios-runtime-fixes
fix: correctifs de comportement iOS au lancement et à l'exécution
2026-05-19 22:33:18 +02:00
MysticSaba
31ace14e5b
Merge pull request #9 from MathieuVce/feat/ios-app-icon
feat: app icon iOS toutes les tailles générées
2026-05-19 22:33:01 +02:00
Mathieu
e5048c5461 fix: cast iOS retourne false sans log d erreur car module Android only 2026-05-17 12:38:44 +02:00
Mathieu
171b0976ec fix: WebView iOS gestion deep links et interception URL schemes externes 2026-05-17 12:38:35 +02:00
Mathieu
57a85bf278 feat: UpdateModule iOS lecture version native depuis Info.plist 2026-05-17 12:38:28 +02:00
Mathieu
8fd0568a94 fix: splash screen overlay RN avec logo jusqu au premier chargement WebView 2026-05-17 12:38:20 +02:00
Mathieu
ac44033ae4 feat: app icon iOS toutes les tailles générées 2026-05-17 12:37:38 +02:00
Movix
2045dbd2c9 Nouvelle adresse movix + nouvelles fonctionalités
Modification du Oauth :
Pouvoir manager les apps depuis le panel admin

Correction de l'affichage des images des admins

Majs des urls extension, userscript et premid

Correction d'un crash sur les commentaires

Ajout d'un light mode sur le frontend
2026-05-14 17:26:13 +02:00
MysticSaba
8b8e63f504
Merge pull request #7 from MathieuVce/fix/migrate-name-compilation-ios
Fix  compilation ios
2026-05-14 12:53:18 +02:00
Mathieu
e5f20ec240 fix: compilation name in AppDelegate 2026-05-12 00:09:07 +02:00
Mathieu
5c55a52845 fix: compilation with Xcode & npm run ios working + adding missing files du to migration & launchscreen with logo 2026-05-11 21:24:18 +02:00
Mathieu
23cce73a20 migrate: update repo references to MovixApp for iOS build podfile 2026-05-11 18:42:44 +02:00
MysticSaba
974775c0e7
Fix ddl url app 2026-05-11 14:54:20 +02:00
Movix
e57910d274 j'ai oublié de supprimé les fichiers code morts 2026-05-10 16:39:13 +02:00
Movix
4bba4cab40 chore: drop firebase + perf wave + mobile v2.5.3 + uqload HLS + multi-receiver cast + SW gateway
Nettoyage massif côté frontend, grosse passe perf, app mobile v2.5.3
(écran qui ne s'éteint plus + fix build), extracteur Uqload HLS sur
extensions/userscript, redirection réseau-bloqué via passerelle
explicative et cast cross-receiver/cross-browser.

Nettoyage Firebase & code mort
- Drop firebase + @firebase/firestore (package.json + vite.config
  optimizeDeps + alias)
- Suppression src/config/firebase.ts (jamais utilisé)
- Suppression services morts : adminService, commentService, logService,
  notificationService + composants liés (AdminLogin, CommentSection,
  CommentItem, ReactionBar) + types/Comment.ts
- Suppression scripts non-utilisés : bundle-report.mjs, publish-app.mjs
- Net : -3 449 lignes

Perf carrousels & TMDB images
- useTmdbImages : 1 seul fetch TMDB pour logo + poster (au lieu de 2),
  prefetch idle au mount du carousel + dedup via inflight map (0 doublon
  entre prefetch et hooks), include_image_language=fr,en,null pour
  récupérer les versions FR-prioritisées
- EmblaCarousel : pré-décode des posters off-DOM (img.decode) en idle
  pour éliminer le coût de décode pendant le scroll horizontal, priority
  cap statique (eager + fetchpriority=high pour les N premières cards
  selon viewport), suppression du tracking visibleSlides (state churn)
- content-visibility:auto sur slides hors viewport (skip layout/paint
  natif), exclu des slides Top 10 pour ne pas clipper le digit débordant
- will-change:transform pré-promotion compositing layer (PC only via
  hover:hover)
- Embla duration 25 → 15 (snap plus rapide, moins de frames composées)
- Boutons nav carousel : suppression backdrop-blur (cher), bg opaque
- LazyImage : width/height attrs pour éviter CLS + alléger placeholder

Top progress bar (style YouTube)
- TopProgressBar : asymptote vers 85% pendant chunk loads, fill 100%
  smooth + fade out à la fin, 120ms grace period pour suppress flash
  sur chunks cachés
- lazyWithRetry tracke les loads actifs + dispatch chunk:load:start /
  chunk:load:end events sur window
- Routes loaders supportent { silent: true } pour skip le tracking sur
  les prefetch (PrefetchLink hover + IDLE_PREFETCH au mount)

SW redirect → passerelle movix.health explicative
- buildMirrorUrl() factorise la construction d'URL miroir avec contexte
- handleNavigation passe ?from=&reason=unreachable&error=&via= à la
  gateway pour qu'elle affiche une popup explicative au user au lieu
  d'un redirect silencieux
- MOVIX_FORCE_REDIRECT message handler passe reason=api-errors
- blockDetection.ts transmet la dernière erreur axios au SW
- index.html : cache-bust du Cast SDK URL (cb=Date.now()) pour éviter
  qu'un SDK stale ne reste coincé en cache navigateur/SW

Cast (Chromecast + AirPlay + Remote Playback API)
- loadMediaOnCastWithFallback : retry sur 3 MIME HLS différents
  (application/vnd.apple.mpegurl, x-mpegurl, x-mpegURL) — certains
  receivers rejettent le premier choix selon firmware
- Subtitles externes attachés au cast (CastSubtitleTrack) via
  chrome.cast.media.Track + TextTrackStyle par défaut (50% black
  background, edge outline) lisible sur la majorité des TV
- isRemotePlaybackSupported : fallback W3C Remote Playback API pour
  Firefox / Edge avec cast extension bloquée / Brave avec shields →
  device discovery + picker via video.remote.prompt()
- initializeAirPlay supporte désormais les deux paths (WebKit AirPlay
  pour Safari + Remote Playback pour les autres)
- Détection castSdkBlocked : si le SDK Cast ne charge pas en 5s
  (adblock, FAI, shield), affiche un message d'erreur explicite au
  lieu du générique "aucun device trouvé"
- 7 nouvelles strings i18n FR + EN pour les états cast :
  castUnavailable, castUnavailableNoDevices,
  castUnavailableUnsupportedBrowser, castUnavailableSdkBlocked,
  castUnavailableHelpChromecast, castUnavailableHelpAirPlay,
  castUnavailableSeeHelp

App mobile Android v2.5.3 (versionCode 12)
- AndroidManifest : android:keepScreenOn="true" sur MainActivity →
  l'écran ne s'éteint plus pendant le visionnage (avant le user devait
  toucher l'écran toutes les 30s pour pas que le téléphone se lock en
  plein film)
- build.gradle : exclude androidx.legacy:legacy-support-core-utils
  (tiré transitivement par mediarouter → palette) qui embarquait ses
  propres androidx.autofill.R$attr → "duplicate class" au mergeDexRelease
  contre le module androidx.autofill:autofill:1.1.0 d'appcompat
- gradle.properties : android.nonTransitiveRClass=true pour empêcher
  chaque lib de regénérer ses R classes transitivement (même cause
  racine du duplicate class)
- version.json bumped 2.5.2 → 2.5.3, nouvel APK (-17KB), release notes
  FR : "Correction extraction du lecteur Uqload" + "L'écran ne s'éteint
  plus lors de l'utilisation de l'app"
- apkUrl repointé sur le repo Movix-STMG (au lieu de movixcorp)

Userscript + Extensions Chrome/Firefox — Uqload HLS
- extractUqload : préfère désormais le master.m3u8 multi-bitrate (qualité
  adaptative) au v.mp4 single-quality. Regex tente d'abord
  /master\.m3u8/, sinon n'importe quel .m3u8, et fallback sur l'ancien
  pattern v.mp4 si rien trouvé. Les 3 cibles (Chrome MV3, Firefox MV2,
  Tampermonkey) sont synchronisées sur la même logique.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 13:28:51 +02:00
Movix
7059124b24 Majs de urls + corrections scrapers + nouvelle source
Maj url dans l'app mobile, extension et userscript et backend : streamonsport, livetv.

Amélioration du scraper darkiworld/hydracker

Nouvelle source vo/vostfr qui est plutôt pas mal
Renommages des sources vo/vostfr avec le nom du doamine pour mieux se repérer
Correction de la synchronisation des données qui étais buggé sur certains navigateurs autre que chrome sur certaines versions
Amélioration de la détection du blocage dns
2026-05-06 22:54:06 +02:00
Qzenlebg
02d8361d06 Ajout des fichiers Xcode pour la partie iOS 2026-05-06 19:57:26 +02:00
Movix
cbc3f1dad9 Merge depuis le repo privé après tests
Corrections de vulnérabilités sur les commentaires (IDOR)
Rajouts de ratelimit sur les commentaires
Correction de pas de son sur hlsplayer
Livetvplayer détecte le type du flux automatiquement
Amélioration du scraper darkiworld (très chiant)
Correction du détection de l'extension

Correction de la vérification du VIP sur server.py (proxy)
Correction du scraper seekstreaming proxy

Nouvelle url streamonsport et coflix
Correction du scraper fstream (get seasons) car la route fonctionne plus sur leur site
Correction du scraper francetv
Ajout de hydrackerBatch (c'étais pour des tests)
2026-05-03 12:47:41 +02:00
BARTHES Mathéo
e05ded8117
Update build.yml for iOS build directory changes 2026-04-29 21:56:24 +02:00
BARTHES Mathéo
31f00e0de5
Add GitHub Actions workflow for building iOS applications 2026-04-29 21:51:52 +02:00
MysticSaba
ac0e29bbb4
Update version.json 2026-04-28 18:15:38 +02:00
Movix
1401dc20f3 tird release
mon compte github a été détecté comme du spam je crois
2026-04-28 17:55:00 +02:00