From f5857e216273b9555548259883fa5ddc82279eb4 Mon Sep 17 00:00:00 2001 From: Fredrik Burmester Date: Sun, 27 Oct 2024 12:37:46 +0100 Subject: [PATCH] fix: native pill look on android --- app.json | 3 +- app/(auth)/(tabs)/_layout.tsx | 30 +++++++--- plugins/withNativeStyles.js | 110 ++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 8 deletions(-) create mode 100644 plugins/withNativeStyles.js diff --git a/app.json b/app.json index 00b060b9..ee1e3abb 100644 --- a/app.json +++ b/app.json @@ -99,7 +99,8 @@ { "motionPermission": "Allow Streamyfin to access your device motion for landscape video watching." } - ] + ], + "./plugins/withNativeStyles.js" ], "experiments": { "typedRoutes": true diff --git a/app/(auth)/(tabs)/_layout.tsx b/app/(auth)/(tabs)/_layout.tsx index 9c3cedb0..9224fc83 100644 --- a/app/(auth)/(tabs)/_layout.tsx +++ b/app/(auth)/(tabs)/_layout.tsx @@ -18,6 +18,7 @@ import type { TabNavigationState, } from "@react-navigation/native"; import {} from "@expo/vector-icons/Ionicons"; +import { Colors } from "@/constants/Colors"; export const NativeTabs = withLayoutContext< BottomTabNavigationOptions, @@ -35,30 +36,45 @@ export default function TabLayout() { }, []); return ( - + - require("@/assets/icons/house.fill.png"), + tabBarIcon: + Platform.OS == "android" + ? ({ color, focused, size }) => + require("@/assets/icons/house.fill.png") + : () => ({ sfSymbol: "house" }), }} /> - require("@/assets/icons/magnifyingglass.png"), + tabBarIcon: + Platform.OS == "android" + ? ({ color, focused, size }) => + require("@/assets/icons/magnifyingglass.png") + : () => ({ sfSymbol: "magnifyingglass" }), }} /> - require("@/assets/icons/server.rack.png"), + tabBarIcon: + Platform.OS == "android" + ? ({ color, focused, size }) => + require("@/assets/icons/server.rack.png") + : () => ({ sfSymbol: "rectangle.stack" }), }} /> diff --git a/plugins/withNativeStyles.js b/plugins/withNativeStyles.js new file mode 100644 index 00000000..81d80326 --- /dev/null +++ b/plugins/withNativeStyles.js @@ -0,0 +1,110 @@ +const { withAndroidStyles, withDangerousMod } = require("@expo/config-plugins"); +const fs = require("fs"); +const path = require("path"); + +function withNativeTabBarStyles(config) { + // First, apply the styles modifications + config = withAndroidStyles(config, async (config) => { + const styleContents = config.modResults; + + // Find or create the AppTheme style + let appTheme = styleContents.resources.style.find( + (style) => style.$.name === "AppTheme" + ); + + if (!appTheme) { + appTheme = { + $: { + name: "AppTheme", + parent: "Theme.Material3.DayNight.NoActionBar", + }, + item: [], + }; + styleContents.resources.style.push(appTheme); + } else { + appTheme.$.parent = "Theme.Material3.DayNight.NoActionBar"; + } + + // Update or add items in the AppTheme style + const itemsToAdd = [ + { + name: "android:editTextBackground", + value: "@drawable/rn_edit_text_material", + }, + { + name: "bottomNavigationStyle", + value: "@style/Widget.Material3.BottomNavigationView", + }, + { + name: "android:navigationBarColor", + value: "@android:color/transparent", + }, + { name: "android:statusBarColor", value: "@android:color/transparent" }, + ]; + + itemsToAdd.forEach(({ name, value }) => { + const existingItem = appTheme.item.find((item) => item.$.name === name); + if (existingItem) { + existingItem._ = value; + } else { + appTheme.item.push({ + $: { name }, + _: value, + }); + } + }); + + // Add custom bottom navigation style + styleContents.resources.style.push({ + $: { + name: "Widget.Material3.BottomNavigationView", + parent: "@style/Widget.Material3.BottomNavigationView", + }, + item: [ + { + $: { name: "android:layout_margin" }, + _: "16dp", + }, + { + $: { name: "android:background" }, + _: "@drawable/bottom_nav_background", + }, + ], + }); + + return { + ...config, + modResults: styleContents, + }; + }); + + // Then, add the drawable file creation + return withDangerousMod(config, [ + "android", + async (config) => { + const drawablePath = path.join( + config.modRequest.platformProjectRoot, + "app", + "src", + "main", + "res", + "drawable" + ); + const filePath = path.join(drawablePath, "bottom_nav_background.xml"); + + const fileContent = ` + + + +`; + + await fs.promises.mkdir(drawablePath, { recursive: true }); + await fs.promises.writeFile(filePath, fileContent); + + return config; + }, + ]); +} + +module.exports = withNativeTabBarStyles;