[SDK-500] Follow the system light/dark theme in HTML in-app messages - #1084
[SDK-500] Follow the system light/dark theme in HTML in-app messages#1084franco-zalamena-iterable wants to merge 4 commits into
Conversation
HTML in-app messages always reported prefers-color-scheme: dark to the campaign HTML, so a campaign with an @media (prefers-color-scheme: dark) block rendered its dark styles even on a light-mode device. Two things combined, and either fix alone is inert: - Both in-app containers hard-coded a dark, non-DayNight AppCompat theme, so isLightTheme resolved false regardless of the configuration. - The fragment path built its WebView from the host activity context rather than the dialog's themed context. Reparent both containers onto Theme.AppCompat.DayNight.NoActionBar and give the fragment path's WebView the dialog context. DayNight resolves from the configuration uiMode, which is also what AppCompatDelegate.setDefaultNightMode manipulates - the analogue of iOS, where WKWebView inherits the system trait collection. Dark mode is unchanged: DayNight resolves to Theme.AppCompat.NoActionBar under values-night, which is the theme in use today. This development was started by contributor @AndrazP. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
joaodordio
left a comment
There was a problem hiding this comment.
Left a comment regarding the composer support and we also need a docs PR to cover these changes plz!
Other than that, all good!
| this.messageId = ""; | ||
| insetPadding = new Rect(); | ||
| this.setStyle(DialogFragment.STYLE_NO_FRAME, androidx.appcompat.R.style.Theme_AppCompat_NoActionBar); | ||
| this.setStyle(DialogFragment.STYLE_NO_FRAME, androidx.appcompat.R.style.Theme_AppCompat_DayNight_NoActionBar); |
There was a problem hiding this comment.
This is the right fix for apps that follow the system or use AppCompatDelegate.setDefaultNightMode, but it leaves Compose apps that keep their theme in Compose state with no way to influence it.
A Compose app on a light-mode device with the user set to dark currently gets a dark in-app and will get a light one after this. The Dialog path exists for exactly those apps (#1015), so I don't think we can ship this without either an IterableConfig override for the in-app color scheme, or an explicit docs note telling those integrators to call setDefaultNightMode. Which one do you think it's better? Or am I missing something on the Compose support side?
There was a problem hiding this comment.
Good catch. I tested the documentation-only AppCompatDelegate.setDefaultNightMode option against the pure ComponentActivity path, and the dialog stayed light, so that would not reliably cover Compose-managed theme state.
I added an explicit config API in c34ff01:
setInAppColorScheme()for a fixedAUTOMATIC/LIGHT/DARKvaluesetInAppColorSchemeProvider()for Compose state; it is queried whenever an in-app container is created
The tests cover explicit overrides on both the Fragment and Dialog renderers and changing the provider value between two Dialog in-apps. The documentation is staged in Iterable/iterable-docs on docs/sdk/september-release at b6cfb52cc; its PR will be opened with the September SDK release.
Summary
Jira ticket: SDK-500
Description
A campaign with an
@media (prefers-color-scheme: dark)block rendered its dark styles even in light mode. WebView takesprefers-color-schemefrom theisLightThemeattribute of its context's theme, and both in-app containers were pinned to a non-DayNight AppCompat theme (always dark). On top of that, the fragment path built its WebView from the host activity instead of the dialog, so fixing the theme alone did nothing.Both containers now use a DayNight theme and the WebView gets the dialog's context. In the default
AUTOMATICmode, the in-app follows the host activity's Android UI mode.Apps that keep their theme only in Compose state can configure
IterableConfig.Builder.setInAppColorScheme()for a fixed override orsetInAppColorSchemeProvider()for a value that is evaluated whenever an in-app message is created.Documentation is staged on the
Iterable/iterable-docsbranchdocs/sdk/september-releasein commitb6cfb52cc. The documentation PR willbe opened with the September SDK release.
Worth calling out: in
AUTOMATICmode, an app with a hard-coded light theme running on a dark-mode device gets a dark in-app. Apps that need the in-app to follow a separately managed theme can use the explicit override.This development was started by contributor @AndrazP.
Addresses #1056 and supersedes #1057, which only covered the fragment path. The Dialog path used by Compose apps (#1015) had the same problem.
Docs branch created for the september release: https://github.com/Iterable/iterable-docs/tree/docs/sdk/september-release
SDK-500-before-after.mp4