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
|
||
|---|---|---|
| .. | ||
| android | ||
| assets | ||
| ios | ||
| scripts | ||
| src | ||
| .env.example | ||
| .gitignore | ||
| app.json | ||
| babel.config.cjs | ||
| index.js | ||
| metro.config.cjs | ||
| movix-android.apk | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| version.json | ||
Movix — Application Mobile
Application iOS & Android pour Movix. WebView avec l'extension Movix intégrée (remplacement du userscript Tampermonkey) et changeur DNS 1.1.1.1.
⚠️ Statut iOS : non testé, non compilé
Je n'ai pas de Mac à disposition, donc la partie iOS (Xcode, CocoaPods,
NEDNSSettingsManager, entitlements, archive, signature, App Store) n'a jamais été buildée ni testée. Le code natif Swift/Objective-C et la configPodfilesont rédigés à l'aveugle à partir de la documentation Apple.Il est très probable qu'il y ait des erreurs de build, des permissions manquantes, du linking à corriger ou un bridging header à ajuster avant que l'app tourne sur un vrai device iOS.
Toute aide est la bienvenue : si tu as un Mac et un peu de temps, n'hésite pas à tester, ouvrir une issue ou soumettre une PR. La partie Android est elle fonctionnelle et testée localement.
Architecture
app/
├── src/
│ ├── App.tsx # Navigation (Browser + Settings)
│ ├── screens/
│ │ ├── BrowserScreen.tsx # WebView principal + toolbar
│ │ └── SettingsScreen.tsx # Toggle DNS + infos extension
│ ├── components/
│ │ ├── WebViewBrowser.tsx # WebView avec injection userscript
│ │ └── BrowserToolbar.tsx # Barre de navigation
│ ├── services/
│ │ ├── bridge.ts # Bridge RN ↔ WebView (remplace GM_xmlhttpRequest)
│ │ └── dns.ts # Wrapper module DNS natif
│ ├── injection/
│ │ ├── bridge-runtime.ts # JS injecté dans le WebView (API GM_*)
│ │ ├── inject.ts # Assembleur bridge + userscript
│ │ └── userscript-source.ts # Source du userscript (auto-généré)
│ └── config/
│ └── index.ts # Configuration de l'app
├── android/ # Code natif Android (VPN DNS)
├── ios/ # Code natif iOS (NEDNSSettings)
└── scripts/
└── build-userscript.js # Génère userscript-source.ts
Comment ça marche
- WebView charge
movix.cash - Bridge runtime est injecté AVANT le chargement de la page — fournit
GM_xmlhttpRequest,GM_getValue,GM_setValue,GM_deleteValue,unsafeWindow - Userscript original est injecté et fonctionne comme dans Tampermonkey
- Quand le userscript fait une requête via
GM_xmlhttpRequest, le bridge envoie un message à React Native - React Native fait la requête HTTP nativement (pas de CORS) et renvoie la réponse
- DNS 1.1.1.1 : sur Android via un VPN local, sur iOS via
NEDNSSettingsManager
Prérequis
- Node.js 18+
- React Native CLI (
npm install -g @react-native-community/cli) - Android : Android Studio, JDK 17, Android SDK 35
- iOS : Xcode 15+, CocoaPods (
gem install cocoapods)
Installation
cd app
# Installer les dépendances
npm install
# Générer le userscript source
node scripts/build-userscript.js
# iOS seulement
cd ios && pod install && cd ..
Lancement
# Android
npm run android
# iOS
npm run ios
# Metro bundler seul
npm run start
Build de production
Android (APK / AAB)
cd android
./gradlew assembleRelease # APK
./gradlew bundleRelease # AAB (Play Store)
L'APK sera dans android/app/build/outputs/apk/release/.
iOS
⚠️ Section non vérifiée — voir l'avertissement en haut du README. Les étapes ci-dessous sont les étapes Xcode standard pour un projet React Native, mais elles n'ont pas été exécutées sur ce projet.
- Ouvrir
ios/Movix.xcworkspacedans Xcode - Sélectionner le scheme "Movix" et la target device
- Product → Archive
DNS 1.1.1.1
Android
- Utilise
VpnServicepour créer un VPN local - Seules les requêtes DNS sont redirigées vers 1.1.1.1
- Aucune donnée ne transite par un serveur tiers
- L'utilisateur doit approuver la connexion VPN
iOS
- Utilise
NEDNSSettingsManager(iOS 14+) - DNS-over-HTTPS vers
cloudflare-dns.com - Nécessite l'entitlement
com.apple.developer.networking.dns-settings - Requiert un profil de provisioning avec cette capability
Mise à jour du userscript
Quand le userscript (../userscript/movix.user.js) est modifié :
node scripts/build-userscript.js
Puis rebuild l'app.
Notes
- Le
DnsPackage.ktdoit être enregistré dansMainApplication.kt(ajouté augetPackages()) - Pour iOS, le bridging header doit pointer vers
Movix-Bridging-Header.h - L'app exclut son propre trafic du VPN DNS pour éviter les boucles
- Le mode audio en arrière-plan est activé pour la lecture vidéo continue