Files
orca/mobile/plugins/android-navigation-bar-theme.js

53 lines
1.9 KiB
JavaScript

const { withMainActivity } = require('expo/config-plugins')
// Why: edge-to-edge picks the navigation bar's light or dark look (and the contrast scrim drawn
// behind it) once, from the phone's theme at launch (#34246). MainActivity handles uiMode itself,
// so Orca's own theme choice and later phone switches never reach the bar, leaving a white scrim
// under a dark app. AppCompat reports both through onConfigurationChanged with the resolved uiMode.
const MARKER = 'orca: navigation bar theme'
const CLASS_HEADER = 'class MainActivity : ReactActivity() {'
const IMPORTS = [
'android.content.res.Configuration',
'androidx.core.view.WindowInsetsControllerCompat'
]
const INIT_BLOCK = `
// ${MARKER}, generated by plugins/android-navigation-bar-theme.js.
init {
addOnConfigurationChangedListener { config ->
val dark = config.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightNavigationBars = !dark
}
}
`
function patchMainActivity(contents) {
if (contents.includes(MARKER)) {
return contents
}
if (!contents.includes(CLASS_HEADER)) {
throw new Error(
"android-navigation-bar-theme: Expo's MainActivity template changed; update the plugin before building."
)
}
const imports = IMPORTS.filter((name) => !contents.includes(`import ${name}\n`))
.map((name) => `import ${name}\n`)
.join('')
return contents
.replace(/^(package [^\n]+\n)/, `$1${imports}`)
.replace(CLASS_HEADER, `${CLASS_HEADER}\n${INIT_BLOCK}`)
}
module.exports = function withAndroidNavigationBarTheme(config) {
return withMainActivity(config, (cfg) => {
if (cfg.modResults.language !== 'kt') {
throw new Error(
`android-navigation-bar-theme: expected a Kotlin MainActivity, got ${cfg.modResults.language}`
)
}
cfg.modResults.contents = patchMainActivity(cfg.modResults.contents)
return cfg
})
}