Skip to content

Commit f368b62

Browse files
authored
Avoid change of WebView composable after adding/removing insets (#6254)
1 parent 1f1a9c7 commit f368b62

1 file changed

Lines changed: 40 additions & 57 deletions

File tree

app/src/main/kotlin/io/homeassistant/companion/android/webview/WebViewContentScreen.kt

Lines changed: 40 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,17 @@ internal fun WebViewContentScreen(
147147
}
148148
}
149149

150+
/**
151+
* Wrapper for WebView, blurring the contents when the app is locked.
152+
*
153+
* If the Home Assistant frontend does not handle edge-to-edge insets
154+
* (core <2025.12), it also wraps the WebView with colored overlays matching
155+
* the safe area insets.
156+
*
157+
* This wrapper ensures the [HAWebView] is not removed from composition when
158+
* the app lock, theme or server inset support changes, to avoid losing loading
159+
* progress or frontend state when it isn't necessary.
160+
*/
150161
@OptIn(ExperimentalHazeMaterialsApi::class)
151162
@Composable
152163
private fun SafeHAWebView(
@@ -158,80 +169,52 @@ private fun SafeHAWebView(
158169
serverHandleInsets: Boolean,
159170
) {
160171
val hazeModifier = if (currentAppLocked) Modifier.hazeEffect(style = HazeMaterials.thin()) else Modifier
172+
val insets = WindowInsets.safeDrawing
173+
val insetsPaddingValues = insets.asPaddingValues()
161174

162-
if (serverHandleInsets) {
163-
Box(modifier = hazeModifier) {
164-
HAWebView(
165-
nightModeTheme = nightModeTheme,
166-
factory = { webView },
175+
Column(modifier = hazeModifier) {
176+
if (!serverHandleInsets) {
177+
statusBarColor?.Overlay(
167178
modifier = Modifier
168-
.fillMaxSize()
169-
.background(Color.Transparent),
179+
.height(insetsPaddingValues.calculateTopPadding())
180+
.fillMaxWidth()
181+
// We don't want the status bar to color the left and right areas
182+
.padding(insets.only(WindowInsetsSides.Horizontal).asPaddingValues()),
170183
)
171184
}
172-
} else {
173-
HAWebViewWithInsets(
174-
webView = webView,
175-
nightModeTheme = nightModeTheme,
176-
statusBarColor = statusBarColor,
177-
backgroundColor = backgroundColor,
178-
modifier = hazeModifier,
179-
)
180-
}
181-
}
182-
183-
/**
184-
* Wraps the WebView with colored overlays matching the safe area insets.
185-
*
186-
* Used when the Home Assistant frontend does not handle edge-to-edge insets
187-
* version prior 2025.12.x
188-
*/
189-
@Composable
190-
private fun HAWebViewWithInsets(
191-
webView: WebView?,
192-
nightModeTheme: NightModeTheme?,
193-
statusBarColor: Color?,
194-
backgroundColor: Color?,
195-
modifier: Modifier = Modifier,
196-
) {
197-
val insets = WindowInsets.safeDrawing
198-
val insetsPaddingValues = insets.asPaddingValues()
199-
200-
Column(modifier = modifier) {
201-
statusBarColor?.Overlay(
202-
modifier = Modifier
203-
.height(insetsPaddingValues.calculateTopPadding())
204-
.fillMaxWidth()
205-
// We don't want the status bar to color the left and right areas
206-
.padding(insets.only(WindowInsetsSides.Horizontal).asPaddingValues()),
207-
)
208185
// The height is based on whatever is left between the statusBar and navigationBar
209186
Row(modifier = Modifier.weight(1f)) {
210-
// Left safe area
211-
backgroundColor?.Overlay(
212-
modifier = Modifier
213-
.fillMaxHeight()
214-
.width(insetsPaddingValues.calculateLeftPadding(LayoutDirection.Ltr)),
215-
)
187+
if (!serverHandleInsets) {
188+
// Left safe area
189+
backgroundColor?.Overlay(
190+
modifier = Modifier
191+
.fillMaxHeight()
192+
.width(insetsPaddingValues.calculateLeftPadding(LayoutDirection.Ltr)),
193+
)
194+
}
216195
HAWebView(
217196
nightModeTheme = nightModeTheme,
218197
factory = { webView },
219198
modifier = Modifier
220199
.weight(1f)
221200
.background(Color.Transparent),
222201
)
223-
// Right safe area
202+
if (!serverHandleInsets) {
203+
// Right safe area
204+
backgroundColor?.Overlay(
205+
modifier = Modifier
206+
.fillMaxHeight()
207+
.width(insetsPaddingValues.calculateRightPadding(LayoutDirection.Ltr)),
208+
)
209+
}
210+
}
211+
if (!serverHandleInsets) {
224212
backgroundColor?.Overlay(
225213
modifier = Modifier
226-
.fillMaxHeight()
227-
.width(insetsPaddingValues.calculateRightPadding(LayoutDirection.Ltr)),
214+
.fillMaxWidth()
215+
.height(insetsPaddingValues.calculateBottomPadding()),
228216
)
229217
}
230-
backgroundColor?.Overlay(
231-
modifier = Modifier
232-
.fillMaxWidth()
233-
.height(insetsPaddingValues.calculateBottomPadding()),
234-
)
235218
}
236219
}
237220

0 commit comments

Comments
 (0)