diff --git a/frontend b/frontend new file mode 160000 index 0000000..e23979c --- /dev/null +++ b/frontend @@ -0,0 +1 @@ +Subproject commit e23979cbe067245ebdd6db360c08aaa6dfd23024 diff --git a/src-tauri/gen/android/app/src/main/java/com/vyla/go/MainActivity.kt b/src-tauri/gen/android/app/src/main/java/com/vyla/go/MainActivity.kt index 47514c2..b2ea3ff 100644 --- a/src-tauri/gen/android/app/src/main/java/com/vyla/go/MainActivity.kt +++ b/src-tauri/gen/android/app/src/main/java/com/vyla/go/MainActivity.kt @@ -1,9 +1,36 @@ package com.vyla.go +import android.graphics.Bitmap import android.os.Bundle +import android.view.View +import android.view.ViewGroup +import android.webkit.WebChromeClient +import android.webkit.WebView class MainActivity : TauriActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + + val root = findViewById(android.R.id.content) + root.viewTreeObserver.addOnGlobalLayoutListener { + findAndHookWebView(root) + } + } + + private fun findAndHookWebView(view: View) { + if (view is WebView) { + view.webChromeClient = object : WebChromeClient() { + override fun getDefaultVideoPoster(): Bitmap { + return Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888) + } + } + return + } + + if (view is ViewGroup) { + for (i in 0 until view.childCount) { + findAndHookWebView(view.getChildAt(i)) + } + } } } \ No newline at end of file diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 24d8edf..6ef619a 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -323,6 +323,45 @@ async fn download_and_extract_payload(app: tauri::AppHandle, window: WebviewWind Ok(base_dir) } +const ANDROID_VIDEO_FIX_SCRIPT: &str = r#" +(function() { + function suppressNativeOverlay() { + const styleId = '__vyla_native_video_fix'; + if (!document.getElementById(styleId)) { + const s = document.createElement('style'); + s.id = styleId; + s.textContent = ` + video::-webkit-media-controls, + video::-webkit-media-controls-enclosure, + video::-webkit-media-controls-panel, + video::-webkit-media-controls-overlay-play-button, + video::-webkit-media-controls-start-playback-button { + display: none !important; + -webkit-appearance: none !important; + opacity: 0 !important; + pointer-events: none !important; + } + `; + (document.head || document.documentElement).appendChild(s); + } + + document.querySelectorAll('video').forEach(v => { + v.setAttribute('playsinline', ''); + v.setAttribute('webkit-playsinline', ''); + v.removeAttribute('poster'); + }); + } + + suppressNativeOverlay(); + new MutationObserver(suppressNativeOverlay).observe(document.documentElement, { + childList: true, + subtree: true, + attributes: true, + attributeFilter: ['poster'] + }); +})(); +"#; + #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() @@ -389,6 +428,10 @@ pub fn run() { .setup(|app| { let handle = app.handle().clone(); + if let Some(window) = handle.get_webview_window("main") { + let _ = window.eval(ANDROID_VIDEO_FIX_SCRIPT); + } + tauri::async_runtime::spawn(async move { std::thread::sleep(std::time::Duration::from_millis(400)); @@ -398,7 +441,10 @@ pub fn run() { match download_and_extract_payload(handle.clone(), window.clone()).await { Ok(_) => { std::thread::sleep(std::time::Duration::from_millis(400)); - let _ = window.eval("window.location.replace('http://vyla.localhost/frontend/index.html');"); + let _ = window.eval(&format!( + "{}; window.location.replace('http://vyla.localhost/frontend/index.html');", + ANDROID_VIDEO_FIX_SCRIPT + )); } Err(err) => { update_ui(