mirror of
https://github.com/minibits-cash/minibits_wallet.git
synced 2026-10-05 19:28:26 +00:00
Replace codepush with Hot updater
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
google-services.json
|
||||
minibits-upload-key.keystore
|
||||
GoogleService-Info.plist
|
||||
minibits-prod-firebase-adminsdk.json
|
||||
|
||||
# OSX
|
||||
#
|
||||
|
||||
@@ -95,7 +95,7 @@ android {
|
||||
applicationId "com.minibits_wallet"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 58034
|
||||
versionCode 58036
|
||||
versionName "0.2.2"
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.facebook.react.soloader.OpenSourceMergedSoMapping
|
||||
import com.facebook.soloader.SoLoader
|
||||
import com.facebook.react.modules.network.OkHttpClientProvider
|
||||
// import com.microsoft.codepush.react.CodePush
|
||||
import com.hotupdater.HotUpdater
|
||||
|
||||
class MainApplication : Application(), ReactApplication {
|
||||
|
||||
@@ -38,6 +39,9 @@ class MainApplication : Application(), ReactApplication {
|
||||
// override fun getJSBundleFile(): String {
|
||||
// return CodePush.getJSBundleFile()
|
||||
// }
|
||||
override fun getJSBundleFile(): String? {
|
||||
return HotUpdater.getJSBundleFile(applicationContext)
|
||||
}
|
||||
}
|
||||
|
||||
override val reactHost: ReactHost
|
||||
|
||||
@@ -37,3 +37,4 @@ newArchEnabled=true
|
||||
# Use this property to enable or disable the Hermes JS engine.
|
||||
# If set to false, you will be using JSC instead.
|
||||
hermesEnabled=true
|
||||
|
||||
|
||||
+2
-1
@@ -13,6 +13,7 @@ module.exports = {
|
||||
],
|
||||
'module:react-native-dotenv',
|
||||
'react-native-reanimated/plugin',
|
||||
'@babel/plugin-proposal-export-namespace-from'
|
||||
'@babel/plugin-proposal-export-namespace-from',
|
||||
'hot-updater/babel-plugin',
|
||||
],
|
||||
};
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { metro } from '@hot-updater/metro';
|
||||
import {firebaseStorage, firebaseDatabase} from '@hot-updater/firebase';
|
||||
import * as admin from 'firebase-admin';
|
||||
import { defineConfig } from 'hot-updater';
|
||||
import 'dotenv/config';
|
||||
|
||||
// https://firebase.google.com/docs/admin/setup?hl=en#initialize_the_sdk_in_non-google_environments
|
||||
// Check your .env file and add the credentials
|
||||
// Set the GOOGLE_APPLICATION_CREDENTIALS environment variable to your credentials file path
|
||||
// Example: GOOGLE_APPLICATION_CREDENTIALS=./firebase-adminsdk-credentials.json
|
||||
const credential = admin.credential.applicationDefault();
|
||||
|
||||
export default defineConfig({
|
||||
build: metro({
|
||||
enableHermes: true,
|
||||
}),
|
||||
storage: firebaseStorage({
|
||||
projectId: process.env.HOT_UPDATER_FIREBASE_PROJECT_ID!,
|
||||
storageBucket: process.env.HOT_UPDATER_FIREBASE_STORAGE_BUCKET!,
|
||||
credential,
|
||||
}),
|
||||
database: firebaseDatabase({
|
||||
projectId: process.env.HOT_UPDATER_FIREBASE_PROJECT_ID!,
|
||||
credential,
|
||||
}),
|
||||
});
|
||||
@@ -62,6 +62,31 @@ PODS:
|
||||
- hermes-engine (0.79.0-rc.3):
|
||||
- hermes-engine/Pre-built (= 0.79.0-rc.3)
|
||||
- hermes-engine/Pre-built (0.79.0-rc.3)
|
||||
- HotUpdater (0.16.0):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- hermes-engine
|
||||
- RCT-Folly (= 2024.11.18.00)
|
||||
- RCTRequired
|
||||
- RCTTypeSafety
|
||||
- React-Core
|
||||
- React-debug
|
||||
- React-Fabric
|
||||
- React-featureflags
|
||||
- React-graphics
|
||||
- React-hermes
|
||||
- React-ImageManager
|
||||
- React-jsi
|
||||
- React-NativeModulesApple
|
||||
- React-RCTFabric
|
||||
- React-renderercss
|
||||
- React-rendererdebug
|
||||
- React-utils
|
||||
- ReactCodegen
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- SSZipArchive (~> 2.2.2)
|
||||
- Yoga
|
||||
- libwebp (1.5.0):
|
||||
- libwebp/demux (= 1.5.0)
|
||||
- libwebp/mux (= 1.5.0)
|
||||
@@ -2330,6 +2355,7 @@ PODS:
|
||||
- SDWebImage/Core (~> 5.10)
|
||||
- Sentry/HybridSDK (8.48.0)
|
||||
- SocketRocket (0.7.1)
|
||||
- SSZipArchive (2.2.3)
|
||||
- Yoga (0.0.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
@@ -2340,6 +2366,7 @@ DEPENDENCIES:
|
||||
- fmt (from `../node_modules/react-native/third-party-podspecs/fmt.podspec`)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
|
||||
- "HotUpdater (from `../node_modules/@hot-updater/react-native`)"
|
||||
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
- RCT-Folly/Fabric (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
- RCTDeprecation (from `../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
|
||||
@@ -2446,6 +2473,7 @@ SPEC REPOS:
|
||||
- SDWebImageWebPCoder
|
||||
- Sentry
|
||||
- SocketRocket
|
||||
- SSZipArchive
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
boost:
|
||||
@@ -2463,6 +2491,8 @@ EXTERNAL SOURCES:
|
||||
hermes-engine:
|
||||
:podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec"
|
||||
:tag: hermes-2025-03-03-RNv0.79.0-bc17d964d03743424823d7dd1a9f37633459c5c5
|
||||
HotUpdater:
|
||||
:path: "../node_modules/@hot-updater/react-native"
|
||||
RCT-Folly:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
|
||||
RCTDeprecation:
|
||||
@@ -2648,6 +2678,7 @@ SPEC CHECKSUMS:
|
||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||
hermes-engine: 222573b97e0c0023ee02f5a8480d6aa3080ceb3f
|
||||
HotUpdater: 3f457ec8e209a7060a1403d6d523ef159eb016f8
|
||||
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
|
||||
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
||||
OpenSSL-Universal: d776ce24dab24323e6995dfb17c64d598885d05c
|
||||
@@ -2740,6 +2771,7 @@ SPEC CHECKSUMS:
|
||||
SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d
|
||||
Sentry: 1ca8405451040482877dcd344dfa3ef80b646631
|
||||
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
|
||||
SSZipArchive: 62d4947b08730e4cda640473b0066d209ff033c9
|
||||
Yoga: df4e6df930f6d93d6647c10c61d4d6fe5a694805
|
||||
|
||||
PODFILE CHECKSUM: b2ad66c55434d53dace9ea1b56b7aa7734ed7189
|
||||
|
||||
@@ -443,7 +443,10 @@
|
||||
"-DFOLLY_CFG_NO_COROUTINES=1",
|
||||
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
|
||||
);
|
||||
OTHER_LDFLAGS = "$(inherited) ";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
" ",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
|
||||
@@ -524,7 +527,10 @@
|
||||
"-DFOLLY_CFG_NO_COROUTINES=1",
|
||||
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
|
||||
);
|
||||
OTHER_LDFLAGS = "$(inherited) ";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
" ",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
shouldAutocreateTestPlan = "YES">
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
|
||||
@@ -3,6 +3,7 @@ import React
|
||||
import React_RCTAppDelegate
|
||||
import ReactAppDependencyProvider
|
||||
import Firebase
|
||||
import HotUpdater
|
||||
|
||||
@main
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
@@ -47,6 +48,7 @@ class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
|
||||
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
|
||||
#else
|
||||
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
|
||||
HotUpdater.bundleURL()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
+9
-2
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "minibits_wallet",
|
||||
"version": "0.2.2-beta.5",
|
||||
"version": "0.2.2-beta.6",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"android:clean": "cd android && ./gradlew clean",
|
||||
"android:dev": "react-native run-android --active-arch-only",
|
||||
"android:test": "react-native run-android --mode=release",
|
||||
"android:test": "react-native run-android --mode=release --active-arch-only",
|
||||
"android:bundle": "react-native build-android --mode=release",
|
||||
"android:apk": "cd android && ./gradlew assembleRelease",
|
||||
"ios:dev": "npx react-native run-ios --scheme \"minibits_wallet\"",
|
||||
@@ -29,6 +29,7 @@
|
||||
"@gandlaf21/bc-ur": "^1.1.12",
|
||||
"@gandlaf21/bolt11-decode": "^3.1.1",
|
||||
"@gocodingnow/rn-size-matters": "^0.0.4",
|
||||
"@hot-updater/react-native": "0.16.3",
|
||||
"@notifee/react-native": "^9.1.8",
|
||||
"@react-native-clipboard/clipboard": "^1.16.2",
|
||||
"@react-native-community/netinfo": "^11.4.1",
|
||||
@@ -87,6 +88,8 @@
|
||||
"@babel/plugin-proposal-export-namespace-from": "^7.18.9",
|
||||
"@babel/preset-env": "^7.25.3",
|
||||
"@babel/runtime": "^7.25.0",
|
||||
"@hot-updater/firebase": "0.16.3",
|
||||
"@hot-updater/metro": "0.16.3",
|
||||
"@react-native-community/cli": "18.0.0",
|
||||
"@react-native-community/cli-platform-android": "18.0.0",
|
||||
"@react-native-community/cli-platform-ios": "18.0.0",
|
||||
@@ -100,8 +103,12 @@
|
||||
"@types/react": "^19.0.0",
|
||||
"@types/react-test-renderer": "^19.0.0",
|
||||
"babel-plugin-module-resolver": "^5.0.0",
|
||||
"dotenv": "^16.5.0",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"firebase-admin": "^13.2.0",
|
||||
"firebase-tools": "^14.2.0",
|
||||
"hot-updater": "^0.16.3",
|
||||
"jest": "^29.6.3",
|
||||
"metro-react-native-babel-preset": "0.76.7",
|
||||
"prettier": "2.8.8",
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
JS_BUNDLE_VERSION,
|
||||
ANDROID_VERSION_NAME,
|
||||
} from '@env'
|
||||
// import codePush from 'react-native-code-push'
|
||||
import FlashMessage from "react-native-flash-message"
|
||||
import {
|
||||
SafeAreaProvider,
|
||||
@@ -129,7 +128,4 @@ const $title: TextStyle = {
|
||||
color: 'white'
|
||||
}
|
||||
|
||||
/*const deploymentKey = APP_ENV === Env.PROD ? CODEPUSH_PRODUCTION_DEPLOYMENT_KEY : CODEPUSH_STAGING_DEPLOYMENT_KEY
|
||||
const codePushOptions = { deploymentKey, checkFrequency: codePush.CheckFrequency.MANUAL }
|
||||
export default codePush(codePushOptions)(App)*/
|
||||
export default App
|
||||
|
||||
@@ -14,6 +14,7 @@ import { colors, useThemeColor, spacing } from "../theme"
|
||||
import { Text, TextProps } from "./Text"
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context"
|
||||
import { Header } from "@react-navigation/stack"
|
||||
import { moderateVerticalScale } from "@gocodingnow/rn-size-matters"
|
||||
|
||||
|
||||
interface ModalProps extends ViewProps {
|
||||
@@ -136,7 +137,7 @@ export function BottomModal(props: ModalProps) {
|
||||
const insets = useSafeAreaInsets()
|
||||
|
||||
const $innerContainerStyle = [
|
||||
$innerContainerBase, { backgroundColor: useThemeColor('card'), paddingBottom: insets.bottom + 60 }, $containerStyleOverride
|
||||
$innerContainerBase, { backgroundColor: useThemeColor('card'), paddingBottom: insets.bottom + moderateVerticalScale(40) }, $containerStyleOverride
|
||||
]
|
||||
|
||||
const isHeadingPresent = !!(HeadingComponent || heading || headingTx)
|
||||
@@ -163,6 +164,7 @@ export function BottomModal(props: ModalProps) {
|
||||
const statusBarOnModalOpen = useThemeColor('statusBarOnModalOpen')
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Modal
|
||||
isVisible={isVisible}
|
||||
statusBarTranslucent={false}
|
||||
@@ -214,7 +216,8 @@ export function BottomModal(props: ModalProps) {
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
</Modal>
|
||||
</Modal>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ import {
|
||||
} from "../screens"
|
||||
import { colors, spacing, typography } from "../theme"
|
||||
import { moderateVerticalScale } from "@gocodingnow/rn-size-matters"
|
||||
import { initialWindowMetrics } from "react-native-safe-area-context"
|
||||
|
||||
const $tabBar: ViewStyle = {
|
||||
borderTopColor: 'transparent',
|
||||
@@ -152,13 +153,14 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const TabsNavigator = createBottomTabNavigator({
|
||||
initialRouteName: "WalletNavigator",
|
||||
backBehavior: 'firstRoute',
|
||||
screenOptions: {
|
||||
headerShown: false,
|
||||
tabBarHideOnKeyboard: true,
|
||||
tabBarStyle: [$tabBar, { height: moderateVerticalScale(70) }],
|
||||
tabBarStyle: [$tabBar, { height: 70 + initialWindowMetrics?.insets.bottom }],
|
||||
tabBarItemStyle: $tabBarItem,
|
||||
tabBarLabelStyle: $tabBarLabel,
|
||||
animation: 'shift',
|
||||
|
||||
@@ -48,7 +48,8 @@ export const ContactsScreen = observer(function ({ route }: Props) {
|
||||
])
|
||||
|
||||
const gotoProfile = function () {
|
||||
navigation.navigate('Profile')
|
||||
// @ts-ignore
|
||||
navigation.navigate('Profile', {prevScreen: 'Contacts'})
|
||||
}
|
||||
|
||||
const headerBg = useThemeColor('header')
|
||||
|
||||
@@ -11,13 +11,18 @@ import { log } from '../services/logService'
|
||||
import { KeyChain, MinibitsClient, NostrClient, NostrProfile } from '../services'
|
||||
import { translate, TxKeyPath } from '../i18n'
|
||||
import { CollapsibleText } from '../components/CollapsibleText'
|
||||
import { StaticScreenProps, useNavigation } from '@react-navigation/native'
|
||||
import { CommonActions, StaticScreenProps, useNavigation } from '@react-navigation/native'
|
||||
import { QRShareModal } from '../components/QRShareModal'
|
||||
|
||||
type Props = StaticScreenProps<undefined>
|
||||
type Props = StaticScreenProps<{
|
||||
prevScreen: 'Contacts' | 'Wallet'
|
||||
}>
|
||||
|
||||
export const ProfileScreen = observer(function ProfileScreen({ route }: Props) {
|
||||
const navigation = useNavigation()
|
||||
const {
|
||||
prevScreen
|
||||
} = route.params
|
||||
const {walletProfileStore, userSettingsStore, relaysStore, walletStore} = useStores()
|
||||
const {npub, nip05, pubkey} = walletProfileStore
|
||||
|
||||
@@ -168,7 +173,20 @@ export const ProfileScreen = observer(function ProfileScreen({ route }: Props) {
|
||||
<Screen contentContainerStyle={$screen} preset='fixed'>
|
||||
<Header
|
||||
leftIcon='faArrowLeft'
|
||||
onLeftPress={() => {navigation.goBack()}}
|
||||
onLeftPress={() => {
|
||||
if(prevScreen === 'Wallet') {
|
||||
navigation.dispatch(
|
||||
CommonActions.reset({
|
||||
index: 1,
|
||||
routes: [{
|
||||
name: 'WalletNavigator'
|
||||
}]
|
||||
})
|
||||
)
|
||||
} else {
|
||||
navigation.goBack()
|
||||
}
|
||||
}}
|
||||
rightIcon='faCopy'
|
||||
onRightPress={onCopyNip05}
|
||||
/>
|
||||
|
||||
@@ -5,6 +5,8 @@ import notifee, { AuthorizationStatus } from '@notifee/react-native'
|
||||
import messaging from '@react-native-firebase/messaging'
|
||||
import {
|
||||
APP_ENV,
|
||||
HOT_UPDATER_API_KEY,
|
||||
HOT_UPDATER_URL,
|
||||
} from '@env'
|
||||
import {ThemeCode, Themes, colors, spacing, useThemeColor} from '../theme'
|
||||
import {ListItem, Screen, Text, Card, NwcIcon, Button, BottomModal, InfoModal, Icon} from '../components'
|
||||
@@ -19,6 +21,7 @@ import { NotificationService } from '../services/notificationService'
|
||||
import { SvgXml } from 'react-native-svg'
|
||||
import { CurrencySign } from './Wallet/CurrencySign'
|
||||
import { CommonActions, StaticScreenProps, useNavigation } from '@react-navigation/native'
|
||||
import { HotUpdater } from '@hot-updater/react-native'
|
||||
|
||||
type Props = StaticScreenProps<undefined>
|
||||
|
||||
@@ -50,18 +53,36 @@ export const SettingsScreen = observer(function SettingsScreen({ route }: Props)
|
||||
useEffect(() => {
|
||||
const checkForUpdate = async () => {
|
||||
try {
|
||||
/*const update = await codePush.checkForUpdate(deploymentKey, handleBinaryVersionMismatchCallback)
|
||||
if (update && update.failedInstall !== true) { // do not announce update that failed to install before
|
||||
setUpdateDescription(update.description)
|
||||
setUpdateSize(`${round(update.packageSize * 0.000001, 2)}MB`)
|
||||
const updateInfo = await HotUpdater.checkForUpdate({
|
||||
source: HOT_UPDATER_URL,
|
||||
requestHeaders: {
|
||||
Authorization: `Bearer ${HOT_UPDATER_API_KEY}`,
|
||||
},
|
||||
})
|
||||
|
||||
log.debug('[checkForUpdate]', {updateInfo})
|
||||
|
||||
if (!updateInfo) {
|
||||
return
|
||||
}
|
||||
|
||||
if(!__DEV__) {
|
||||
setIsUpdateAvailable(true)
|
||||
}*/
|
||||
setUpdateDescription(updateInfo.message)
|
||||
|
||||
if (updateInfo.shouldForceUpdate) {
|
||||
// apply emergency update immediately
|
||||
await HotUpdater.updateBundle(updateInfo.id, updateInfo.fileUrl)
|
||||
HotUpdater.reload()
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e: any) {
|
||||
log.info(e.name, e.message)
|
||||
return false // silent
|
||||
log.error(e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkForUpdate()
|
||||
}, [])
|
||||
|
||||
@@ -139,26 +160,32 @@ export const SettingsScreen = observer(function SettingsScreen({ route }: Props)
|
||||
} */
|
||||
|
||||
const gotoMints = function() {
|
||||
// @ts-ignore
|
||||
navigation.navigate('Mints', {})
|
||||
}
|
||||
|
||||
const gotoSecurity = function() {
|
||||
// @ts-ignore
|
||||
navigation.navigate('Security')
|
||||
}
|
||||
|
||||
const gotoPrivacy = function() {
|
||||
// @ts-ignore
|
||||
navigation.navigate('Privacy')
|
||||
}
|
||||
|
||||
const gotoDevOptions = function() {
|
||||
// @ts-ignore
|
||||
navigation.navigate('Developer')
|
||||
}
|
||||
|
||||
const gotoRelays = function() {
|
||||
// @ts-ignore
|
||||
navigation.navigate('Relays')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const gotoBackupOptions = function() {
|
||||
// @ts-ignore
|
||||
navigation.navigate('BackupOptions')
|
||||
}
|
||||
|
||||
@@ -171,7 +198,8 @@ export const SettingsScreen = observer(function SettingsScreen({ route }: Props)
|
||||
))
|
||||
}
|
||||
|
||||
/* const gotoUpdate = function() {
|
||||
const gotoUpdate = function() {
|
||||
// @ts-ignore
|
||||
navigation.navigate('Update', {
|
||||
isNativeUpdateAvailable,
|
||||
isUpdateAvailable,
|
||||
@@ -179,9 +207,10 @@ export const SettingsScreen = observer(function SettingsScreen({ route }: Props)
|
||||
updateSize,
|
||||
prevScreen: 'Settings'
|
||||
})
|
||||
}*/
|
||||
}
|
||||
|
||||
const gotoNwc = function() {
|
||||
// @ts-ignore
|
||||
navigation.navigate('Nwc')
|
||||
}
|
||||
|
||||
@@ -465,7 +494,7 @@ export const SettingsScreen = observer(function SettingsScreen({ route }: Props)
|
||||
bottomSeparator={true}
|
||||
onPress={gotoPrivacy}
|
||||
/>
|
||||
{/*<ListItem
|
||||
<ListItem
|
||||
tx='settingsScreen.update'
|
||||
leftIcon='faWandMagicSparkles'
|
||||
leftIconColor={(isUpdateAvailable || isNativeUpdateAvailable) ? colors.palette.iconMagenta200 : colors.palette.neutral400}
|
||||
@@ -481,7 +510,7 @@ export const SettingsScreen = observer(function SettingsScreen({ route }: Props)
|
||||
style={$item}
|
||||
bottomSeparator={true}
|
||||
onPress={gotoUpdate}
|
||||
/>*/}
|
||||
/>
|
||||
<ListItem
|
||||
tx='settingsScreen.devOptions'
|
||||
leftIcon='faCode'
|
||||
|
||||
@@ -2,9 +2,9 @@ import {observer} from 'mobx-react-lite'
|
||||
import React, {FC, useEffect, useState} from 'react'
|
||||
import {Linking, Platform, ScrollView, Switch, TextStyle, View, ViewStyle} from 'react-native'
|
||||
import {
|
||||
APP_ENV,
|
||||
CODEPUSH_STAGING_DEPLOYMENT_KEY,
|
||||
CODEPUSH_PRODUCTION_DEPLOYMENT_KEY,
|
||||
APP_ENV,
|
||||
HOT_UPDATER_API_KEY,
|
||||
HOT_UPDATER_URL,
|
||||
} from '@env'
|
||||
// import codePush from "react-native-code-push"
|
||||
import {colors, spacing, useThemeColor} from '../theme'
|
||||
@@ -18,17 +18,18 @@ import {
|
||||
ErrorModal,
|
||||
InfoModal,
|
||||
Button,
|
||||
BottomModal,
|
||||
} from '../components'
|
||||
import {useHeader} from '../utils/useHeader'
|
||||
import AppError from '../utils/AppError'
|
||||
import AppError, { Err } from '../utils/AppError'
|
||||
import { log } from '../services'
|
||||
import {Env} from '../utils/envtypes'
|
||||
import { CommonActions, StaticScreenProps, useNavigation } from '@react-navigation/native'
|
||||
import { translate } from '../i18n'
|
||||
import { HotUpdater, useHotUpdaterStore } from '@hot-updater/react-native'
|
||||
import { ResultModalInfo } from './Wallet/ResultModalInfo'
|
||||
|
||||
|
||||
const deploymentKey = APP_ENV === Env.PROD ? CODEPUSH_PRODUCTION_DEPLOYMENT_KEY : CODEPUSH_STAGING_DEPLOYMENT_KEY
|
||||
|
||||
type Props = StaticScreenProps<{
|
||||
isNativeUpdateAvailable: boolean,
|
||||
isUpdateAvailable: boolean,
|
||||
@@ -45,14 +46,20 @@ export const UpdateScreen = observer(function UpdateScreen({ route }: Props) {
|
||||
updateDescription,
|
||||
updateSize,
|
||||
prevScreen
|
||||
} = route.params
|
||||
} = route.params
|
||||
|
||||
const { progress, isBundleUpdated } = useHotUpdaterStore()
|
||||
|
||||
useHeader({
|
||||
leftIcon: 'faArrowLeft',
|
||||
onLeftPress: () => {
|
||||
//@ts-ignore
|
||||
navigation.setParams({isUpdateAvailable: undefined})
|
||||
//@ts-ignore
|
||||
navigation.setParams({isNativeUpdateAvailable: undefined})
|
||||
//@ts-ignore
|
||||
navigation.setParams({updateDescription: undefined})
|
||||
//@ts-ignore
|
||||
navigation.setParams({updateSize: undefined})
|
||||
|
||||
if(prevScreen === 'Settings') {
|
||||
@@ -70,39 +77,35 @@ export const UpdateScreen = observer(function UpdateScreen({ route }: Props) {
|
||||
},
|
||||
})
|
||||
|
||||
// const {userSettingsStore} = useStores()
|
||||
|
||||
const [info, setInfo] = useState('')
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [isUpdateModalVisible, setIsUpdateModalVisible] = useState(false)
|
||||
const [error, setError] = useState<AppError | undefined>()
|
||||
|
||||
const toggleUpdateModal = () => {
|
||||
setIsUpdateModalVisible(previousState => !previousState)
|
||||
}
|
||||
|
||||
const handleUpdate = function (): void {
|
||||
/*try {
|
||||
codePush.sync({
|
||||
deploymentKey,
|
||||
rollbackRetryOptions: {
|
||||
delayInHours: 1,
|
||||
maxRetryAttempts: 3
|
||||
const handleUpdate = async function () {
|
||||
try {
|
||||
setIsUpdateModalVisible(true)
|
||||
const updateInfo = await HotUpdater.checkForUpdate({
|
||||
source: HOT_UPDATER_URL,
|
||||
requestHeaders: {
|
||||
Authorization: `Bearer ${HOT_UPDATER_API_KEY}`,
|
||||
},
|
||||
installMode: codePush.InstallMode.IMMEDIATE,
|
||||
|
||||
},
|
||||
(status) => {
|
||||
switch (status) {
|
||||
case codePush.SyncStatus.DOWNLOADING_PACKAGE:
|
||||
log.trace('Downloading update...')
|
||||
setInfo(translate("updateScreen.downloading"))
|
||||
break
|
||||
case codePush.SyncStatus.INSTALLING_UPDATE:
|
||||
log.trace('Installing update...')
|
||||
setInfo(translate("updateScreen.installing"))
|
||||
break
|
||||
}
|
||||
})
|
||||
} catch (e: any) {
|
||||
|
||||
if (!updateInfo) {
|
||||
throw new AppError(Err.NETWORK_ERROR, 'Could not retrieve update information')
|
||||
}
|
||||
|
||||
await HotUpdater.updateBundle(updateInfo.id, updateInfo.fileUrl)
|
||||
HotUpdater.reload()
|
||||
|
||||
} catch(e: any) {
|
||||
handleError(e)
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -128,6 +131,7 @@ export const UpdateScreen = observer(function UpdateScreen({ route }: Props) {
|
||||
|
||||
const handleError = function (e: AppError): void {
|
||||
setIsLoading(false)
|
||||
setIsUpdateModalVisible(false)
|
||||
setError(e)
|
||||
}
|
||||
|
||||
@@ -162,14 +166,14 @@ export const UpdateScreen = observer(function UpdateScreen({ route }: Props) {
|
||||
topSeparator={true}
|
||||
style={$item}
|
||||
/>
|
||||
<ListItem
|
||||
{/*<ListItem
|
||||
tx='updateScreen.updateSize'
|
||||
subText={updateSize || '1.0MB'}
|
||||
leftIcon='faDownload'
|
||||
leftIconColor={colors.palette.neutral500}
|
||||
topSeparator={true}
|
||||
style={$item}
|
||||
/>
|
||||
/>*/}
|
||||
</>
|
||||
)}
|
||||
{isNativeUpdateAvailable && (
|
||||
@@ -220,7 +224,21 @@ export const UpdateScreen = observer(function UpdateScreen({ route }: Props) {
|
||||
}
|
||||
/>
|
||||
{isLoading && <Loading />}
|
||||
</ScrollView>
|
||||
</ScrollView>
|
||||
<BottomModal
|
||||
isVisible={isUpdateModalVisible ? true : false}
|
||||
style={{alignItems: 'stretch', padding: spacing.small}}
|
||||
ContentComponent={
|
||||
<ResultModalInfo
|
||||
icon='faDownload'
|
||||
iconColor={colors.palette.accent400}
|
||||
title={`${Math.round(progress * 100)}%`}
|
||||
message='Update is in progress...'
|
||||
/>
|
||||
}
|
||||
onBackButtonPress={toggleUpdateModal}
|
||||
onBackdropPress={toggleUpdateModal}
|
||||
/>
|
||||
{error && <ErrorModal error={error} />}
|
||||
{info && <InfoModal message={info} />}
|
||||
</Screen>
|
||||
|
||||
@@ -14,7 +14,8 @@ import {
|
||||
Linking,
|
||||
LayoutAnimation,
|
||||
AppStateStatus,
|
||||
Platform,
|
||||
Platform,
|
||||
Alert,
|
||||
} from 'react-native'
|
||||
// import codePush, { RemotePackage } from 'react-native-code-push'
|
||||
import {moderateScale, verticalScale} from '@gocodingnow/rn-size-matters'
|
||||
@@ -48,6 +49,8 @@ import {WalletTask} from '../services'
|
||||
import {translate} from '../i18n'
|
||||
import AppError, { Err } from '../utils/AppError'
|
||||
import {
|
||||
HOT_UPDATER_API_KEY,
|
||||
HOT_UPDATER_URL,
|
||||
MINIBITS_MINT_URL,
|
||||
} from '@env'
|
||||
import { IncomingParser } from '../services/incomingParser'
|
||||
@@ -58,6 +61,7 @@ import { CurrencyAmount } from './Wallet/CurrencyAmount'
|
||||
import { LeftProfileHeader } from './ContactsScreen'
|
||||
import { getUnixTime } from 'date-fns/getUnixTime'
|
||||
import FastImage from 'react-native-fast-image'
|
||||
import { HotUpdater } from '@hot-updater/react-native'
|
||||
|
||||
const MINT_CHECK_INTERVAL = 60
|
||||
|
||||
@@ -109,24 +113,38 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
|
||||
const [isNativeUpdateAvailable, setIsNativeUpdateAvailable] = useState<boolean>(false)
|
||||
|
||||
// On app start
|
||||
/* useEffect(() => {
|
||||
const checkForUpdate = async () => {
|
||||
useEffect(() => {
|
||||
const checkForUpdate = async () => {
|
||||
try {
|
||||
const update = await codePush.checkForUpdate(deploymentKey, handleBinaryVersionMismatchCallback)
|
||||
|
||||
if (update && update.failedInstall !== true) { // do not announce update that failed to install before
|
||||
// log.trace('[checkForUpdate]', update)
|
||||
if(ANDROID_VERSION_NAME === update.appVersion) {
|
||||
setUpdateDescription(update.description)
|
||||
setUpdateSize(`${round(update.packageSize * 0.000001, 2)}MB`)
|
||||
setIsUpdateAvailable(true)
|
||||
toggleUpdateModal()
|
||||
}
|
||||
}
|
||||
} catch (e: any) {
|
||||
return false // silent
|
||||
}
|
||||
const updateInfo = await HotUpdater.checkForUpdate({
|
||||
source: HOT_UPDATER_URL,
|
||||
requestHeaders: {
|
||||
Authorization: `Bearer ${HOT_UPDATER_API_KEY}`,
|
||||
},
|
||||
})
|
||||
|
||||
log.debug('[checkForUpdate]', {updateInfo})
|
||||
|
||||
if (!updateInfo) {
|
||||
return
|
||||
}
|
||||
|
||||
if(!__DEV__) {
|
||||
setIsUpdateAvailable(true)
|
||||
setUpdateDescription(updateInfo.message)
|
||||
toggleUpdateModal()
|
||||
|
||||
if (updateInfo.shouldForceUpdate) {
|
||||
// apply emergency update immediately
|
||||
await HotUpdater.updateBundle(updateInfo.id, updateInfo.fileUrl)
|
||||
HotUpdater.reload()
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e: any) {
|
||||
log.error(e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
@@ -139,11 +157,11 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
|
||||
}, [])
|
||||
|
||||
|
||||
const handleBinaryVersionMismatchCallback = function(update: RemotePackage) {
|
||||
/* const handleBinaryVersionMismatchCallback = function(update: RemotePackage) {
|
||||
log.info('[handleBinaryVersionMismatchCallback] triggered', ANDROID_VERSION_NAME, update)
|
||||
setIsNativeUpdateAvailable(true)
|
||||
toggleUpdateModal()
|
||||
} */
|
||||
}*/
|
||||
|
||||
// On app start
|
||||
useEffect(() => {
|
||||
@@ -394,7 +412,10 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
|
||||
const gotoProfile = function () {
|
||||
// @ts-ignore
|
||||
navigation.navigate('ContactsNavigator', {
|
||||
screen: 'Profile'
|
||||
screen: 'Profile',
|
||||
params: {
|
||||
prevScreen: 'Wallet'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -718,7 +739,7 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
|
||||
textStyle={{marginLeft: spacing.tiny}}
|
||||
preset='secondary'
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
{info && <InfoModal message={info} />}
|
||||
{error && <ErrorModal error={error} />}
|
||||
|
||||
@@ -7,6 +7,8 @@ declare module '@env' {
|
||||
export const MINIBITS_NIP05_DOMAIN: string
|
||||
export const MINIBITS_RELAY_URL: string
|
||||
export const MINIBITS_MINT_URL: string
|
||||
export const HOT_UPDATER_URL: string
|
||||
export const HOT_UPDATER_API_KEY: string
|
||||
export const ANDROID_VERSION_NAME: string
|
||||
export const ANDROID_VERSION_CODE: string
|
||||
export const JS_BUNDLE_VERSION: string
|
||||
|
||||
Reference in New Issue
Block a user