diff --git a/android/App.js b/android/App.js index b414139..670629d 100644 --- a/android/App.js +++ b/android/App.js @@ -59,6 +59,7 @@ import { SafeAreaProvider, useSafeAreaInsets, } from "react-native-safe-area-context"; +import { LinearGradient } from "expo-linear-gradient"; // Replaced @gorhom/bottom-sheet with SimpleActionSheet import SimpleActionSheet from "./components/SimpleActionSheet"; import TokenIcon from "./src/components/TokenIcon"; @@ -2091,19 +2092,19 @@ function AppContent() { const handleCreateNewWallet = async () => { setShowAddWalletModal(false); - // If master seed phrase already exists, create wallet directly without showing seed phrase + // Always show seed phrase modal when creating wallet + // If master seed phrase already exists, use it; otherwise generate new one if (masterSeedPhrase) { - console.log("Master seed phrase exists, creating wallet directly"); - await handleConfirmCreateWallet(); - return; + console.log("Master seed phrase exists, showing it for backup"); + setNewMnemonic(masterSeedPhrase); + } else { + // First wallet - generate master seed phrase and show it for backup + const newMasterSeed = bip39.generateMnemonic(); + setMasterSeedPhrase(newMasterSeed); + await saveMasterSeedPhrase(newMasterSeed); + setNewMnemonic(newMasterSeed); + console.log("Generated and saved new master seed phrase"); } - - // First wallet - generate master seed phrase and show it for backup - const newMasterSeed = bip39.generateMnemonic(); - setMasterSeedPhrase(newMasterSeed); - await saveMasterSeedPhrase(newMasterSeed); - setNewMnemonic(newMasterSeed); - console.log("Generated and saved new master seed phrase"); setShowCreateWalletModal(true); }; @@ -3430,6 +3431,66 @@ function AppContent() { ); } + // Show empty state when no wallets exist (but not when modals are open) + if (authState === "unlocked" && wallets.length === 0 && !showCreateWalletModal && !showAddWalletModal && !showImportWalletModal) { + return ( + + + ); + } + return ( <> @@ -7815,6 +7876,93 @@ const styles = StyleSheet.create({ color: "#4A90E2", fontWeight: "600", }, + // Empty State Styles + emptyStateContainer: { + flex: 1, + position: "relative", + }, + emptyStateBackground: { + position: "absolute", + top: 0, + left: 0, + right: 0, + bottom: 0, + width: "100%", + height: "100%", + }, + emptyStateGradientOverlay: { + position: "absolute", + top: 0, + left: 0, + right: 0, + bottom: 0, + width: "100%", + height: "100%", + }, + emptyStateContent: { + flex: 1, + justifyContent: "center", + alignItems: "center", + paddingHorizontal: 40, + }, + emptyStateLogoContainer: { + position: "relative", + alignItems: "center", + justifyContent: "center", + marginBottom: 24, + }, + emptyStateLogoBlur: { + position: "absolute", + width: 120, + height: 120, + zIndex: 0, + }, + emptyStateLogo: { + width: 120, + height: 120, + zIndex: 1, + }, + emptyStateTitle: { + fontSize: 32, + fontWeight: "bold", + color: "#FFFFFF", + marginBottom: 60, + textAlign: "center", + }, + emptyStateButtons: { + width: "100%", + }, + emptyStateCreateButton: { + backgroundColor: "#4A90E2", + borderRadius: 12, + paddingVertical: 16, + paddingHorizontal: 24, + alignItems: "center", + justifyContent: "center", + width: "100%", + marginBottom: 16, + }, + emptyStateCreateButtonText: { + fontSize: 16, + fontWeight: "600", + color: "#FFFFFF", + }, + emptyStateImportButton: { + backgroundColor: "#1a1a1a", + borderRadius: 12, + paddingVertical: 16, + paddingHorizontal: 24, + alignItems: "center", + justifyContent: "center", + width: "100%", + borderWidth: 1, + borderColor: "#333333", + }, + emptyStateImportButtonText: { + fontSize: 16, + fontWeight: "600", + color: "#FFFFFF", + }, // QR Scanner styles scanIcon: { width: 24, @@ -7832,9 +7980,6 @@ const styles = StyleSheet.create({ qrOverlayTop: { flex: 1, backgroundColor: "rgba(0, 0, 0, 0.6)", - justifyContent: "center", - alignItems: "center", - paddingHorizontal: 40, }, qrOverlayMiddle: { flexDirection: "row", diff --git a/android/assets/bg.png b/android/assets/bg.png new file mode 100644 index 0000000..df8463a Binary files /dev/null and b/android/assets/bg.png differ diff --git a/android/assets/x1-logo-with-blur.png b/android/assets/x1-logo-with-blur.png new file mode 100644 index 0000000..daf54c3 Binary files /dev/null and b/android/assets/x1-logo-with-blur.png differ diff --git a/android/assets/x1-wallet.png b/android/assets/x1-wallet.png new file mode 100644 index 0000000..eefceb1 Binary files /dev/null and b/android/assets/x1-wallet.png differ diff --git a/android/clean_build.sh b/android/clean_build.sh new file mode 100755 index 0000000..49a3bce --- /dev/null +++ b/android/clean_build.sh @@ -0,0 +1,2 @@ +!#bin/sh +cd /Users/wei/projects/backpack-android-2/android/android && rm -rf app/.cxx app/build .gradle build && find . -name ".cxx" -type d -exec rm -rf {} + 2>/dev/null || true diff --git a/android/package-lock.json b/android/package-lock.json index fa51fc1..a5066e2 100644 --- a/android/package-lock.json +++ b/android/package-lock.json @@ -29,6 +29,7 @@ "expo": "~54.0.23", "expo-camera": "^17.0.9", "expo-clipboard": "~8.0.7", + "expo-linear-gradient": "^15.0.7", "expo-local-authentication": "^17.0.7", "expo-secure-store": "~15.0.7", "expo-status-bar": "~3.0.8", @@ -76,7 +77,6 @@ "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.14.0.tgz", "integrity": "sha512-0YQKKRIxiMlIou+SekQqdCo0ZTHxOcES+K8vKB53cIDpwABNR0P0yRzPgsbgcj3zRJniD93S/ontsnZsCLZrxQ==", "license": "MIT", - "peer": true, "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@wry/caches": "^1.0.0", @@ -142,7 +142,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -3224,7 +3223,6 @@ "integrity": "sha512-gXlD85hqDDC0C1e2on0pTJoV6pOL3ZJBRDbAzAqSa8Q6Y76tHWqsNTTBuipTjzr/9yFxqPp96p/i/P6lMMsvLg==", "hasInstallScript": true, "license": "MIT", - "peer": true, "dependencies": { "canvaskit-wasm": "0.40.0", "react-reconciler": "0.31.0" @@ -3482,7 +3480,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.17.tgz", "integrity": "sha512-Qec1E3mhALmaspIrhWt9jkQMNdw6bReVu64mjvhbhq2NFPftLPVr+l1SZgmw/66WwBNpDh7ao5AT6gF5v41PFA==", "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -4318,7 +4315,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", @@ -5432,7 +5428,6 @@ "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.23.tgz", "integrity": "sha512-b4uQoiRwQ6nwqsT2709RS15CWYNGF3eJtyr1KyLw9WuMAK7u4jjofkhRiO0+3o1C2NbV+WooyYTOZGubQQMBaQ==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "54.0.16", @@ -5511,6 +5506,17 @@ "react-native": "*" } }, + "node_modules/expo-linear-gradient": { + "version": "15.0.7", + "resolved": "https://registry.npmjs.org/expo-linear-gradient/-/expo-linear-gradient-15.0.7.tgz", + "integrity": "sha512-yF+y+9Shpr/OQFfy/wglB/0bykFMbwHBTuMRa5Of/r2P1wbkcacx8rg0JsUWkXH/rn2i2iWdubyqlxSJa3ggZA==", + "license": "MIT", + "peerDependencies": { + "expo": "*", + "react": "*", + "react-native": "*" + } + }, "node_modules/expo-local-authentication": { "version": "17.0.7", "resolved": "https://registry.npmjs.org/expo-local-authentication/-/expo-local-authentication-17.0.7.tgz", @@ -5931,7 +5937,6 @@ "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.9.tgz", "integrity": "sha512-xCoQbR/36qqB6tew/LQ6GWICpaBmHLhg/Loix5Rku/0ZtNaXMJv08M9o1AcrdiGTn/Xf/BnLu6DgS45cWQEHZg==", "license": "MIT", - "peer": true, "dependencies": { "fontfaceobserver": "^2.1.0" }, @@ -6417,7 +6422,6 @@ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.12.0.tgz", "integrity": "sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==", "license": "MIT", - "peer": true, "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } @@ -9436,7 +9440,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -9474,7 +9477,6 @@ "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.81.5.tgz", "integrity": "sha512-1w+/oSjEXZjMqsIvmkCRsOc8UBYv163bTWKTI8+1mxztvQPhCRYGTvZ/PL1w16xXHneIj/SLGfxWg2GWN2uexw==", "license": "MIT", - "peer": true, "dependencies": { "@jest/create-cache-key-function": "^29.7.0", "@react-native/assets-registry": "0.81.5", @@ -9556,7 +9558,6 @@ "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.28.0.tgz", "integrity": "sha512-0msfJ1vRxXKVgTgvL+1ZOoYw3/0z1R+Ked0+udoJhyplC2jbVKIJ8Z1bzWdpQRCV3QcQ87Op0zJVE5DhKK2A0A==", "license": "MIT", - "peer": true, "dependencies": { "@egjs/hammerjs": "^2.0.17", "hoist-non-react-statics": "^3.3.0", @@ -9669,7 +9670,6 @@ "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.1.3.tgz", "integrity": "sha512-GP8wsi1u3nqvC1fMab/m8gfFwFyldawElCcUSBJQgfrXeLmsPPUOpDw44lbLeCpcwUuLa05WTVePdTEwCLTUZg==", "license": "MIT", - "peer": true, "dependencies": { "react-native-is-edge-to-edge": "^1.2.1", "semver": "7.7.2" @@ -9698,7 +9698,6 @@ "resolved": "git+ssh://git@github.com/AppAndFlow/react-native-safe-area-context.git", "integrity": "sha512-4XGqMNj5qjUTYywJqpdWZ9IG8jgkS3h06sfVjfw5yZQZfWnRFXczi0GnYyFyCc2EBps/qFmoCH8fez//WumdVg==", "license": "MIT", - "peer": true, "peerDependencies": { "react": "*", "react-native": "*" @@ -9723,7 +9722,6 @@ "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.12.1.tgz", "integrity": "sha512-vCuZJDf8a5aNC2dlMovEv4Z0jjEUET53lm/iILFnFewa15b4atjVxU6Wirm6O9y6dEsdjDZVD7Q3QM4T1wlI8g==", "license": "MIT", - "peer": true, "dependencies": { "css-select": "^5.1.0", "css-tree": "^1.1.3", @@ -9749,7 +9747,6 @@ "resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.16.0.tgz", "integrity": "sha512-Nh13xKZWW35C0dbOskD7OX01nQQavOzHbCw9XoZmar4eXCo7AvrYJ0jlUfRVVIJzqINxHlpECYLdmAdFsl9xDA==", "license": "MIT", - "peer": true, "dependencies": { "escape-string-regexp": "^4.0.0", "invariant": "2.2.4" @@ -9764,7 +9761,6 @@ "resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.5.1.tgz", "integrity": "sha512-lJG6Uk9YuojjEX/tQrCbcbmpdLCSFxDK1rJlkDhgqkVi1KZzG7cdcBFQRqyNOOzR9Y0CXNuldmtWTGOyM0k0+w==", "license": "MIT", - "peer": true, "dependencies": { "@babel/plugin-transform-arrow-functions": "^7.0.0-0", "@babel/plugin-transform-class-properties": "^7.0.0-0", @@ -9895,7 +9891,6 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -11220,7 +11215,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -11669,7 +11663,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=8.3.0" }, @@ -11857,7 +11850,6 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/android/package.json b/android/package.json index 63d8296..368e4bc 100644 --- a/android/package.json +++ b/android/package.json @@ -30,6 +30,7 @@ "expo": "~54.0.23", "expo-camera": "^17.0.9", "expo-clipboard": "~8.0.7", + "expo-linear-gradient": "^15.0.7", "expo-local-authentication": "^17.0.7", "expo-secure-store": "~15.0.7", "expo-status-bar": "~3.0.8", diff --git a/android/src/auth/PinDots.js b/android/src/auth/PinDots.js index a615b65..c4458dd 100644 --- a/android/src/auth/PinDots.js +++ b/android/src/auth/PinDots.js @@ -18,16 +18,16 @@ const styles = StyleSheet.create({ container: { flexDirection: "row", justifyContent: "center", - gap: 15, - marginVertical: 30, + marginVertical: 16, }, dot: { - width: 16, - height: 16, - borderRadius: 8, + width: 14, + height: 14, + borderRadius: 7, borderWidth: 2, - borderColor: "rgba(255, 255, 255, 0.3)", + borderColor: "#FFFFFF", backgroundColor: "transparent", + marginHorizontal: 8, }, dotFilled: { backgroundColor: "#FFFFFF", diff --git a/android/src/auth/PinPad.js b/android/src/auth/PinPad.js index 8b802be..ab62e08 100644 --- a/android/src/auth/PinPad.js +++ b/android/src/auth/PinPad.js @@ -2,62 +2,84 @@ import React from "react"; import { View, Text, TouchableOpacity, StyleSheet } from "react-native"; export const PinPad = ({ onNumberPress, onBackspace }) => { - const numbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "", "0", "⌫"]; + const renderButton = (num, index) => { + if (num === "") { + return ; + } - return ( - - {numbers.map((num, index) => { - if (num === "") { - return ; - } + if (num === "←") { + return ( + + {num} + + ); + } - if (num === "⌫") { - return ( - - {num} - - ); - } + return ( + onNumberPress(num)} + activeOpacity={0.7} + > + {num} + + ); + }; - return ( - onNumberPress(num)} - activeOpacity={0.7} - > - {num} - - ); - })} + return ( + + {/* Row 1: 1, 2, 3 */} + + {["1", "2", "3"].map((num, index) => renderButton(num, index))} + + {/* Row 2: 4, 5, 6 */} + + {["4", "5", "6"].map((num, index) => renderButton(num, index + 3))} + + {/* Row 3: 7, 8, 9 */} + + {["7", "8", "9"].map((num, index) => renderButton(num, index + 6))} + + {/* Row 4: empty, 0, backspace */} + + {renderButton("", 9)} + {renderButton("0", 10)} + {renderButton("←", 11)} + ); }; const styles = StyleSheet.create({ container: { + width: "100%", + maxWidth: 300, + alignItems: "center", + paddingHorizontal: 20, + }, + row: { flexDirection: "row", - flexWrap: "wrap", - width: 300, justifyContent: "center", + marginBottom: 12, }, button: { - width: 90, - height: 70, + width: 80, + height: 60, justifyContent: "center", alignItems: "center", - margin: 5, - borderRadius: 45, - backgroundColor: "rgba(255, 255, 255, 0.1)", + marginHorizontal: 8, + borderRadius: 12, + backgroundColor: "rgba(26, 26, 26, 0.8)", }, buttonText: { color: "#FFFFFF", - fontSize: 28, - fontWeight: "300", + fontSize: 24, + fontWeight: "400", }, }); diff --git a/android/src/auth/PinSetup.js b/android/src/auth/PinSetup.js index 749b6ee..394ddf3 100644 --- a/android/src/auth/PinSetup.js +++ b/android/src/auth/PinSetup.js @@ -1,11 +1,14 @@ import React, { useState } from "react"; -import { View, Text, StyleSheet, Alert } from "react-native"; +import { View, Text, StyleSheet, Alert, Image } from "react-native"; +import { LinearGradient } from "expo-linear-gradient"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; import { PinPad } from "./PinPad"; import { PinDots } from "./PinDots"; import { AuthManager } from "./AuthManager"; import { Toast } from "./Toast"; export const PinSetup = ({ password, onComplete }) => { + const insets = useSafeAreaInsets(); const [pin, setPin] = useState(""); const [confirmPin, setConfirmPin] = useState(""); const [step, setStep] = useState("enter"); // 'enter' or 'confirm' @@ -83,23 +86,54 @@ export const PinSetup = ({ password, onComplete }) => { return ( - - - {step === "enter" ? "Create PIN" : "Confirm PIN"} - - - {step === "enter" - ? "Enter a 6-digit PIN to secure your wallet" - : "Re-enter your PIN to confirm"} - - - - + {/* Dark blue to transparent gradient overlay */} + + + {/* Logo with blur background */} + + + + + + {/* Header */} + + + {step === "enter" ? "Create PIN" : "Confirm PIN"} + + + {step === "enter" + ? "Enter a 6-digit PIN to secure your wallet" + : "Re-enter your PIN to confirm"} + + + + {/* PIN Dots */} + - + {/* Keypad */} + + + + { const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: "#111827", + position: "relative", + }, + backgroundImage: { + position: "absolute", + top: 0, + left: 0, + right: 0, + bottom: 0, + width: "100%", + height: "100%", + }, + gradientOverlay: { + position: "absolute", + top: 0, + left: 0, + right: 0, + bottom: 0, + width: "100%", + height: "100%", + }, + content: { + flex: 1, justifyContent: "center", alignItems: "center", - padding: 20, + paddingHorizontal: 20, }, - header: { + logoContainer: { + position: "relative", alignItems: "center", + justifyContent: "center", marginBottom: 20, }, + logoBlur: { + position: "absolute", + width: 100, + height: 100, + zIndex: 0, + }, + logo: { + width: 100, + height: 100, + zIndex: 1, + }, + header: { + alignItems: "center", + marginBottom: 16, + }, title: { - fontSize: 28, + fontSize: 32, fontWeight: "bold", color: "#FFFFFF", - marginBottom: 10, + marginBottom: 8, }, subtitle: { fontSize: 14, @@ -135,4 +207,9 @@ const styles = StyleSheet.create({ textAlign: "center", paddingHorizontal: 40, }, + keypadContainer: { + marginTop: 20, + width: "100%", + alignItems: "center", + }, }); diff --git a/android/src/auth/PinUnlock.js b/android/src/auth/PinUnlock.js index fdc798b..88d93ed 100644 --- a/android/src/auth/PinUnlock.js +++ b/android/src/auth/PinUnlock.js @@ -7,12 +7,15 @@ import { Alert, Image, } from "react-native"; +import { LinearGradient } from "expo-linear-gradient"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; import { PinPad } from "./PinPad"; import { PinDots } from "./PinDots"; import { AuthManager, PinLockoutError } from "./AuthManager"; import { Toast } from "./Toast"; export const PinUnlock = ({ onUnlock }) => { + const insets = useSafeAreaInsets(); const [pin, setPin] = useState(""); const [error, setError] = useState(""); const [lockoutMs, setLockoutMs] = useState(0); @@ -161,31 +164,63 @@ export const PinUnlock = ({ onUnlock }) => { return ( - - Enter PIN - - {lockoutMs > 0 - ? `Locked for ${formatLockoutTime(lockoutMs)}` - : "Enter your 6-digit PIN to unlock"} - - - - - - {biometricAvailable && lockoutMs === 0 && ( - + + {/* Dark blue to transparent gradient overlay */} + + + {/* Logo with blur background */} + - - )} + + + + {/* Header */} + + Enter PIN + + {lockoutMs > 0 + ? `Locked for ${formatLockoutTime(lockoutMs)}` + : "Enter your 6-digit PIN to unlock"} + + + + {/* PIN Dots */} + - + {/* Biometric button (if available) */} + {biometricAvailable && lockoutMs === 0 && ( + + + + )} + + {/* Keypad */} + + + + { const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: "#111827", + position: "relative", + }, + backgroundImage: { + position: "absolute", + top: 0, + left: 0, + right: 0, + bottom: 0, + width: "100%", + height: "100%", + }, + gradientOverlay: { + position: "absolute", + top: 0, + left: 0, + right: 0, + bottom: 0, + width: "100%", + height: "100%", + }, + content: { + flex: 1, justifyContent: "center", alignItems: "center", - padding: 20, + paddingHorizontal: 20, + }, + logoContainer: { + position: "relative", + alignItems: "center", + justifyContent: "center", + marginBottom: 20, + }, + logoBlur: { + position: "absolute", + width: 100, + height: 100, + zIndex: 0, + }, + logo: { + width: 100, + height: 100, + zIndex: 1, }, header: { alignItems: "center", - marginBottom: 10, + marginBottom: 16, }, title: { - fontSize: 28, + fontSize: 32, fontWeight: "bold", color: "#FFFFFF", - marginBottom: 10, + marginBottom: 8, }, subtitle: { fontSize: 14, @@ -229,8 +302,8 @@ const styles = StyleSheet.create({ }, biometricButton: { alignSelf: "center", - marginTop: -10, - marginBottom: 15, + marginTop: 8, + marginBottom: 16, padding: 10, }, fingerprintImage: { @@ -238,4 +311,9 @@ const styles = StyleSheet.create({ height: 95, opacity: 0.5, }, + keypadContainer: { + marginTop: 20, + width: "100%", + alignItems: "center", + }, }); diff --git a/android/yarn.lock b/android/yarn.lock index 0a4e2e2..2208af5 100644 --- a/android/yarn.lock +++ b/android/yarn.lock @@ -3123,6 +3123,11 @@ expo-keep-awake@~15.0.7: resolved "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.7.tgz" integrity sha512-CgBNcWVPnrIVII5G54QDqoE125l+zmqR4HR8q+MQaCfHet+dYpS5vX5zii/RMayzGN4jPgA4XYIQ28ePKFjHoA== +expo-linear-gradient@^15.0.7: + version "15.0.7" + resolved "https://registry.npmjs.org/expo-linear-gradient/-/expo-linear-gradient-15.0.7.tgz" + integrity sha512-yF+y+9Shpr/OQFfy/wglB/0bykFMbwHBTuMRa5Of/r2P1wbkcacx8rg0JsUWkXH/rn2i2iWdubyqlxSJa3ggZA== + expo-local-authentication@^17.0.7: version "17.0.7" resolved "https://registry.npmjs.org/expo-local-authentication/-/expo-local-authentication-17.0.7.tgz"