diff --git a/android/app/src/main/java/com/uplink/app/MainActivity.java b/android/app/src/main/java/com/uplink/app/MainActivity.java index 097717087..980bbf858 100644 --- a/android/app/src/main/java/com/uplink/app/MainActivity.java +++ b/android/app/src/main/java/com/uplink/app/MainActivity.java @@ -1,5 +1,13 @@ package com.uplink.app; import com.getcapacitor.BridgeActivity; +import com.uplink.plugins.SafeAreaColorPlugin; +import android.os.Bundle; -public class MainActivity extends BridgeActivity {} +public class MainActivity extends BridgeActivity { + @Override + public void onCreate(Bundle savedInstanceState) { + registerPlugin(SafeAreaColorPlugin.class); + super.onCreate(savedInstanceState); + } +} diff --git a/android/app/src/main/java/com/uplink/plugins/SafeAreaColorPlugin.java b/android/app/src/main/java/com/uplink/plugins/SafeAreaColorPlugin.java new file mode 100644 index 000000000..b656a0694 --- /dev/null +++ b/android/app/src/main/java/com/uplink/plugins/SafeAreaColorPlugin.java @@ -0,0 +1,60 @@ +package com.uplink.plugins; + +import android.app.Activity; +import android.os.Build; +import android.view.View; +import android.view.Window; +import androidx.annotation.NonNull; + +import com.getcapacitor.JSObject; +import com.getcapacitor.Plugin; +import com.getcapacitor.annotation.CapacitorPlugin; +import com.getcapacitor.PluginCall; +import com.getcapacitor.PluginMethod; + +@CapacitorPlugin(name = "SafeAreaColorPlugin") +public class SafeAreaColorPlugin extends Plugin { + + @PluginMethod + public void setStatusBarColor(PluginCall call) { + String color = call.getString("color"); + + if (color == null) { + call.reject("Color must be provided"); + return; + } + getActivity().runOnUiThread(() -> { + try { + Window window = getActivity().getWindow(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + window.setStatusBarColor(android.graphics.Color.parseColor(color)); + } + call.resolve(); + } catch (Exception e) { + call.reject("Failed to set status bar color", e); + } + }); + } + + @PluginMethod + public void setNavigationBarColor(PluginCall call) { + String color = call.getString("color"); + + if (color == null) { + call.reject("Color must be provided"); + return; + } + + getActivity().runOnUiThread(() -> { + try { + Window window = getActivity().getWindow(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + window.setNavigationBarColor(android.graphics.Color.parseColor(color)); + } + call.resolve(); + } catch (Exception e) { + call.reject("Failed to set navigation bar color", e); + } + }); + } +} diff --git a/src/lib/plugins/safeAreaColorAndroid.ts b/src/lib/plugins/safeAreaColorAndroid.ts new file mode 100644 index 000000000..02730a278 --- /dev/null +++ b/src/lib/plugins/safeAreaColorAndroid.ts @@ -0,0 +1,32 @@ +import { log } from "$lib/utils/Logger" +import { registerPlugin } from "@capacitor/core" + +interface ISafeAreaColorPlugin { + setStatusBarColor(options: { color: string }): Promise<{ value: string }> + setNavigationBarColor(options: { color: string }): Promise<{ value: string }> +} + +const SafeAreaColorPlugin = registerPlugin("SafeAreaColorPlugin") + +async function setStatusBarColor(color: string) { + try { + log.info("Calling native android function to change status bar color") + await SafeAreaColorPlugin.setStatusBarColor({ color }) + } catch (error) { + log.error("Error setting status bar color:", error) + } +} + +async function setNavigationBarColor(color: string) { + try { + log.info("Calling native android function to change navigation bar color") + await SafeAreaColorPlugin.setNavigationBarColor({ color }) + } catch (error) { + log.error("Error setting navigation bar color:", error) + } +} + +export function changeSafeAreaColorsOnAndroid(color: string) { + setStatusBarColor(color) + setNavigationBarColor(color) +} diff --git a/src/lib/utils/Mobile.ts b/src/lib/utils/Mobile.ts index 5eefd9b57..24ecfe19a 100644 --- a/src/lib/utils/Mobile.ts +++ b/src/lib/utils/Mobile.ts @@ -19,3 +19,11 @@ export function isAndroidOriOS(): boolean { } return platform === "ios" || platform === "android" } + +export function isAndroid(): boolean { + if (platform === null) { + log.warn("Platform info not yet loaded. Assuming 'false'.") + return false + } + return platform === "android" +} diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index b0267420e..03c9d4c0e 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -28,7 +28,8 @@ import Market from "$lib/components/market/Market.svelte" import { swipe } from "$lib/components/ui/Swipe" import { ScreenOrientation } from "@capacitor/screen-orientation" - import { fetchDeviceInfo, isAndroidOriOS } from "$lib/utils/Mobile" + import { fetchDeviceInfo, isAndroid, isAndroidOriOS } from "$lib/utils/Mobile" + import { changeSafeAreaColorsOnAndroid } from "$lib/plugins/safeAreaColorAndroid" log.debug("Initializing app, layout routes page.") @@ -224,8 +225,19 @@ UIStore.state.theme.subscribe(f => { theme = f style = buildStyle() + changeSafeAreaColors() }) + function changeSafeAreaColors() { + setTimeout(() => { + if (isAndroid()) { + const rootStyles = getComputedStyle(document.documentElement) + let mainBgColor = rootStyles.getPropertyValue("--background").trim() + changeSafeAreaColorsOnAndroid(mainBgColor) + } + }, 1000) + } + SettingsStore.state.subscribe(settings => { keybinds = settings.keybinds devmode = settings.devmode @@ -284,6 +296,7 @@ await checkIfUserIsLogged($page.route.id) await initializeLocale() buildStyle() + changeSafeAreaColors() })