diff --git a/packages/frontend/apps/android/App/app/capacitor.build.gradle b/packages/frontend/apps/android/App/app/capacitor.build.gradle index 5ac6e7f126..34285effe4 100644 --- a/packages/frontend/apps/android/App/app/capacitor.build.gradle +++ b/packages/frontend/apps/android/App/app/capacitor.build.gradle @@ -12,7 +12,6 @@ dependencies { implementation project(':capacitor-app') implementation project(':capacitor-keyboard') implementation project(':capacitor-status-bar') - implementation project(':capawesome-capacitor-android-edge-to-edge-support') implementation project(':capgo-inappbrowser') } diff --git a/packages/frontend/apps/android/App/app/src/main/java/app/affine/pro/MainActivity.kt b/packages/frontend/apps/android/App/app/src/main/java/app/affine/pro/MainActivity.kt index 3f25829c89..17d731210b 100644 --- a/packages/frontend/apps/android/App/app/src/main/java/app/affine/pro/MainActivity.kt +++ b/packages/frontend/apps/android/App/app/src/main/java/app/affine/pro/MainActivity.kt @@ -1,10 +1,13 @@ package app.affine.pro import android.content.res.ColorStateList +import android.os.Bundle import android.view.Gravity import android.view.View import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.content.ContextCompat +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat import androidx.core.view.updateMargins import androidx.lifecycle.lifecycleScope import app.affine.pro.ai.AIActivity @@ -64,6 +67,16 @@ class MainActivity : BridgeActivity(), AIButtonPlugin.Callback, AffineThemePlugi } } + private var naviHeight = 0 + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(window.decorView) { v, insets -> + naviHeight = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom + ViewCompat.onApplyWindowInsets(v, insets) + } + } + override fun load() { super.load() AuthInitializer.initialize(bridge) @@ -96,6 +109,10 @@ class MainActivity : BridgeActivity(), AIButtonPlugin.Callback, AffineThemePlugi } } + override fun getSystemNaviBarHeight(): Int { + return naviHeight + } + override fun onClick(v: View) { lifecycleScope.launch { webService.update(bridge) diff --git a/packages/frontend/apps/android/App/app/src/main/java/app/affine/pro/plugin/AffineThemePlugin.kt b/packages/frontend/apps/android/App/app/src/main/java/app/affine/pro/plugin/AffineThemePlugin.kt index 25d3ffbe6b..9431bbc08c 100644 --- a/packages/frontend/apps/android/App/app/src/main/java/app/affine/pro/plugin/AffineThemePlugin.kt +++ b/packages/frontend/apps/android/App/app/src/main/java/app/affine/pro/plugin/AffineThemePlugin.kt @@ -1,5 +1,6 @@ package app.affine.pro.plugin +import com.getcapacitor.JSObject import com.getcapacitor.Plugin import com.getcapacitor.PluginCall import com.getcapacitor.PluginMethod @@ -11,6 +12,7 @@ class AffineThemePlugin : Plugin() { interface Callback { fun onThemeChanged(darkMode: Boolean) + fun getSystemNaviBarHeight(): Int } @PluginMethod @@ -20,4 +22,10 @@ class AffineThemePlugin : Plugin() { (bridge.activity as? Callback)?.onThemeChanged(darkMode) call.resolve() } + + @PluginMethod + fun getSystemNaviBarHeight(call: PluginCall) { + val height = (bridge.activity as? Callback)?.getSystemNaviBarHeight() ?: 0 + call.resolve(JSObject().put("height", height)) + } } \ No newline at end of file diff --git a/packages/frontend/apps/android/App/app/src/main/java/uniffi/affine_mobile_native/affine_mobile_native.kt b/packages/frontend/apps/android/App/app/src/main/java/uniffi/affine_mobile_native/affine_mobile_native.kt index 06c4fe4118..8d1ff7fb91 100644 --- a/packages/frontend/apps/android/App/app/src/main/java/uniffi/affine_mobile_native/affine_mobile_native.kt +++ b/packages/frontend/apps/android/App/app/src/main/java/uniffi/affine_mobile_native/affine_mobile_native.kt @@ -1303,6 +1303,70 @@ inline fun T.use(block: (T) -> R) = * @suppress * */ object NoPointer +/** + * The cleaner interface for Object finalization code to run. + * This is the entry point to any implementation that we're using. + * + * The cleaner registers objects and returns cleanables, so now we are + * defining a `UniffiCleaner` with a `UniffiClenaer.Cleanable` to abstract the + * different implmentations available at compile time. + * + * @suppress + */ +interface UniffiCleaner { + interface Cleanable { + fun clean() + } + + fun register(value: Any, cleanUpTask: Runnable): UniffiCleaner.Cleanable + + companion object +} + +// The fallback Jna cleaner, which is available for both Android, and the JVM. +private class UniffiJnaCleaner : UniffiCleaner { + private val cleaner = com.sun.jna.internal.Cleaner.getCleaner() + + override fun register(value: Any, cleanUpTask: Runnable): UniffiCleaner.Cleanable = + UniffiJnaCleanable(cleaner.register(value, cleanUpTask)) +} + +private class UniffiJnaCleanable( + private val cleanable: com.sun.jna.internal.Cleaner.Cleanable, +) : UniffiCleaner.Cleanable { + override fun clean() = cleanable.clean() +} + + +// We decide at uniffi binding generation time whether we were +// using Android or not. +// There are further runtime checks to chose the correct implementation +// of the cleaner. +private fun UniffiCleaner.Companion.create(): UniffiCleaner = + try { + // For safety's sake: if the library hasn't been run in android_cleaner = true + // mode, but is being run on Android, then we still need to think about + // Android API versions. + // So we check if java.lang.ref.Cleaner is there, and use that… + java.lang.Class.forName("java.lang.ref.Cleaner") + JavaLangRefCleaner() + } catch (e: ClassNotFoundException) { + // … otherwise, fallback to the JNA cleaner. + UniffiJnaCleaner() + } + +private class JavaLangRefCleaner : UniffiCleaner { + val cleaner = java.lang.ref.Cleaner.create() + + override fun register(value: Any, cleanUpTask: Runnable): UniffiCleaner.Cleanable = + JavaLangRefCleanable(cleaner.register(value, cleanUpTask)) +} + +private class JavaLangRefCleanable( + val cleanable: java.lang.ref.Cleaner.Cleanable +) : UniffiCleaner.Cleanable { + override fun clean() = cleanable.clean() +} /** * @suppress @@ -1529,70 +1593,6 @@ public object FfiConverterString: FfiConverter { // -/** - * The cleaner interface for Object finalization code to run. - * This is the entry point to any implementation that we're using. - * - * The cleaner registers objects and returns cleanables, so now we are - * defining a `UniffiCleaner` with a `UniffiClenaer.Cleanable` to abstract the - * different implmentations available at compile time. - * - * @suppress - */ -interface UniffiCleaner { - interface Cleanable { - fun clean() - } - - fun register(value: Any, cleanUpTask: Runnable): UniffiCleaner.Cleanable - - companion object -} - -// The fallback Jna cleaner, which is available for both Android, and the JVM. -private class UniffiJnaCleaner : UniffiCleaner { - private val cleaner = com.sun.jna.internal.Cleaner.getCleaner() - - override fun register(value: Any, cleanUpTask: Runnable): UniffiCleaner.Cleanable = - UniffiJnaCleanable(cleaner.register(value, cleanUpTask)) -} - -private class UniffiJnaCleanable( - private val cleanable: com.sun.jna.internal.Cleaner.Cleanable, -) : UniffiCleaner.Cleanable { - override fun clean() = cleanable.clean() -} - - -// We decide at uniffi binding generation time whether we were -// using Android or not. -// There are further runtime checks to chose the correct implementation -// of the cleaner. -private fun UniffiCleaner.Companion.create(): UniffiCleaner = - try { - // For safety's sake: if the library hasn't been run in android_cleaner = true - // mode, but is being run on Android, then we still need to think about - // Android API versions. - // So we check if java.lang.ref.Cleaner is there, and use that… - java.lang.Class.forName("java.lang.ref.Cleaner") - JavaLangRefCleaner() - } catch (e: ClassNotFoundException) { - // … otherwise, fallback to the JNA cleaner. - UniffiJnaCleaner() - } - -private class JavaLangRefCleaner : UniffiCleaner { - val cleaner = java.lang.ref.Cleaner.create() - - override fun register(value: Any, cleanUpTask: Runnable): UniffiCleaner.Cleanable = - JavaLangRefCleanable(cleaner.register(value, cleanUpTask)) -} - -private class JavaLangRefCleanable( - val cleanable: java.lang.ref.Cleaner.Cleanable -) : UniffiCleaner.Cleanable { - override fun clean() = cleanable.clean() -} public interface DocStoragePoolInterface { suspend fun `clearClocks`(`universalId`: kotlin.String) diff --git a/packages/frontend/apps/android/App/capacitor.settings.gradle b/packages/frontend/apps/android/App/capacitor.settings.gradle index a42220c996..ea13bcd033 100644 --- a/packages/frontend/apps/android/App/capacitor.settings.gradle +++ b/packages/frontend/apps/android/App/capacitor.settings.gradle @@ -11,8 +11,5 @@ project(':capacitor-keyboard').projectDir = new File('../../../../../node_module include ':capacitor-status-bar' project(':capacitor-status-bar').projectDir = new File('../../../../../node_modules/@capacitor/status-bar/android') -include ':capawesome-capacitor-android-edge-to-edge-support' -project(':capawesome-capacitor-android-edge-to-edge-support').projectDir = new File('../../../../../node_modules/@capawesome/capacitor-android-edge-to-edge-support/android') - include ':capgo-inappbrowser' project(':capgo-inappbrowser').projectDir = new File('../../../../../node_modules/@capgo/inappbrowser/android') diff --git a/packages/frontend/apps/android/capacitor.config.ts b/packages/frontend/apps/android/capacitor.config.ts index bd7d302f33..fc761f0ce5 100644 --- a/packages/frontend/apps/android/capacitor.config.ts +++ b/packages/frontend/apps/android/capacitor.config.ts @@ -25,6 +25,7 @@ const config: CapacitorConfig & AppConfig = { keystoreAliasPassword: process.env.AFFINE_ANDROID_KEYSTORE_ALIAS_PASSWORD, releaseType: 'AAB', }, + adjustMarginsForEdgeToEdge: 'force', }, server: { cleartext: true, diff --git a/packages/frontend/apps/android/package.json b/packages/frontend/apps/android/package.json index 63a02c19a1..e03d7ec209 100644 --- a/packages/frontend/apps/android/package.json +++ b/packages/frontend/apps/android/package.json @@ -23,7 +23,6 @@ "@capacitor/core": "^7.0.0", "@capacitor/keyboard": "^7.0.0", "@capacitor/status-bar": "^7.0.0", - "@capawesome/capacitor-android-edge-to-edge-support": "^7.0.0", "@capgo/inappbrowser": "^7.1.0", "@sentry/react": "^9.2.0", "@toeverything/infra": "workspace:*", diff --git a/packages/frontend/apps/android/src/app.tsx b/packages/frontend/apps/android/src/app.tsx index 9d7a695c93..ee7be9b110 100644 --- a/packages/frontend/apps/android/src/app.tsx +++ b/packages/frontend/apps/android/src/app.tsx @@ -40,7 +40,6 @@ import { import { App as CapacitorApp } from '@capacitor/app'; import { Keyboard } from '@capacitor/keyboard'; import { StatusBar, Style } from '@capacitor/status-bar'; -import { EdgeToEdge } from '@capawesome/capacitor-android-edge-to-edge-support'; import { InAppBrowser } from '@capgo/inappbrowser'; import { Framework, FrameworkRoot, getCurrentStore } from '@toeverything/infra'; import { OpClient } from '@toeverything/infra/op'; @@ -329,9 +328,6 @@ const ThemeProvider = () => { ? Style.Light : Style.Default, }).catch(console.error); - EdgeToEdge.setBackgroundColor({ - color: resolvedTheme === 'dark' ? '#000000' : '#F5F5F5', - }).catch(console.error); AffineTheme.onThemeChanged({ darkMode: resolvedTheme === 'dark', }).catch(console.error); diff --git a/packages/frontend/apps/android/src/plugins/affine-theme/definitions.ts b/packages/frontend/apps/android/src/plugins/affine-theme/definitions.ts index 62858a91b8..b02759610c 100644 --- a/packages/frontend/apps/android/src/plugins/affine-theme/definitions.ts +++ b/packages/frontend/apps/android/src/plugins/affine-theme/definitions.ts @@ -1,3 +1,4 @@ export interface AffineThemePlugin { onThemeChanged(options: { darkMode: boolean }): Promise; + getSystemNaviBarHeight(): Promise<{ height: number }>; } diff --git a/yarn.lock b/yarn.lock index 9e6c0b85da..1d6b2cf3b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -260,7 +260,6 @@ __metadata: "@capacitor/core": "npm:^7.0.0" "@capacitor/keyboard": "npm:^7.0.0" "@capacitor/status-bar": "npm:^7.0.0" - "@capawesome/capacitor-android-edge-to-edge-support": "npm:^7.0.0" "@capgo/inappbrowser": "npm:^7.1.0" "@sentry/react": "npm:^9.2.0" "@toeverything/infra": "workspace:*" @@ -4527,15 +4526,6 @@ __metadata: languageName: node linkType: hard -"@capawesome/capacitor-android-edge-to-edge-support@npm:^7.0.0": - version: 7.2.1 - resolution: "@capawesome/capacitor-android-edge-to-edge-support@npm:7.2.1" - peerDependencies: - "@capacitor/core": ">=7.0.0" - checksum: 10/6d84de3a7e8bc6dcd11809b00a295cc7269963e695b73ca036fbc7a60688cdbf8835a6e811709aeeb0cf15c8c1ac10f0ff597dee673a7597864aadafb879ca2e - languageName: node - linkType: hard - "@capgo/inappbrowser@npm:^7.1.0": version: 7.9.3 resolution: "@capgo/inappbrowser@npm:7.9.3"