Android navigation bar theming, hotupdater switch to fingerprint deployment

This commit is contained in:
minibits-cash
2026-03-18 05:47:10 -07:00
parent 3456805ebe
commit c0312d770c
14 changed files with 192 additions and 127 deletions

View File

@@ -95,7 +95,7 @@ android {
applicationId "com.minibits_wallet" applicationId "com.minibits_wallet"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 58065 versionCode 58068
versionName "0.4.0" versionName "0.4.0"
} }

View File

@@ -1,4 +1,4 @@
<resources> <resources>
<string name="app_name">Minibits</string> <string name="app_name">Minibits</string>
<string name="hot_updater_fingerprint_hash" moduleConfig="true">440d1216e37cbc37f8613487dc90c89d54f1c1b6</string> <string name="hot_updater_fingerprint_hash" moduleConfig="true">52a90c95e5a8b3d48b60c5a12a638832479c59ae</string>
</resources> </resources>

View File

@@ -1,13 +1,16 @@
<resources> <resources>
<!-- Base application theme. --> <!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar"> <style name="AppTheme" parent="Theme.EdgeToEdge">
<!-- Customize your theme here. --> <!-- Customize your theme here. -->
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item> <item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
<!-- Fixed dark window background shown before React Native renders its first frame. <!-- Fixed dark window background shown before React Native renders its first frame.
Matches the dark app themes (DEFAULT/DARK/GOLDEN). For LIGHT theme, the JS Matches the dark app themes (DEFAULT/DARK/GOLDEN). For LIGHT theme, the JS
splash view overrides this immediately on first render. --> splash view overrides this immediately on first render. -->
<item name="android:windowBackground">#2e2e2e</item> <item name="android:windowBackground">#2e2e2e</item>
<!-- Disable automatic contrast enforcement so the JS-side SystemBars component
can explicitly control nav bar icon colors to match the app theme. -->
<item name="enforceNavigationBarContrast">false</item>
</style> </style>
</resources> </resources>

File diff suppressed because one or more lines are too long

View File

@@ -33,5 +33,5 @@ export default defineConfig({
projectId: process.env.HOT_UPDATER_FIREBASE_PROJECT_ID!, projectId: process.env.HOT_UPDATER_FIREBASE_PROJECT_ID!,
credential, credential,
}), }),
updateStrategy: "appVersion", // or "fingerprint" updateStrategy: "fingerprint",
}); });

View File

@@ -44,9 +44,9 @@
<key>NFCReaderUsageDescription</key> <key>NFCReaderUsageDescription</key>
<string>This app uses NFC to pay on supported POS</string> <string>This app uses NFC to pay on supported POS</string>
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key> <key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array> <array>
<string>D2760000850101</string> <string>D2760000850101</string>
</array> </array>
<key>RCTNewArchEnabled</key> <key>RCTNewArchEnabled</key>
<true/> <true/>
<key>UIAppFonts</key> <key>UIAppFonts</key>
@@ -77,7 +77,7 @@
<key>UIViewControllerBasedStatusBarAppearance</key> <key>UIViewControllerBasedStatusBarAppearance</key>
<false/> <false/>
<key>HOT_UPDATER_FINGERPRINT_HASH</key> <key>HOT_UPDATER_FINGERPRINT_HASH</key>
<string>98c1f26187f02f38ddef1fcb75384246a1c5fa03</string> <string>52a90c95e5a8b3d48b60c5a12a638832479c59ae</string>
<key>CFBundleIcons</key> <key>CFBundleIcons</key>
<dict> <dict>
<key>CFBundlePrimaryIcon</key> <key>CFBundlePrimaryIcon</key>

View File

@@ -1,6 +1,6 @@
{ {
"name": "minibits_wallet", "name": "minibits_wallet",
"version": "0.4.0-beta.1", "version": "0.4.0-beta.2",
"private": true, "private": true,
"scripts": { "scripts": {
"android:clean": "cd android && ./gradlew clean", "android:clean": "cd android && ./gradlew clean",
@@ -61,6 +61,7 @@
"react-native-animated-pagination-dots": "^0.1.73", "react-native-animated-pagination-dots": "^0.1.73",
"react-native-camera-kit": "16.2.1", "react-native-camera-kit": "16.2.1",
"react-native-change-icon": "^3.0.0", "react-native-change-icon": "^3.0.0",
"react-native-edge-to-edge": "^1.8.1",
"react-native-exit-app": "^2.0.0", "react-native-exit-app": "^2.0.0",
"react-native-fast-image": "^8.6.3", "react-native-fast-image": "^8.6.3",
"react-native-flash-message": "^0.4.2", "react-native-flash-message": "^0.4.2",

View File

@@ -16,6 +16,7 @@ import {ErrorBoundary} from './screens/ErrorScreen/ErrorBoundary'
import Config from './config' import Config from './config'
import {log} from './services' import {log} from './services'
import { Image, TextStyle, View } from 'react-native' import { Image, TextStyle, View } from 'react-native'
import { SystemBars } from 'react-native-edge-to-edge'
import { ThemeCode, colors, spacing, typography } from './theme' import { ThemeCode, colors, spacing, typography } from './theme'
import useColorScheme from './theme/useThemeColor' import useColorScheme from './theme/useThemeColor'
import { displayName } from '../app.json' import { displayName } from '../app.json'
@@ -190,6 +191,7 @@ function App() {
return ( return (
<SafeAreaProvider> <SafeAreaProvider>
<SystemBars style={isLight ? 'dark' : 'light'} />
<Screen preset='fixed' backgroundColor={splashBg} safeAreaEdges={['top', 'bottom']}> <Screen preset='fixed' backgroundColor={splashBg} safeAreaEdges={['top', 'bottom']}>
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}> <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Image source={isGolden <Image source={isGolden

View File

@@ -7,7 +7,6 @@ import {
View, View,
ViewStyle, ViewStyle,
StatusBar, StatusBar,
StatusBarProps,
ColorValue, ColorValue,
Platform Platform
} from "react-native" } from "react-native"
@@ -142,10 +141,6 @@ export interface HeaderProps {
* Override the default edges for the safe area. * Override the default edges for the safe area.
*/ */
safeAreaEdges?: ExtendedEdge[] safeAreaEdges?: ExtendedEdge[]
/**
* Pass any additional props directly to the StatusBar component.
*/
StatusBarProps?: StatusBarProps
/** /**
* Shared value from scroll position for animated title. * Shared value from scroll position for animated title.
* When provided, the title will fade in as the user scrolls. * When provided, the title will fade in as the user scrolls.
@@ -170,11 +165,12 @@ interface HeaderActionProps {
} }
/* Needed to keep status bar styles on navigation tabs */ /* Keeps status bar style in sync with navigation focus — only applies when this screen is active.
function FocusAwareStatusBar(props: StatusBarProps) { Uses React Native's StatusBar (status bar only) so it does not override the nav bar icon style
const isFocused = useIsFocused(); managed by the root SystemBars in AppNavigator. */
function FocusAwareStatusBar() {
return isFocused ? <StatusBar translucent={true} {...props} /> : null; const isFocused = useIsFocused()
return isFocused ? <StatusBar translucent barStyle="light-content" /> : null
} }
/** /**
@@ -213,7 +209,6 @@ export function Header(props: HeaderProps) {
style: $styleOverride, style: $styleOverride,
titleStyle: $titleStyleOverride, titleStyle: $titleStyleOverride,
containerStyle: $containerStyleOverride, containerStyle: $containerStyleOverride,
StatusBarProps,
scrollY, scrollY,
scrollDistance = 60, scrollDistance = 60,
} = props } = props
@@ -237,10 +232,7 @@ export function Header(props: HeaderProps) {
return ( return (
<View style={[$container, $containerInsets, { backgroundColor }, $containerStyleOverride]}> <View style={[$container, $containerInsets, { backgroundColor }, $containerStyleOverride]}>
<FocusAwareStatusBar <FocusAwareStatusBar />
barStyle = 'light-content'
{...StatusBarProps}
/>
<View style={[$wrapper, $styleOverride]}> <View style={[$wrapper, $styleOverride]}>
<HeaderAction <HeaderAction
tx={leftTx} tx={leftTx}

View File

@@ -1,8 +1,8 @@
import { import {
createStaticNavigation, createStaticNavigation,
DarkTheme, DarkTheme,
DefaultTheme, DefaultTheme,
StaticParamList, StaticParamList,
} from "@react-navigation/native" } from "@react-navigation/native"
import { createNativeStackNavigator } from "@react-navigation/native-stack" import { createNativeStackNavigator } from "@react-navigation/native-stack"
import { observer } from "mobx-react-lite" import { observer } from "mobx-react-lite"
@@ -11,7 +11,7 @@ import Config from "../config"
import { import {
WelcomeScreen, WelcomeScreen,
SeedRecoveryScreen, SeedRecoveryScreen,
MintsScreen, MintsScreen,
SeedRecoveryOptionsScreen, SeedRecoveryOptionsScreen,
ImportBackupScreen, ImportBackupScreen,
RecoverWalletAddressScreen, RecoverWalletAddressScreen,
@@ -21,8 +21,10 @@ import {
import { rootStoreInstance } from "../models" import { rootStoreInstance } from "../models"
import { TabsNavigator } from "./TabsNavigator" import { TabsNavigator } from "./TabsNavigator"
import { navigationRef, useBackButtonHandler } from "./navigationUtilities" import { navigationRef, useBackButtonHandler } from "./navigationUtilities"
import { useThemeColor } from "../theme" import { ThemeCode, useThemeColor } from "../theme"
import useColorScheme from "../theme/useThemeColor" import useColorScheme from "../theme/useThemeColor"
import { MMKVStorage } from "../services"
import { SystemBars } from "react-native-edge-to-edge"
/** /**
@@ -65,7 +67,12 @@ export const AppNavigator = observer(function AppNavigator() {
useBackButtonHandler((routeName) => exitRoutes.includes(routeName)) useBackButtonHandler((routeName) => exitRoutes.includes(routeName))
const dark = useColorScheme() === 'dark' ? true : false const colorScheme = useColorScheme()
const dark = colorScheme === 'dark'
const theme = MMKVStorage.loadTheme()
const isLightTheme = theme === ThemeCode.LIGHT ||
(theme === ThemeCode.DEFAULT && colorScheme === 'light')
const background = useThemeColor('background') as string const background = useThemeColor('background') as string
const primary = useThemeColor('tabActiveIcon') as string const primary = useThemeColor('tabActiveIcon') as string
const card = useThemeColor('background') as string const card = useThemeColor('background') as string
@@ -90,10 +97,13 @@ export const AppNavigator = observer(function AppNavigator() {
} }
return ( return (
<Navigation <>
// @ts-ignore <SystemBars style={isLightTheme ? "dark" : "light"} />
ref={navigationRef} <Navigation
theme={NavigationTheme} // @ts-ignore
/> ref={navigationRef}
theme={NavigationTheme}
/>
</>
) )
}) })

View File

@@ -72,7 +72,7 @@ export const SettingsScreen = observer(function SettingsScreen({ route }: Props)
try { try {
const updateInfo = await HotUpdater.checkForUpdate({ const updateInfo = await HotUpdater.checkForUpdate({
source: getUpdateSource(HOT_UPDATER_URL, { source: getUpdateSource(HOT_UPDATER_URL, {
updateStrategy: "appVersion", updateStrategy: "fingerprint",
}), }),
requestHeaders: { requestHeaders: {
Authorization: `Bearer ${HOT_UPDATER_API_KEY}`, Authorization: `Bearer ${HOT_UPDATER_API_KEY}`,

View File

@@ -91,7 +91,7 @@ export const UpdateScreen = observer(function UpdateScreen({ route }: Props) {
setIsUpdateModalVisible(true) setIsUpdateModalVisible(true)
const updateInfo = await HotUpdater.checkForUpdate({ const updateInfo = await HotUpdater.checkForUpdate({
source: getUpdateSource(HOT_UPDATER_URL, { source: getUpdateSource(HOT_UPDATER_URL, {
updateStrategy: "appVersion", updateStrategy: "fingerprint",
}), }),
requestHeaders: { requestHeaders: {
Authorization: `Bearer ${HOT_UPDATER_API_KEY}`, Authorization: `Bearer ${HOT_UPDATER_API_KEY}`,

View File

@@ -128,7 +128,7 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
try { try {
const updateInfo = await HotUpdater.checkForUpdate({ const updateInfo = await HotUpdater.checkForUpdate({
source: getUpdateSource(HOT_UPDATER_URL, { source: getUpdateSource(HOT_UPDATER_URL, {
updateStrategy: "appVersion", updateStrategy: "fingerprint",
}), }),
requestHeaders: { requestHeaders: {
Authorization: `Bearer ${HOT_UPDATER_API_KEY}`, Authorization: `Bearer ${HOT_UPDATER_API_KEY}`,

View File

@@ -14672,6 +14672,7 @@ __metadata:
react-native-change-icon: ^3.0.0 react-native-change-icon: ^3.0.0
react-native-clean-project: ^4.0.3 react-native-clean-project: ^4.0.3
react-native-dotenv: ^3.4.11 react-native-dotenv: ^3.4.11
react-native-edge-to-edge: ^1.8.1
react-native-exit-app: ^2.0.0 react-native-exit-app: ^2.0.0
react-native-fast-image: ^8.6.3 react-native-fast-image: ^8.6.3
react-native-flash-message: ^0.4.2 react-native-flash-message: ^0.4.2
@@ -16530,6 +16531,16 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-native-edge-to-edge@npm:^1.8.1":
version: 1.8.1
resolution: "react-native-edge-to-edge@npm:1.8.1"
peerDependencies:
react: "*"
react-native: "*"
checksum: 712081dffc84c8c65cae99732b3ecb7cae2c4dfa49c18855a317a27370be96f87397f628c8d174a8819a383eb83a5011e6785a8040aaedb15b14baf1083ba882
languageName: node
linkType: hard
"react-native-exit-app@npm:^2.0.0": "react-native-exit-app@npm:^2.0.0":
version: 2.0.0 version: 2.0.0
resolution: "react-native-exit-app@npm:2.0.0" resolution: "react-native-exit-app@npm:2.0.0"