Skip to content

Commit

Permalink
fix: execute methods on UI thread
Browse files Browse the repository at this point in the history
  • Loading branch information
tafelnl committed May 7, 2024
1 parent 6bdf857 commit d5de337
Showing 1 changed file with 53 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,20 @@ import androidx.core.view.WindowInsetsCompat

class SafeArea(private val activity: Activity, private val webView: WebView) {
var offset = 0
private var appearanceUpdatedInListener = false

fun enable(updateInsets: Boolean, appearanceConfig: AppearanceConfig) {
activity.window.decorView.getRootView().setOnApplyWindowInsetsListener { view, insets ->
updateInsets()
// @TODO: appearance is sometimes not updated on app load
// probably because it is superseded by another plugin or native thing that updates the appearance
// This is probably not the best way to override that behaviour
// So we should think of something better than simply calling `updateAppearance` here
updateAppearance(appearanceConfig)
if (!appearanceUpdatedInListener) {
// @TODO: appearance is sometimes not updated on app load
// probably because it is superseded by another plugin or native thing that updates the appearance
// This is probably not the best way to override that behaviour
// So we should think of something better than simply calling `updateAppearance` here
updateAppearance(appearanceConfig)
// Only update it once, to prevent an infinite loop
appearanceUpdatedInListener = true
}
view.onApplyWindowInsets(insets)
}

Expand All @@ -31,52 +36,58 @@ class SafeArea(private val activity: Activity, private val webView: WebView) {
}

fun disable(appearanceConfig: AppearanceConfig) {
WindowCompat.setDecorFitsSystemWindows(activity.window, true)
activity.runOnUiThread {
WindowCompat.setDecorFitsSystemWindows(activity.window, true)
}
activity.window.decorView.getRootView().setOnApplyWindowInsetsListener(null)
resetProperties()

updateAppearance(appearanceConfig)
}

private fun updateAppearance(appearanceConfig: AppearanceConfig) {
val windowInsetsControllerCompat =
WindowCompat.getInsetsController(activity.window, activity.window.decorView)
windowInsetsControllerCompat.isAppearanceLightStatusBars =
appearanceConfig.statusBarContent == "dark"
windowInsetsControllerCompat.isAppearanceLightNavigationBars =
appearanceConfig.navigationBarContent == "dark"

val window = activity.window

if (appearanceConfig.customColorsForSystemBars) {
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.statusBarColor = Color.parseColor(appearanceConfig.statusBarColor)
window.navigationBarColor = Color.parseColor(appearanceConfig.navigationBarColor)
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
activity.runOnUiThread {
val windowInsetsControllerCompat =
WindowCompat.getInsetsController(activity.window, activity.window.decorView)
windowInsetsControllerCompat.isAppearanceLightStatusBars =
appearanceConfig.statusBarContent == "dark"
windowInsetsControllerCompat.isAppearanceLightNavigationBars =
appearanceConfig.navigationBarContent == "dark"

val window = activity.window

if (appearanceConfig.customColorsForSystemBars) {
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.statusBarColor = Color.parseColor(appearanceConfig.statusBarColor)
window.navigationBarColor = Color.parseColor(appearanceConfig.navigationBarColor)
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
}
}
}

private fun updateInsets() {
WindowCompat.setDecorFitsSystemWindows(activity.window, false)

val windowInsets = ViewCompat.getRootWindowInsets(activity.window.decorView)
val systemBarsInsets =
windowInsets?.getInsets(WindowInsetsCompat.Type.systemBars()) ?: Insets.NONE
val imeInsets = windowInsets?.getInsets(WindowInsetsCompat.Type.ime()) ?: Insets.NONE

val density = activity.resources.displayMetrics.density

setProperty("top", Math.round(systemBarsInsets.top / density) + offset)
setProperty("left", Math.round(systemBarsInsets.left / density))
if (imeInsets.bottom > 0) {
setProperty("bottom", 0)
} else {
setProperty("bottom", Math.round(systemBarsInsets.bottom / density) + offset)
activity.runOnUiThread {
WindowCompat.setDecorFitsSystemWindows(activity.window, false)

val windowInsets = ViewCompat.getRootWindowInsets(activity.window.decorView)
val systemBarsInsets =
windowInsets?.getInsets(WindowInsetsCompat.Type.systemBars()) ?: Insets.NONE
val imeInsets = windowInsets?.getInsets(WindowInsetsCompat.Type.ime()) ?: Insets.NONE

val density = activity.resources.displayMetrics.density

setProperty("top", Math.round(systemBarsInsets.top / density) + offset)
setProperty("left", Math.round(systemBarsInsets.left / density))
if (imeInsets.bottom > 0) {
setProperty("bottom", 0)
} else {
setProperty("bottom", Math.round(systemBarsInsets.bottom / density) + offset)
}
setProperty("right", Math.round(systemBarsInsets.right / density))

activity.window.decorView.setPadding(0, 0, 0, imeInsets.bottom)
}
setProperty("right", Math.round(systemBarsInsets.right / density))

activity.window.decorView.setPadding(0, 0, 0, imeInsets.bottom)
}

private fun resetProperties() {
Expand All @@ -87,6 +98,8 @@ class SafeArea(private val activity: Activity, private val webView: WebView) {
}

private fun setProperty(position: String, size: Int) {
webView.loadUrl("javascript:document.querySelector(':root')?.style.setProperty('--safe-area-inset-" + position + "', 'max(env(safe-area-inset-" + position + "), " + size + "px)');void(0);")
activity.runOnUiThread {
webView.loadUrl("javascript:document.querySelector(':root')?.style.setProperty('--safe-area-inset-" + position + "', 'max(env(safe-area-inset-" + position + "), " + size + "px)');void(0);")
}
}
}

0 comments on commit d5de337

Please sign in to comment.