Commit graph

7 commits

Author SHA1 Message Date
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
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
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
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
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
Movix
1401dc20f3 tird release
mon compte github a été détecté comme du spam je crois
2026-04-28 17:55:00 +02:00