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 b2ea3ff..0a09e5a 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,36 +1,73 @@ package com.vyla.go -import android.graphics.Bitmap +import android.graphics.Color +import android.os.Build import android.os.Bundle -import android.view.View -import android.view.ViewGroup -import android.webkit.WebChromeClient +import android.view.WindowManager +import android.webkit.JavascriptInterface import android.webkit.WebView +import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.WindowInsetsControllerCompat class MainActivity : TauriActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) + private var webView: WebView? = null + private var insetTop = 0f + private var insetRight = 0f + private var insetBottom = 0f + private var insetLeft = 0f - val root = findViewById(android.R.id.content) - root.viewTreeObserver.addOnGlobalLayoutListener { - findAndHookWebView(root) - } + private inner class InsetBridge { + @JavascriptInterface + fun get(): String = + "{\"top\":$insetTop,\"right\":$insetRight,\"bottom\":$insetBottom,\"left\":$insetLeft}" } - 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 + override fun onCreate(savedInstanceState: Bundle?) { + WindowCompat.setDecorFitsSystemWindows(window, false) + window.statusBarColor = Color.TRANSPARENT + window.navigationBarColor = Color.TRANSPARENT + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + window.isNavigationBarContrastEnforced = false + window.isStatusBarContrastEnforced = false } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + window.attributes.layoutInDisplayCutoutMode = + WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES + } + super.onCreate(savedInstanceState) + WindowInsetsControllerCompat(window, window.decorView).apply { + isAppearanceLightStatusBars = false + isAppearanceLightNavigationBars = false + } + ViewCompat.setOnApplyWindowInsetsListener(window.decorView) { _, insets -> + val bars = insets.getInsets( + WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() + ) + val d = resources.displayMetrics.density + insetTop = bars.top / d + insetRight = bars.right / d + insetBottom = bars.bottom / d + insetLeft = bars.left / d + pushInsets() + insets + } + ViewCompat.requestApplyInsets(window.decorView) + } - if (view is ViewGroup) { - for (i in 0 until view.childCount) { - findAndHookWebView(view.getChildAt(i)) - } + override fun onWebViewCreate(webView: WebView) { + this.webView = webView + webView.addJavascriptInterface(InsetBridge(), "VylaInsets") + } + + private fun pushInsets() { + val wv = webView ?: return + wv.post { + wv.evaluateJavascript( + "window.__vylaApplyInsets&&window.__vylaApplyInsets($insetTop,$insetRight,$insetBottom,$insetLeft)", + null + ) } } } \ No newline at end of file diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index dd1f550..a39dfe8 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -626,9 +626,37 @@ const ANDROID_VIDEO_FIX_SCRIPT: &str = r#" })(); "#; +const EDGE_TO_EDGE_SCRIPT: &str = r#" +(function() { + var m = document.querySelector('meta[name=viewport]'); + if (m && m.content.indexOf('viewport-fit') === -1) { + m.content += ', viewport-fit=cover'; + } + function apply(t, r, b, l) { + var s = document.documentElement.style; + s.setProperty('--safe-top', t + 'px'); + s.setProperty('--safe-right', r + 'px'); + s.setProperty('--safe-bottom', b + 'px'); + s.setProperty('--safe-left', l + 'px'); + } + window.__vylaApplyInsets = apply; + try { + if (window.VylaInsets) { + var v = JSON.parse(window.VylaInsets.get()); + apply(v.top, v.right, v.bottom, v.left); + } + } catch (e) {} +})(); +"#; + #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() + .on_page_load(|webview, payload| { + if payload.event() == tauri::webview::PageLoadEvent::Finished { + let _ = webview.eval(EDGE_TO_EDGE_SCRIPT); + } + }) .plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_process::init()) .plugin(tauri_plugin_opener::init()) diff --git a/ui/index.html b/ui/index.html index 05bdaf5..ec54bac 100644 --- a/ui/index.html +++ b/ui/index.html @@ -3,9 +3,17 @@ - + Vyla Go