super-productivity/capacitor.config.ts
Johannes Millan bb3ed74480
feat(android): migrate edge-to-edge to built-in SystemBars (#8543)
* feat(android): migrate edge-to-edge to built-in SystemBars

Replace @capawesome/capacitor-android-edge-to-edge-support with Capacitor 8's
built-in SystemBars (insetsHandling: 'css'). SystemBars handles edge-to-edge
insets + IME padding on WebView >= 140 / API >= 35; the WebView < 140 / API < 35
tail is covered by env() fallback plus a native keyboard shim
(adjustWebViewHeightForKeyboardBelowApi30), gated to WebView < 140 so it does
not fight SystemBars' own IME padding.

- config: drop EdgeToEdge plugin config + includePlugins entry + dep; remove the
  plugin from the generated gradle registration
- theme: stop JS-writing --safe-area-inset-* on Android (SystemBars owns them;
  the SCSS env() fallback preserves the #8283 top fix); bars are now transparent
  with the theme color painted behind them via setWebViewBackgroundColor, since
  SystemBars has no bar-color API
- StartupOverlayManager: derive the overlay inset from the system-bar insets
  instead of the removed plugin's WebView margin

Spike: TypeScript verified (tsc clean, lint clean). Kotlin and on-device
behavior NOT yet validated (gradle unavailable in this environment). Requires
`npm install` + `npx cap sync android` and the device matrix in
docs/plans/2026-06-22-android-systembars-migration-corrected.md before merge.

* build(deps): drop @capawesome edge-to-edge from lockfile

Reconcile package-lock.json with the package.json change in the edge-to-edge ->
SystemBars migration (removes only the @capawesome/capacitor-android-edge-to-edge-
support entry). Generated by `npm install`.

* docs(android): clarify SystemBars band model from implementation review

Comment-only + plan-doc follow-up to the multi-agent review of the migration:

- Correct the band model in the inset comments: SystemBars *injects*
  --safe-area-inset-* only on API >= 35; WebView >= 140 is native env()
  passthrough (no injection below API 35). The SCSS var(..., env()) fallback
  covers every band. (capacitor.config.ts, global-theme.service.ts)
- Fix a stale comment in StartupOverlayManager.show() that still described the
  removed @capawesome plugin insetting the WebView.
- Record the device-validation-only findings in the plan doc (API>=35/WebView<140
  double-count corner, env vs var consumer split, API 30-34/WebView<140 IME
  owner, CDK overlay top shift) so they are checked on the matrix, not blind-fixed
  (a blind shim extension would risk re-creating #8508).

No behavior change.
2026-06-22 16:07:06 +02:00

72 lines
2.7 KiB
TypeScript

import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.super-productivity.app',
appName: 'Super Productivity',
webDir: 'dist/browser',
plugins: {
CapacitorHttp: {
enabled: true,
},
LocalNotifications: {
// Android-specific: small icon for notification
smallIcon: 'ic_stat_sp',
},
Keyboard: {
// iOS-only: Android excludes @capacitor/keyboard via includePlugins below
// and uses JavaScriptInterface for keyboard visibility instead.
// 'native' resizes the WKWebView so 100vh fits above the keyboard.
resize: 'native',
// iOS-only; ignored on Android (plugin excluded). Kept false so the
// WKWebView is not force-resized in fullscreen.
resizeOnFullScreen: false,
},
StatusBar: {
// iOS: overlay the status bar so content can sit beneath it.
// No-op on Android 15+ (targetSdk 36).
overlaysWebView: true,
},
SystemBars: {
// Let Capacitor's built-in SystemBars own edge-to-edge inset handling on
// Android (replaces the @capawesome edge-to-edge plugin). 'css' enables
// SystemBars' Android inset handling: it *injects* --safe-area-inset-* CSS
// vars on API >= 35, and passes native env(safe-area-inset-*) through on
// WebView >= 140. The WebView <140 / API <35 tail gets neither and falls
// back to env() (plus the native keyboard shim in CapacitorMainActivity).
// See docs/plans/2026-06-22-android-systembars-migration-corrected.md.
insetsHandling: 'css',
// Initial bar icon style before the theme service boots; runtime updates
// go through StatusBar.setStyle / NavigationBar (global-theme.service.ts).
style: 'DARK',
},
},
android: {
// Android keyboard visibility is handled by JavaScriptInterface. Keeping
// @capacitor/keyboard Android-side registers an unused insets callback
// that can crash in Keyboard$1.onEnd on some devices.
includePlugins: [
'@capacitor/browser',
'@capacitor/status-bar',
'capacitor-plugin-safe-area',
'@capacitor/app',
'@capacitor/filesystem',
'@capacitor/local-notifications',
'@capacitor/share',
'@capawesome/capacitor-android-dark-mode-support',
'@capawesome/capacitor-background-task',
],
},
ios: {
// Content inset for safe areas (notch, home indicator)
contentInset: 'never',
// Background color for safe areas (home indicator, notch)
// Use dark color to match dark theme (most common on mobile)
backgroundColor: '#131314',
// Allow inline media playback
allowsLinkPreview: true,
// Scroll behavior
scrollEnabled: true,
},
};
export default config;