diff --git a/.github/workflows/build-release-apk.yml b/.github/workflows/build-release-apk.yml index 7a076d3e3..9c8f8c0a9 100644 --- a/.github/workflows/build-release-apk.yml +++ b/.github/workflows/build-release-apk.yml @@ -34,7 +34,7 @@ jobs: uses: actions/setup-java@v3 with: distribution: 'temurin' - java-version: '11' + java-version: '17' cache: 'gradle' - name: Install node_modules diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc4b50740..59c59e252 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,9 +66,7 @@ jobs: - name: Free Disk Space uses: jlumbroso/free-disk-space@main with: - # this might remove tools that are actually needed, - # if set to "true" but frees about 6 GB - tool-cache: false + tool-cache: true android: false dotnet: true haskell: true @@ -141,7 +139,7 @@ jobs: force-avd-creation: false emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -camera-back none -camera-front none -partition-size 2047 arch: x86_64 - script: npm run e2e:release-test -- --record-videos all --record-logs all --take-screenshots all --headless -d 200000 -R 3 --artifacts-location /mnt/artifacts + script: npm run e2e:release-test -- --record-videos all --record-logs all --take-screenshots all --headless -d 200000 -R 5 --artifacts-location /mnt/artifacts - uses: actions/upload-artifact@v4 if: failure() diff --git a/Gemfile.lock b/Gemfile.lock index 154aa4726..8c754f2db 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,19 +18,19 @@ GEM artifactory (3.0.17) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.948.0) - aws-sdk-core (3.199.0) + aws-partitions (1.950.0) + aws-sdk-core (3.201.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.8) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.87.0) - aws-sdk-core (~> 3, >= 3.199.0) - aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.154.0) - aws-sdk-core (~> 3, >= 3.199.0) + aws-sdk-kms (1.88.0) + aws-sdk-core (~> 3, >= 3.201.0) + aws-sigv4 (~> 1.5) + aws-sdk-s3 (1.156.0) + aws-sdk-core (~> 3, >= 3.201.0) aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.8) + aws-sigv4 (~> 1.5) aws-sigv4 (1.8.0) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) @@ -210,7 +210,7 @@ GEM base64 mini_magick (4.13.1) mini_mime (1.1.5) - minitest (5.24.0) + minitest (5.24.1) molinillo (0.8.0) multi_json (1.15.0) multipart-post (2.4.1) diff --git a/NavigationService.ts b/NavigationService.ts index 9d9a0d791..21f9074db 100644 --- a/NavigationService.ts +++ b/NavigationService.ts @@ -2,9 +2,9 @@ import { createNavigationContainerRef, NavigationAction, ParamListBase, StackAct export const navigationRef = createNavigationContainerRef(); -export function navigate(name: string, params?: ParamListBase) { +export function navigate(name: string, params?: ParamListBase, options?: { merge: boolean }) { if (navigationRef.isReady()) { - navigationRef.current?.navigate(name, params); + navigationRef.current?.navigate({ name, params, merge: options?.merge }); } } @@ -14,6 +14,10 @@ export function dispatch(action: NavigationAction) { } } +export function navigateToWalletsList() { + navigate('WalletsList'); +} + export function reset() { if (navigationRef.isReady()) { navigationRef.current?.reset({ diff --git a/android/app/build.gradle b/android/app/build.gradle index d63905c9b..2392e894d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -84,6 +84,11 @@ android { testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } + lintOptions { + abortOnError false + checkReleaseBuilds false + } + sourceSets { main { assets.srcDirs = ['src/main/assets', 'src/main/res/assets'] @@ -125,7 +130,6 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation fileTree(dir: "libs", include: ["*.jar"]) implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - implementation 'com.google.android.material:material:1.4.0' } apply plugin: 'com.google.gms.google-services' // Google Services plugin diff --git a/android/build.gradle b/android/build.gradle index 05a211e07..53a501978 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -4,9 +4,9 @@ buildscript { ext { minSdkVersion = 24 supportLibVersion = "28.0.0" - buildToolsVersion = "34.0.0" - compileSdkVersion = 33 - targetSdkVersion = 33 + buildToolsVersion = "33.0.0" + compileSdkVersion = 34 + targetSdkVersion = 34 googlePlayServicesVersion = "16.+" googlePlayServicesIidVersion = "16.0.1" firebaseVersion = "17.3.4" @@ -15,7 +15,7 @@ buildscript { // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. ndkVersion = "23.1.7779620" kotlin_version = '1.9.25' - kotlinVersion = '1.9.23' + kotlinVersion = '1.9.25' } repositories { google() @@ -23,11 +23,11 @@ buildscript { } dependencies { classpath("com.android.tools.build:gradle") + classpath("com.facebook.react:react-native-gradle-plugin") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") classpath("com.bugsnag:bugsnag-android-gradle-plugin:5.+") classpath 'com.google.gms:google-services:4.4.2' // Google Services plugin - classpath("com.facebook.react:react-native-gradle-plugin") - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") - + } } @@ -56,14 +56,19 @@ allprojects { google() maven { url 'https://www.jitpack.io' } } + configurations.all { + resolutionStrategy { + force 'androidx.activity:activity:1.5.1' + } + } } subprojects { afterEvaluate {project -> if (project.hasProperty("android")) { android { - buildToolsVersion "34.0.0" - compileSdkVersion 33 + buildToolsVersion "33.0.0" + compileSdkVersion 34 defaultConfig { minSdkVersion 24 } @@ -78,4 +83,4 @@ subprojects { } } -} +} \ No newline at end of file diff --git a/android/gradle.properties b/android/gradle.properties index cc86a726d..cb3f09d17 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -10,7 +10,7 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m -org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m +org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=1024m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit diff --git a/blue_modules/BlueElectrum.ts b/blue_modules/BlueElectrum.ts index 5edd8e851..e7f06d204 100644 --- a/blue_modules/BlueElectrum.ts +++ b/blue_modules/BlueElectrum.ts @@ -89,7 +89,7 @@ const defaultPeer = { host: 'electrum1.bluewallet.io', ssl: '443' }; export const hardcodedPeers: Peer[] = [ { host: 'mainnet.foundationdevices.com', ssl: '50002' }, { host: 'bitcoin.lukechilds.co', ssl: '50002' }, - { host: 'electrum.jochen-hoenicke.de', ssl: '50006' }, + // { host: 'electrum.jochen-hoenicke.de', ssl: '50006' }, { host: 'electrum1.bluewallet.io', ssl: '443' }, { host: 'electrum.acinq.co', ssl: '50002' }, { host: 'electrum.bitaroo.net', ssl: '50002' }, @@ -887,7 +887,7 @@ export async function multiGetTransactionByTxid( const tx = ret[txid]; // dont cache immature txs, but only for 'verbose', since its fully decoded tx jsons. non-verbose are just plain // strings txhex - if (verbose && typeof tx !== 'string' && (!tx.confirmations || tx.confirmations < 7)) { + if (verbose && typeof tx !== 'string' && (!tx?.confirmations || tx.confirmations < 7)) { continue; } diff --git a/components/Alert.ts b/components/Alert.ts index 4a4e284fc..2d42901f6 100644 --- a/components/Alert.ts +++ b/components/Alert.ts @@ -1,5 +1,4 @@ -import { Alert as RNAlert } from 'react-native'; - +import { Alert as RNAlert, Platform, ToastAndroid } from 'react-native'; import triggerHapticFeedback, { HapticFeedbackTypes } from '../blue_modules/hapticFeedback'; import loc from '../loc'; @@ -21,7 +20,14 @@ const presentAlert = ({ if (hapticFeedback) { triggerHapticFeedback(hapticFeedback); } + + if (Platform.OS !== 'android') { + type = AlertType.Alert; + } switch (type) { + case AlertType.Toast: + ToastAndroid.showWithGravity(message, ToastAndroid.LONG, ToastAndroid.BOTTOM); + break; default: RNAlert.alert(title ?? loc.alert.default, message); break; diff --git a/components/BottomModal.tsx b/components/BottomModal.tsx index f63aa4eb4..5c17d3760 100644 --- a/components/BottomModal.tsx +++ b/components/BottomModal.tsx @@ -1,86 +1,130 @@ -import React from 'react'; -import { Platform, StyleSheet, useWindowDimensions, View } from 'react-native'; -import Modal from 'react-native-modal'; +import React, { forwardRef, useImperativeHandle, useRef, ReactElement, ComponentType, JSXElementConstructor, ReactNode } from 'react'; +import { SheetSize, SizeInfo, TrueSheet, TrueSheetProps } from '@lodev09/react-native-true-sheet'; +import { Keyboard, StyleSheet, View, TouchableOpacity, Platform, Image } from 'react-native'; -import { BlueSpacing10 } from '../BlueComponents'; -import loc from '../loc'; -import Button from './Button'; -import { useTheme } from './themes'; +interface BottomModalProps extends TrueSheetProps { + children?: React.ReactNode; + onClose?: () => void; + name?: string; + isGrabberVisible?: boolean; + sizes?: SheetSize[] | undefined; + footer?: ReactElement | ComponentType; + footerDefaultMargins?: boolean | number; + onPresent?: () => void; + onSizeChange?: (size: SizeInfo) => void; + showCloseButton?: boolean; +} + +export interface BottomModalHandle { + present: () => Promise; + dismiss: () => Promise; +} const styles = StyleSheet.create({ - root: { - justifyContent: 'flex-end', - margin: 0, + footerContainer: { + alignItems: 'center', + justifyContent: 'center', }, - hasDoneButton: { - padding: 16, - paddingBottom: 24, + buttonContainer: { + position: 'absolute', + backgroundColor: 'lightgray', + justifyContent: 'center', + alignItems: 'center', + width: 30, + height: 30, + borderRadius: 15, + top: 20, + right: 20, + zIndex: 10, }, }); -interface BottomModalProps { - children?: React.ReactNode; - onBackButtonPress?: () => void; - onBackdropPress?: () => void; - onClose: () => void; - windowHeight?: number; - windowWidth?: number; - doneButton?: boolean; - avoidKeyboard?: boolean; - allowBackdropPress?: boolean; - isVisible: boolean; - coverScreen?: boolean; - propagateSwipe?: boolean; -} - -const BottomModal: React.FC = ({ - onBackButtonPress, - onBackdropPress, - onClose, - windowHeight, - windowWidth, - doneButton, - isVisible, - avoidKeyboard = false, - allowBackdropPress = true, - coverScreen = true, - propagateSwipe, - ...props -}) => { - const { height: valueWindowHeight, width: valueWindowWidth } = useWindowDimensions(); - const handleBackButtonPress = onBackButtonPress ?? onClose; - const handleBackdropPress = allowBackdropPress ? onBackdropPress ?? onClose : undefined; - const { colors } = useTheme(); - const stylesHook = StyleSheet.create({ - hasDoneButton: { - backgroundColor: colors.elevated, +const BottomModal = forwardRef( + ( + { + name, + onClose, + onPresent, + onSizeChange, + showCloseButton = true, + isGrabberVisible = true, + sizes = ['auto'], + footer, + footerDefaultMargins, + children, + ...props }, - }); + ref, + ) => { + const trueSheetRef = useRef(null); - return ( - - {props.children} - {doneButton && ( - -