ADD: Dark Mode

This commit is contained in:
Marcos Rodriguez Vélez 2020-07-15 13:32:59 -04:00 committed by GitHub
parent 8e0fc159e2
commit 2ce7111687
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
62 changed files with 2071 additions and 1769 deletions

22
App.js
View file

@ -3,18 +3,20 @@ import React from 'react';
import { Linking, Appearance, DeviceEventEmitter, AppState, StyleSheet, KeyboardAvoidingView, Platform, View } from 'react-native';
import Clipboard from '@react-native-community/clipboard';
import Modal from 'react-native-modal';
import { NavigationContainer, CommonActions, DefaultTheme, DarkTheme } from '@react-navigation/native';
import { NavigationContainer, CommonActions } from '@react-navigation/native';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import Navigation from './Navigation';
import { navigationRef } from './NavigationService';
import * as NavigationService from './NavigationService';
import { BlueTextCentered, BlueButton } from './BlueComponents';
import { BlueTextCentered, BlueButton, SecondButton } from './BlueComponents';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { Chain } from './models/bitcoinUnits';
import QuickActions from 'react-native-quick-actions';
import * as Sentry from '@sentry/react-native';
import OnAppLaunch from './class/on-app-launch';
import DeeplinkSchemaMatch from './class/deeplink-schema-match';
import { BlueDefaultTheme, BlueDarkTheme, BlueCurrentTheme } from './components/themes';
const A = require('./blue_modules/analytics');
if (process.env.NODE_ENV !== 'development') {
@ -35,12 +37,21 @@ export default class App extends React.Component {
isClipboardContentModalVisible: false,
clipboardContentModalAddressType: bitcoinModalString,
clipboardContent: '',
theme: Appearance.getColorScheme(),
};
componentDidMount() {
EV(EV.enum.WALLETS_INITIALIZED, this.addListeners);
Appearance.addChangeListener(this.appearanceChanged);
}
appearanceChanged = () => {
const appearance = Appearance.getColorScheme();
if (appearance) {
this.setState({ theme: appearance });
}
};
addListeners = () => {
Linking.addEventListener('url', this.handleOpenURL);
AppState.addEventListener('change', this._handleAppStateChange);
@ -104,6 +115,7 @@ export default class App extends React.Component {
componentWillUnmount() {
Linking.removeEventListener('url', this.handleOpenURL);
AppState.removeEventListener('change', this._handleAppStateChange);
Appearance.removeChangeListener(this.appearanceChanged);
}
_handleAppStateChange = async nextAppState => {
@ -192,7 +204,7 @@ export default class App extends React.Component {
You have a {this.state.clipboardContentModalAddressType} on your clipboard. Would you like to use it for a transaction?
</BlueTextCentered>
<View style={styles.modelContentButtonLayout}>
<BlueButton
<SecondButton
noMinWidth
title={loc.send.details.cancel}
onPress={() => this.setState({ isClipboardContentModalVisible: false })}
@ -219,7 +231,7 @@ export default class App extends React.Component {
return (
<SafeAreaProvider>
<View style={styles.root}>
<NavigationContainer ref={navigationRef} theme={Appearance.getColorScheme() === 'dark' ? { ...DarkTheme } : DefaultTheme} tr>
<NavigationContainer ref={navigationRef} theme={this.state.theme === 'dark' ? BlueDarkTheme : BlueDefaultTheme}>
<Navigation />
</NavigationContainer>
{this.renderClipboardContentModal()}
@ -237,7 +249,7 @@ const styles = StyleSheet.create({
marginHorizontal: 8,
},
modalContent: {
backgroundColor: '#FFFFFF',
backgroundColor: BlueCurrentTheme.colors.elevated,
padding: 22,
justifyContent: 'center',
alignItems: 'center',

File diff suppressed because it is too large Load diff

View file

@ -62,8 +62,7 @@ import LNDViewInvoice from './screen/lnd/lndViewInvoice';
import LNDViewAdditionalInvoiceInformation from './screen/lnd/lndViewAdditionalInvoiceInformation';
import LoadingScreen from './LoadingScreen';
import UnlockWith from './UnlockWith';
const BlueApp = require('./BlueApp');
const loc = require('./loc');
import { BlueNavigationStyle } from './BlueComponents';
const SCREEN_HEIGHT = Dimensions.get('window').height;
const defaultScreenOptions =
@ -103,15 +102,9 @@ const WalletsRoot = () => (
name="Settings"
component={Settings}
options={{
headerStyle: {
backgroundColor: '#FFFFFF',
borderBottomWidth: 0,
elevation: 0,
shadowColor: 'transparent',
},
title: '',
headerBackTitleVisible: false,
headerTintColor: '#0c2550',
...BlueNavigationStyle(),
headerTitle: '',
}}
/>
<WalletsStack.Screen name="SelectWallet" component={SelectWallet} options={SelectWallet.navigationOptions} />
@ -140,18 +133,8 @@ const WalletsRoot = () => (
component={LNDViewAdditionalInvoiceInformation}
options={LNDViewAdditionalInvoiceInformation.navigationOptions}
/>
<WalletsStack.Screen
name="Broadcast"
component={Broadcast}
options={{
title: 'Broadcast',
headerStyle: {
backgroundColor: '#FFFFFF',
borderBottomWidth: 0,
},
headerTintColor: '#0c2550',
}}
/>
<WalletsStack.Screen name="HodlHodlViewOffer" component={HodlHodlViewOffer} options={HodlHodlViewOffer.navigationOptions} />
<WalletsStack.Screen name="Broadcast" component={Broadcast} options={Broadcast.navigationOptions} />
</WalletsStack.Navigator>
);
@ -189,16 +172,7 @@ const SendDetailsRoot = () => (
}}
/>
<SendDetailsStack.Screen name="Success" component={Success} options={Success.navigationOptions} />
<SendDetailsStack.Screen
name="SelectWallet"
component={SelectWallet}
options={{
headerTitle: loc.wallets.select_wallet,
headerRight: null,
headerBackTitleVisible: false,
headerTintColor: BlueApp.settings.foregroundColor,
}}
/>
<SendDetailsStack.Screen name="SelectWallet" component={SelectWallet} options={SelectWallet.navigationOptions} />
</SendDetailsStack.Navigator>
);
@ -206,16 +180,7 @@ const LNDCreateInvoiceStack = createStackNavigator();
const LNDCreateInvoiceRoot = () => (
<LNDCreateInvoiceStack.Navigator screenOptions={defaultStackScreenOptions}>
<LNDCreateInvoiceStack.Screen name="LNDCreateInvoice" component={LNDCreateInvoice} options={LNDCreateInvoice.navigationOptions} />
<LNDCreateInvoiceStack.Screen
name="SelectWallet"
component={SelectWallet}
options={{
headerTitle: loc.wallets.select_wallet,
headerRight: null,
headerBackTitleVisible: false,
headerTintColor: BlueApp.settings.foregroundColor,
}}
/>
<LNDCreateInvoiceStack.Screen name="SelectWallet" component={SelectWallet} options={SelectWallet.navigationOptions} />
<LNDCreateInvoiceStack.Screen
name="LNDViewInvoice"
component={LNDViewInvoice}
@ -231,32 +196,12 @@ const LNDCreateInvoiceRoot = () => (
</LNDCreateInvoiceStack.Navigator>
);
const HodlHodlStack = createStackNavigator();
const HodlHodlRoot = () => (
<HodlHodlStack.Navigator>
<HodlHodlStack.Screen name="HodlHodl" component={HodlHodl} options={HodlHodl.navigationOptions} />
<HodlHodlStack.Screen name="HodlHodlViewOffer" component={HodlHodlViewOffer} options={HodlHodlViewOffer.navigationOptions} />
<HodlHodlStack.Screen name="HodlHodlLogin" component={HodlHodlLogin} options={HodlHodlLogin.navigationOptions} />
<HodlHodlStack.Screen name="HodlHodlMyContracts" component={HodlHodlMyContracts} options={HodlHodlMyContracts.navigationOptions} />
<HodlHodlStack.Screen name="HodlHodlWebview" component={HodlHodlWebview} options={HodlHodlWebview.navigationOptions} />
</HodlHodlStack.Navigator>
);
// LightningScanInvoiceStackNavigator === ScanLndInvoiceStack
const ScanLndInvoiceStack = createStackNavigator();
const ScanLndInvoiceRoot = () => (
<ScanLndInvoiceStack.Navigator screenOptions={defaultStackScreenOptions}>
<ScanLndInvoiceStack.Screen name="ScanLndInvoice" component={ScanLndInvoice} options={ScanLndInvoice.navigationOptions} />
<ScanLndInvoiceStack.Screen
name="SelectWallet"
component={SelectWallet}
options={{
headerTitle: loc.wallets.select_wallet,
headerRight: null,
headerBackTitleVisible: false,
headerTintColor: BlueApp.settings.foregroundColor,
}}
/>
<ScanLndInvoiceStack.Screen name="SelectWallet" component={SelectWallet} options={SelectWallet.navigationOptions} />
<ScanLndInvoiceStack.Screen name="Success" component={Success} options={Success.navigationOptions} />
</ScanLndInvoiceStack.Navigator>
);
@ -290,6 +235,13 @@ const UnlockWithScreenRoot = () => (
</UnlockWithScreenStack.Navigator>
);
const HodlHodlLoginStack = createStackNavigator();
const HodlHodlLoginRoot = () => (
<HodlHodlLoginStack.Navigator name="HodlHodlLoginRoot" screenOptions={defaultStackScreenOptions}>
<HodlHodlLoginStack.Screen name="HodlHodlLogin" component={HodlHodlLogin} options={HodlHodlLogin.navigationOptions} />
</HodlHodlLoginStack.Navigator>
);
const RootStack = createStackNavigator();
const Navigation = () => (
<RootStack.Navigator mode="modal" screenOptions={defaultScreenOptions} initialRouteName="LoadingScreenRoot">
@ -306,7 +258,9 @@ const Navigation = () => (
<RootStack.Screen name="LNDCreateInvoiceRoot" component={LNDCreateInvoiceRoot} options={{ headerShown: false }} />
<RootStack.Screen name="ScanLndInvoiceRoot" component={ScanLndInvoiceRoot} options={{ headerShown: false }} />
<RootStack.Screen name="AztecoRedeemRoot" component={AztecoRedeemRoot} options={{ headerShown: false }} />
<RootStack.Screen name="HodlHodlRoot" component={HodlHodlRoot} options={{ headerShown: false }} />
<RootStack.Screen name="HodlHodlLoginRoot" component={HodlHodlLoginRoot} options={{ headerShown: false }} />
<RootStack.Screen name="HodlHodlMyContracts" component={HodlHodlMyContracts} options={HodlHodlMyContracts.navigationOptions} />
<RootStack.Screen name="HodlHodlWebview" component={HodlHodlWebview} options={HodlHodlWebview.navigationOptions} />
<RootStack.Screen
name="ScanQRCodeRoot"
component={ScanQRCodeRoot}

View file

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { View, Image, TouchableOpacity, StyleSheet, Appearance } from 'react-native';
import { View, Image, TouchableOpacity, StyleSheet, Appearance, StatusBar } from 'react-native';
import { Icon } from 'react-native-elements';
import Biometric from './class/biometrics';
import { SafeAreaView } from 'react-native-safe-area-context';
@ -48,9 +48,10 @@ const styles = StyleSheet.create({
});
export default class UnlockWith extends Component {
state = { biometricType: false, isStorageEncrypted: false, isAuthenticating: false };
state = { biometricType: false, isStorageEncrypted: false, isAuthenticating: false, appearance: Appearance.getColorScheme() };
async componentDidMount() {
Appearance.addChangeListener(this.appearanceChanged);
let biometricType = false;
if (await Biometric.isBiometricUseCapableAndEnabled()) {
biometricType = await Biometric.biometricType();
@ -63,6 +64,17 @@ export default class UnlockWith extends Component {
});
}
componentWillUnmount() {
Appearance.removeChangeListener();
}
appearanceChanged = () => {
const appearance = Appearance.getColorScheme();
if (appearance) {
this.setState({ appearance });
}
};
successfullyAuthenticated = () => {
EV(EV.enum.WALLETS_INITIALIZED);
NavigationService.dispatch(StackActions.replace('WalletsRoot'));
@ -94,9 +106,10 @@ export default class UnlockWith extends Component {
return <View />;
}
const color = Appearance.getColorScheme() === 'dark' ? '#FFFFFF' : '#000000';
const color = this.state.appearance === 'dark' ? '#FFFFFF' : '#000000';
return (
<SafeAreaView style={styles.root}>
<StatusBar barStyle="default" />
<View style={styles.container}>
<View style={styles.qrCode}>
<Image source={require('./img/qr-code.png')} style={styles.qrCodeImage} />
@ -115,9 +128,7 @@ export default class UnlockWith extends Component {
<>
<TouchableOpacity disabled={this.state.isAuthenticating} onPress={this.unlockWithBiometrics}>
<Image
source={
Appearance.getColorScheme() === 'dark' ? require('./img/faceid-default.png') : require('./img/faceid-dark.png')
}
source={this.state.appearance === 'dark' ? require('./img/faceid-default.png') : require('./img/faceid-dark.png')}
style={styles.icon}
/>
</TouchableOpacity>

View file

@ -39,32 +39,6 @@ export class AppStorage {
this.wallets = [];
this.tx_metadata = {};
this.cachedPassword = false;
this.settings = {
brandingColor: '#ffffff',
foregroundColor: '#0c2550',
buttonBackgroundColor: '#ccddf9',
buttonTextColor: '#0c2550',
buttonAlternativeTextColor: '#2f5fb3',
buttonDisabledBackgroundColor: '#eef0f4',
buttonDisabledTextColor: '#9aa0aa',
inputBorderColor: '#d2d2d2',
inputBackgroundColor: '#f5f5f5',
alternativeTextColor: '#9aa0aa',
alternativeTextColor2: '#0f5cc0',
buttonBlueBackgroundColor: '#ccddf9',
incomingBackgroundColor: '#d2f8d6',
incomingForegroundColor: '#37c0a1',
outgoingBackgroundColor: '#f8d2d2',
outgoingForegroundColor: '#d0021b',
successColor: '#37c0a1',
failedColor: '#ff0000',
shadowColor: '#000000',
inverseForegroundColor: '#ffffff',
hdborderColor: '#68BBE1',
hdbackgroundColor: '#ECF9FF',
lnborderColor: '#F7C056',
lnbackgroundColor: '#FFFAEF',
};
}
/**

View file

@ -9,6 +9,7 @@ import { PlaceholderWallet } from './wallets/placeholder-wallet';
import { SegwitBech32Wallet } from './wallets/segwit-bech32-wallet';
import { HDLegacyElectrumSeedP2PKHWallet } from './wallets/hd-legacy-electrum-seed-p2pkh-wallet';
import { HDSegwitElectrumSeedP2WPKHWallet } from './wallets/hd-segwit-electrum-seed-p2wpkh-wallet';
import { BlueCurrentTheme } from '../components/themes';
export default class WalletGradient {
static hdSegwitP2SHWallet = ['#65ceef', '#68bbe1'];
@ -20,7 +21,7 @@ export default class WalletGradient {
static hdLegacyBreadWallet = ['#fe6381', '#f99c42'];
static defaultGradients = ['#c65afb', '#9053fe'];
static lightningCustodianWallet = ['#f1be07', '#f79056'];
static createWallet = '#eef0f4';
static createWallet = BlueCurrentTheme.colors.lightButton;
static gradientsFor(type) {
let gradient;

105
components/themes.js Normal file
View file

@ -0,0 +1,105 @@
import { DefaultTheme, DarkTheme } from '@react-navigation/native';
import { Appearance } from 'react-native';
export const BlueDefaultTheme = {
...DefaultTheme,
closeImage: require('../img/close.png'),
scanImage: require('../img/scan.png'),
colors: {
...DefaultTheme.colors,
brandingColor: '#ffffff',
foregroundColor: '#0c2550',
borderTopColor: 'rgba(0, 0, 0, 0.1)',
buttonBackgroundColor: '#ccddf9',
buttonTextColor: '#0c2550',
buttonAlternativeTextColor: '#2f5fb3',
buttonDisabledBackgroundColor: '#eef0f4',
buttonDisabledTextColor: '#9aa0aa',
inputBorderColor: '#d2d2d2',
inputBackgroundColor: '#f5f5f5',
alternativeTextColor: '#9aa0aa',
alternativeTextColor2: '#0f5cc0',
buttonBlueBackgroundColor: '#ccddf9',
incomingBackgroundColor: '#d2f8d6',
incomingForegroundColor: '#37c0a1',
outgoingBackgroundColor: '#f8d2d2',
outgoingForegroundColor: '#d0021b',
successColor: '#37c0a1',
failedColor: '#ff0000',
shadowColor: '#000000',
inverseForegroundColor: '#ffffff',
hdborderColor: '#68BBE1',
hdbackgroundColor: '#ECF9FF',
lnborderColor: '#F7C056',
lnbackgroundColor: '#FFFAEF',
background: '#FFFFFF',
customHeader: 'rgba(0,0,0,0)',
lightButton: '#eef0f4',
ballReceive: '#d2f8d6',
ballOutgoing: '#f8d2d2',
lightBorder: '#ededed',
ballOutgoingExpired: '#EEF0F4',
modal: '#ffffff',
formBorder: '#d2d2d2',
modalButton: '#ccddf9',
darkGray: '#9AA0AA',
scanLabel: '#9AA0AA',
feeText: '#81868e',
feeLabel: '#d2f8d6',
feeValue: '#37c0a1',
labelText: '#81868e',
cta2: '#062453',
outputValue: '#13244D',
elevated: '#ffffff',
mainColor: '#CFDCF6',
success: '#ccddf9',
successCheck: '#0f5cc0',
},
};
export const BlueDarkTheme = {
...DarkTheme,
closeImage: require('../img/close-white.png'),
scanImage: require('../img/scan-white.png'),
colors: {
...BlueDefaultTheme.colors,
...DarkTheme.colors,
brandingColor: '#000000',
borderTopColor: '#9aa0aa',
foregroundColor: '#ffffff',
buttonDisabledBackgroundColor: '#3A3A3C',
buttonBackgroundColor: '#3A3A3C',
customHeader: '#000000',
buttonTextColor: '#ffffff',
lightButton: 'rgba(255,255,255,.1)',
buttonAlternativeTextColor: '#ffffff',
alternativeTextColor: '#9aa0aa',
alternativeTextColor2: '#0A84FF',
ballReceive: '#202020',
ballOutgoing: '#202020',
lightBorder: '#313030',
ballOutgoingExpired: '#202020',
modal: '#202020',
formBorder: '#202020',
inputBackgroundColor: '#262626',
modalButton: '#000000',
darkGray: '#3A3A3C',
feeText: '#81868e',
feeLabel: '#8EFFE5',
feeValue: '#000000',
cta2: '#ffffff',
outputValue: '#ffffff',
elevated: '#121212',
mainColor: '#0A84FF',
success: '#202020',
successCheck: '#0A84FF',
buttonBlueBackgroundColor: '#202020',
scanLabel: 'rgba(255,255,255,.2)',
labelText: '#ffffff',
},
};
export class BlueCurrentTheme {}
BlueCurrentTheme.colors = Appearance.getColorScheme() === 'dark' ? BlueDarkTheme.colors : BlueDefaultTheme.colors;
BlueCurrentTheme.closeImage = Appearance.getColorScheme() === 'dark' ? BlueDarkTheme.closeImage : BlueDefaultTheme.closeImage;
BlueCurrentTheme.scanImage = Appearance.getColorScheme() === 'dark' ? BlueDarkTheme.scanImage : BlueDefaultTheme.scanImage;

BIN
img/scan-white.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B

BIN
img/scan-white@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

BIN
img/scan-white@3x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

View file

@ -60,14 +60,14 @@
]
},
"dependencies": {
"@babel/preset-env": "7.10.2",
"@babel/preset-env": "7.10.3",
"@react-native-community/async-storage": "1.11.0",
"@react-native-community/blur": "3.6.0",
"@react-native-community/clipboard": "1.2.2",
"@react-native-community/masked-view": "0.1.10",
"@react-native-community/slider": "3.0.0",
"@react-navigation/native": "5.5.1",
"@react-navigation/stack": "5.5.1",
"@react-navigation/native": "5.6.1",
"@react-navigation/stack": "5.6.2",
"@remobile/react-native-qrcode-local-image": "git+https://github.com/BlueWallet/react-native-qrcode-local-image.git",
"@sentry/react-native": "1.4.5",
"amplitude-js": "5.11.0",

View file

@ -287,12 +287,6 @@ const styles = StyleSheet.create({
});
export default class Browser extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: 'Lapp Browser',
headerLeft: null,
});
constructor(props) {
super(props);
if (!props.route.params.fromSecret) throw new Error('Invalid param');
@ -435,7 +429,7 @@ export default class Browser extends Component {
return (
<SafeBlueArea>
<View style={styles.safeRoot}>
<StatusBar barStyle="light-content" />
<StatusBar barStyle="default" />
<TouchableOpacity
disabled={!this.state.canGoBack}
onPress={() => {
@ -516,3 +510,9 @@ Browser.propTypes = {
params: PropTypes.object,
}),
};
Browser.navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: 'Lapp Browser',
headerLeft: null,
});

View file

@ -11,6 +11,7 @@ import {
TouchableOpacity,
Text,
StyleSheet,
Image,
} from 'react-native';
import {
BlueNavigationStyle,
@ -26,6 +27,7 @@ import { BitcoinUnit, Chain } from '../../models/bitcoinUnits';
import * as NavigationService from '../../NavigationService';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { Icon } from 'react-native-elements';
import { BlueCurrentTheme } from '../../components/themes';
const currency = require('../../blue_modules/currency');
const BlueApp = require('../../BlueApp');
const EV = require('../../blue_modules/events');
@ -37,14 +39,13 @@ const styles = StyleSheet.create({
marginVertical: 16,
minHeight: 45,
alignContent: 'center',
backgroundColor: '#FFFFFF',
},
scanRoot: {
height: 36,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
backgroundColor: '#9AA0AA',
backgroundColor: BlueCurrentTheme.colors.scanLabel,
borderRadius: 4,
paddingVertical: 4,
paddingHorizontal: 8,
@ -52,7 +53,7 @@ const styles = StyleSheet.create({
},
scanClick: {
marginLeft: 4,
color: BlueApp.settings.inverseForegroundColor,
color: BlueCurrentTheme.colors.inverseForegroundColor,
},
walletRoot: {
marginBottom: 16,
@ -78,18 +79,18 @@ const styles = StyleSheet.create({
alignItems: 'center',
},
walletNameText: {
color: '#0c2550',
color: BlueCurrentTheme.colors.buttonAlternativeTextColor,
fontSize: 14,
},
walletNameBalance: {
color: '#0c2550',
color: BlueCurrentTheme.colors.buttonAlternativeTextColor,
fontSize: 14,
fontWeight: '600',
marginLeft: 8,
marginRight: 4,
},
walletNameSats: {
color: '#0c2550',
color: BlueCurrentTheme.colors.buttonAlternativeTextColor,
fontSize: 11,
fontWeight: '600',
textAlignVertical: 'bottom',
@ -102,19 +103,19 @@ const styles = StyleSheet.create({
root: {
flex: 1,
justifyContent: 'space-between',
backgroundColor: '#FFFFFF',
backgroundColor: BlueCurrentTheme.colors.elevated,
},
amount: {
flex: 1,
backgroundColor: '#FFFFFF',
backgroundColor: BlueCurrentTheme.colors.elevated,
},
fiat: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderColor: BlueCurrentTheme.colors.formBorder,
borderBottomColor: BlueCurrentTheme.colors.formBorder,
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
minHeight: 44,
height: 44,
marginHorizontal: 20,
@ -131,11 +132,6 @@ const styles = StyleSheet.create({
});
export default class LNDCreateInvoice extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: loc.receive.header,
});
constructor(props) {
super(props);
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
@ -356,7 +352,7 @@ export default class LNDCreateInvoice extends Component {
}}
style={styles.scanRoot}
>
<Icon name="qrcode" size={22} type="font-awesome" color={BlueApp.settings.inverseForegroundColor} />
<Image style={{}} source={require('../../img/scan-white.png')} />
<Text style={styles.scanClick}>{loc.send.details.scan}</Text>
</TouchableOpacity>
);
@ -478,3 +474,8 @@ LNDCreateInvoice.propTypes = {
}),
}),
};
LNDCreateInvoice.navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
headerTitle: loc.receive.header,
headerLeft: null,
});

View file

@ -13,7 +13,7 @@ import {
import PropTypes from 'prop-types';
import QRCode from 'react-native-qrcode-svg';
/** @type {AppStorage} */
const BlueApp = require('../../BlueApp');
import { BlueCurrentTheme } from '../../components/themes';
const loc = require('../../loc');
const styles = StyleSheet.create({
@ -21,9 +21,11 @@ const styles = StyleSheet.create({
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: BlueCurrentTheme.colors.elevated,
},
root: {
flex: 1,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
wrapper: {
flex: 1,
@ -42,11 +44,6 @@ const styles = StyleSheet.create({
});
export default class LNDViewAdditionalInvoiceInformation extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(),
title: 'Additional Information',
});
state = { walletInfo: undefined };
async componentDidMount() {
@ -78,8 +75,9 @@ export default class LNDViewAdditionalInvoiceInformation extends Component {
logo={require('../../img/qr-code.png')}
size={300}
logoSize={90}
color={BlueApp.settings.foregroundColor}
logoBackgroundColor={BlueApp.settings.brandingColor}
color={BlueCurrentTheme.colors.foregroundColor}
logoBackgroundColor={BlueCurrentTheme.colors.brandingColor}
backgroundColor={BlueCurrentTheme.colors.background}
/>
<BlueSpacing20 />
<BlueText>{loc.lndViewInvoice.open_direct_channel}</BlueText>
@ -90,7 +88,7 @@ export default class LNDViewAdditionalInvoiceInformation extends Component {
icon={{
name: 'share-alternative',
type: 'entypo',
color: BlueApp.settings.buttonTextColor,
color: BlueCurrentTheme.colors.buttonTextColor,
}}
onPress={async () => {
Share.share({
@ -111,3 +109,8 @@ LNDViewAdditionalInvoiceInformation.propTypes = {
params: PropTypes.object,
}),
};
LNDViewAdditionalInvoiceInformation.navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(),
title: 'Additional Information',
});

View file

@ -1,11 +1,12 @@
import React, { Component } from 'react';
import { View, Text, Dimensions, ScrollView, BackHandler, TouchableOpacity, StyleSheet } from 'react-native';
import { View, Text, Dimensions, StatusBar, ScrollView, BackHandler, TouchableOpacity, StyleSheet } from 'react-native';
import Share from 'react-native-share';
import {
BlueLoading,
BlueText,
SafeBlueArea,
BlueButton,
SecondButton,
BlueCopyTextToClipboard,
BlueNavigationStyle,
BlueSpacing20,
@ -16,7 +17,7 @@ import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { Icon } from 'react-native-elements';
import QRCode from 'react-native-qrcode-svg';
/** @type {AppStorage} */
const BlueApp = require('../../BlueApp');
import { BlueCurrentTheme } from '../../components/themes';
const loc = require('../../loc');
const EV = require('../../blue_modules/events');
const { width, height } = Dimensions.get('window');
@ -41,12 +42,12 @@ const styles = StyleSheet.create({
paddingBottom: 8,
},
valueText: {
color: '#0f5cc0',
color: BlueCurrentTheme.colors.alternativeTextColor2,
fontSize: 32,
fontWeight: '600',
},
valueSats: {
color: '#0f5cc0',
color: BlueCurrentTheme.colors.alternativeTextColor2,
fontSize: 16,
marginHorizontal: 4,
paddingBottom: 3,
@ -69,6 +70,7 @@ const styles = StyleSheet.create({
paidMark: {
marginTop: -100,
marginBottom: 16,
backgroundColor: BlueCurrentTheme.colors.success,
},
detailsRoot: {
flex: 1,
@ -81,12 +83,12 @@ const styles = StyleSheet.create({
alignItems: 'center',
},
detailsText: {
color: '#9aa0aa',
color: BlueCurrentTheme.colors.alternativeTextColor,
fontSize: 14,
marginRight: 8,
},
expired: {
backgroundColor: '#ccddf9',
backgroundColor: BlueCurrentTheme.colors.success,
width: 120,
height: 120,
borderRadius: 60,
@ -108,20 +110,11 @@ const styles = StyleSheet.create({
paddingHorizontal: 16,
},
additionalInfo: {
backgroundColor: BlueApp.settings.brandingColor,
backgroundColor: BlueCurrentTheme.colors.brandingColor,
},
});
export default class LNDViewInvoice extends Component {
static navigationOptions = ({ navigation, route }) =>
route.params.isModal === true
? {
...BlueNavigationStyle(navigation, true, () => navigation.dangerouslyGetParent().pop()),
title: 'Lightning Invoice',
headerLeft: null,
}
: { ...BlueNavigationStyle(), title: 'Lightning Invoice' };
constructor(props) {
super(props);
const invoice = props.route.params.invoice;
@ -212,6 +205,7 @@ export default class LNDViewInvoice extends Component {
if (this.state.showPreimageQr) {
return (
<SafeBlueArea style={styles.root}>
<StatusBar barStyle="default" />
<View style={styles.center}>
<BlueText>Preimage:</BlueText>
<BlueSpacing20 />
@ -220,8 +214,9 @@ export default class LNDViewInvoice extends Component {
logo={require('../../img/qr-code.png')}
size={this.state.qrCodeHeight}
logoSize={90}
color={BlueApp.settings.foregroundColor}
logoBackgroundColor={BlueApp.settings.brandingColor}
color={BlueCurrentTheme.colors.foregroundColor}
backgroundColor={BlueCurrentTheme.colors.background}
logoBackgroundColor={BlueCurrentTheme.colors.brandingColor}
/>
<BlueSpacing20 />
<BlueCopyTextToClipboard
@ -235,6 +230,7 @@ export default class LNDViewInvoice extends Component {
if (invoice.ispaid || invoice.type === 'paid_invoice') {
return (
<SafeBlueArea style={styles.root}>
<StatusBar barStyle="default" />
<View style={styles.valueRoot}>
{invoice.type === 'paid_invoice' && invoice.value && (
<View style={styles.valueAmount}>
@ -259,7 +255,7 @@ export default class LNDViewInvoice extends Component {
{invoice.payment_preimage && typeof invoice.payment_preimage === 'string' ? (
<TouchableOpacity style={styles.detailsTouch} onPress={() => this.setState({ showPreimageQr: true })}>
<Text style={styles.detailsText}>{loc.send.create.details}</Text>
<Icon name="angle-right" size={18} type="font-awesome" color="#9aa0aa" />
<Icon name="angle-right" size={18} type="font-awesome" color={BlueCurrentTheme.colors.alternativeTextColor} />
</TouchableOpacity>
) : (
<View />
@ -271,9 +267,10 @@ export default class LNDViewInvoice extends Component {
if (invoiceExpiration < now && !invoice.ispaid) {
return (
<SafeBlueArea style={styles.root}>
<StatusBar barStyle="default" />
<View style={styles.center}>
<View style={styles.expired}>
<Icon name="times" size={50} type="font-awesome" color="#0f5cc0" />
<Icon name="times" size={50} type="font-awesome" color={BlueCurrentTheme.colors.successCheck} />
</View>
<BlueText>{loc.lndViewInvoice.wasnt_paid_and_expired}</BlueText>
</View>
@ -294,6 +291,7 @@ export default class LNDViewInvoice extends Component {
// Invoice has not expired, nor has it been paid for.
return (
<SafeBlueArea>
<StatusBar barStyle="default" />
<ScrollView>
<View style={styles.activeRoot} onLayout={this.onLayout}>
<View style={styles.activeQrcode}>
@ -302,8 +300,9 @@ export default class LNDViewInvoice extends Component {
logo={require('../../img/qr-code.png')}
size={this.state.qrCodeHeight}
logoSize={90}
color={BlueApp.settings.foregroundColor}
logoBackgroundColor={BlueApp.settings.brandingColor}
color={BlueCurrentTheme.colors.foregroundColor}
logoBackgroundColor={BlueCurrentTheme.colors.brandingColor}
backgroundColor={BlueCurrentTheme.colors.background}
/>
</View>
@ -318,15 +317,9 @@ export default class LNDViewInvoice extends Component {
)}
<BlueCopyTextToClipboard text={this.state.invoice.payment_request} />
<BlueButton
icon={{
name: 'share-alternative',
type: 'entypo',
size: 10,
color: BlueApp.settings.buttonTextColor,
}}
<SecondButton
onPress={() => {
Share.open({ message: `lightning://${invoice.payment_request}` }).catch(error => console.log(error));
Share.open({ message: `lightning:${invoice.payment_request}` }).catch(error => console.log(error));
}}
title={loc.receive.details.share}
/>
@ -354,3 +347,21 @@ LNDViewInvoice.propTypes = {
params: PropTypes.object,
}),
};
LNDViewInvoice.navigationOptions = ({ navigation, route }) =>
route.params.isModal === true
? {
...BlueNavigationStyle(navigation, true, () => navigation.dangerouslyGetParent().pop()),
title: 'Lightning Invoice',
headerLeft: null,
headerStyle: {
backgroundColor: BlueCurrentTheme.colors.customHeader,
},
}
: {
...BlueNavigationStyle(),
title: 'Lightning Invoice',
headerStyle: {
backgroundColor: BlueCurrentTheme.colors.customHeader,
},
};

View file

@ -27,6 +27,7 @@ import { BitcoinUnit, Chain } from '../../models/bitcoinUnits';
import { Icon } from 'react-native-elements';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import Biometric from '../../class/biometrics';
import { BlueCurrentTheme } from '../../components/themes';
/** @type {AppStorage} */
const BlueApp = require('../../BlueApp');
const EV = require('../../blue_modules/events');
@ -58,18 +59,18 @@ const styles = StyleSheet.create({
alignItems: 'center',
},
walletWrapLabel: {
color: '#0c2550',
color: BlueCurrentTheme.colors.buttonAlternativeTextColor,
fontSize: 14,
},
walletWrapBalance: {
color: '#0c2550',
color: BlueCurrentTheme.colors.buttonAlternativeTextColor,
fontSize: 14,
fontWeight: '600',
marginLeft: 4,
marginRight: 4,
},
walletWrapSats: {
color: '#0c2550',
color: BlueCurrentTheme.colors.buttonAlternativeTextColor,
fontSize: 11,
fontWeight: '600',
textAlignVertical: 'bottom',
@ -77,6 +78,7 @@ const styles = StyleSheet.create({
},
root: {
flex: 1,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
scroll: {
flex: 1,
@ -106,12 +108,6 @@ const styles = StyleSheet.create({
});
export default class ScanLndInvoice extends React.Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: loc.send.header,
headerLeft: null,
});
state = {
isLoading: false,
isAmountInitiallyEmpty: false,
@ -465,3 +461,9 @@ ScanLndInvoice.propTypes = {
}),
}),
};
ScanLndInvoice.navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: loc.send.header,
headerLeft: null,
});

View file

@ -17,10 +17,6 @@ const styles = StyleSheet.create({
});
export default class PlausibleDeniability extends Component {
static navigationOptions = {
...BlueNavigationStyle(),
title: loc.plausibledeniability.title,
};
constructor(props) {
super(props);
@ -92,3 +88,8 @@ PlausibleDeniability.propTypes = {
popToTop: PropTypes.func,
}),
};
PlausibleDeniability.navigationOptions = ({ navigation, route }) => ({
...BlueNavigationStyle(),
title: loc.plausibledeniability.title,
});

View file

@ -51,11 +51,6 @@ const styles = StyleSheet.create({
});
export default class AztecoRedeem extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueCreateTxNavigationStyle(navigation),
title: 'Redeem Azte.co voucher',
});
state = { isLoading: true };
constructor(props) {
@ -156,7 +151,7 @@ export default class AztecoRedeem extends Component {
return (
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View>
<StatusBar barStyle="light-content" />
<StatusBar barStyle="default" />
<View style={styles.root}>
<Text>Your voucher code is</Text>
<BlueText style={styles.code}>
@ -187,3 +182,8 @@ AztecoRedeem.propTypes = {
}),
}),
};
AztecoRedeem.navigationOptions = ({ navigation }) => ({
...BlueCreateTxNavigationStyle(navigation),
title: 'Redeem Azte.co voucher',
});

View file

@ -11,19 +11,19 @@ import {
ScrollView,
} from 'react-native';
import QRCode from 'react-native-qrcode-svg';
import { useNavigation, useRoute } from '@react-navigation/native';
import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
import {
BlueLoading,
SafeBlueArea,
BlueLoadingHook,
BlueCopyTextToClipboard,
BlueButton,
BlueButtonLink,
BlueNavigationStyle,
SecondButton,
BlueButtonLinkHook,
is,
BlueBitcoinAmount,
BlueText,
BlueSpacing20,
BlueAlertWalletExportReminder,
BlueNavigationStyle,
} from '../../BlueComponents';
import Privacy from '../../Privacy';
import Share from 'react-native-share';
@ -32,6 +32,7 @@ import Modal from 'react-native-modal';
import HandoffSettings from '../../class/handoff';
import DeeplinkSchemaMatch from '../../class/deeplink-schema-match';
import Handoff from 'react-native-handoff';
import { BlueCurrentTheme } from '../../components/themes';
/** @type {AppStorage} */
const BlueApp = require('../../BlueApp');
const loc = require('../../loc');
@ -49,6 +50,89 @@ const ReceiveDetails = () => {
const [isCustom, setIsCustom] = useState(false);
const [isCustomModalVisible, setIsCustomModalVisible] = useState(false);
const { navigate, goBack } = useNavigation();
const { colors } = useTheme();
const styles = StyleSheet.create({
modalContent: {
backgroundColor: BlueCurrentTheme.colors.modal,
padding: 22,
justifyContent: 'center',
alignItems: 'center',
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
borderTopColor: colors.foregroundColor,
borderWidth: colors.borderWidth,
minHeight: 350,
height: 350,
},
bottomModal: {
justifyContent: 'flex-end',
margin: 0,
},
customAmount: {
flexDirection: 'row',
borderColor: BlueCurrentTheme.colors.formBorder,
borderBottomColor: BlueCurrentTheme.colors.formBorder,
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
minHeight: 44,
height: 44,
marginHorizontal: 20,
alignItems: 'center',
marginVertical: 8,
borderRadius: 4,
},
customAmountText: {
flex: 1,
marginHorizontal: 8,
color: BlueCurrentTheme.colors.foregroundColor,
minHeight: 33,
},
root: {
flex: 1,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
scroll: {
justifyContent: 'space-between',
},
scrollBody: {
marginTop: 32,
alignItems: 'center',
paddingHorizontal: 16,
},
amount: {
color: BlueCurrentTheme.colors.foregroundColor,
fontWeight: '600',
fontSize: 36,
textAlign: 'center',
paddingBottom: 24,
},
label: {
color: BlueCurrentTheme.colors.foregroundColor,
fontWeight: '600',
textAlign: 'center',
paddingBottom: 24,
},
loading: {
alignItems: 'center',
width: 300,
height: 300,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
share: {
alignItems: 'center',
alignContent: 'flex-end',
marginBottom: 24,
},
modalButton: {
backgroundColor: BlueCurrentTheme.colors.modalButton,
paddingVertical: 14,
paddingHorizontal: 70,
maxWidth: '80%',
borderRadius: 50,
fontWeight: '700',
},
});
const renderReceiveDetails = useCallback(async () => {
console.log('receive/details - componentDidMount');
@ -144,14 +228,6 @@ const ReceiveDetails = () => {
setBip21encoded(DeeplinkSchemaMatch.bip21encode(address, { amount, label: customLabel }));
};
const clearCustomAmount = () => {
setIsCustom(false);
setIsCustomModalVisible(false);
setCustomAmount('');
setCustomLabel('');
setBip21encoded(DeeplinkSchemaMatch.bip21encode(address));
};
const renderCustomAmountModal = () => {
return (
<Modal isVisible={isCustomModalVisible} style={styles.bottomModal} onBackdropPress={dismissCustomAmountModal}>
@ -175,9 +251,8 @@ const ReceiveDetails = () => {
</View>
<BlueSpacing20 />
<View>
<BlueButton title={loc.receive.details.create} onPress={createCustomAmountAddress} />
<BlueButton style={styles.modalButton} title={loc.receive.details.create} onPress={createCustomAmountAddress} />
<BlueSpacing20 />
<BlueButtonLink title="Reset" onPress={clearCustomAmount} />
</View>
<BlueSpacing20 />
</View>
@ -206,7 +281,7 @@ const ReceiveDetails = () => {
};
return (
<SafeBlueArea style={styles.root}>
<View style={styles.root}>
<StatusBar barStyle="light-content" />
{isHandOffUseEnabled && address !== undefined && (
<Handoff
@ -215,7 +290,7 @@ const ReceiveDetails = () => {
url={`https://blockstream.info/address/${address}`}
/>
)}
<ScrollView contentContainerStyle={styles.scroll} keyboardShouldPersistTaps="always">
<ScrollView style={styles.root} contentContainerStyle={styles.scroll} keyboardShouldPersistTaps="always">
<View style={styles.scrollBody}>
{isCustom && (
<>
@ -229,7 +304,7 @@ const ReceiveDetails = () => {
)}
{bip21encoded === undefined ? (
<View style={styles.loading}>
<BlueLoading />
<BlueLoadingHook />
</View>
) : (
<QRCode
@ -237,30 +312,23 @@ const ReceiveDetails = () => {
logo={require('../../img/qr-code.png')}
size={(is.ipad() && 300) || 300}
logoSize={90}
color={BlueApp.settings.foregroundColor}
logoBackgroundColor={BlueApp.settings.brandingColor}
color={colors.foregroundColor}
logoBackgroundColor={colors.brandingColor}
backgroundColor={colors.background}
ecl="H"
/>
)}
<BlueCopyTextToClipboard text={isCustom ? bip21encoded : address} />
</View>
<View style={styles.share}>
<BlueButtonLink title={loc.receive.details.setAmount} onPress={showCustomAmountModal} />
<BlueButtonLinkHook title={loc.receive.details.setAmount} onPress={showCustomAmountModal} />
<View>
<BlueButton
icon={{
name: 'share-alternative',
type: 'entypo',
color: BlueApp.settings.buttonTextColor,
}}
onPress={handleShareButtonPressed}
title={loc.receive.details.share}
/>
<SecondButton onPress={handleShareButtonPressed} title={loc.receive.details.share} />
</View>
</View>
{renderCustomAmountModal()}
</ScrollView>
</SafeBlueArea>
{renderCustomAmountModal()}
</View>
);
};
@ -271,75 +339,3 @@ ReceiveDetails.navigationOptions = ({ navigation }) => ({
});
export default ReceiveDetails;
const styles = StyleSheet.create({
modalContent: {
backgroundColor: '#FFFFFF',
padding: 22,
justifyContent: 'center',
alignItems: 'center',
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
borderColor: 'rgba(0, 0, 0, 0.1)',
minHeight: 350,
height: 350,
},
bottomModal: {
justifyContent: 'flex-end',
margin: 0,
},
customAmount: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
marginHorizontal: 20,
alignItems: 'center',
marginVertical: 8,
borderRadius: 4,
},
customAmountText: {
flex: 1,
marginHorizontal: 8,
color: '#81868e',
minHeight: 33,
},
root: {
flex: 1,
},
scroll: {
justifyContent: 'space-between',
},
scrollBody: {
marginTop: 32,
alignItems: 'center',
paddingHorizontal: 16,
},
amount: {
color: '#0c2550',
fontWeight: '600',
fontSize: 36,
textAlign: 'center',
paddingBottom: 24,
},
label: {
color: '#0c2550',
fontWeight: '600',
textAlign: 'center',
paddingBottom: 24,
},
loading: {
alignItems: 'center',
width: 300,
height: 300,
},
share: {
alignItems: 'center',
alignContent: 'flex-end',
marginBottom: 24,
},
});

View file

@ -1,8 +1,9 @@
import React, { Component } from 'react';
import { ScrollView, View, StyleSheet } from 'react-native';
import { BlueLoading, BlueSpacing20, SafeBlueArea, BlueCard, BlueText, BlueNavigationStyle } from '../BlueComponents';
import { BlueSpacing20, SafeBlueArea, BlueCard, BlueText, BlueNavigationStyle, BlueLoadingHook } from '../BlueComponents';
import PropTypes from 'prop-types';
import { SegwitP2SHWallet, LegacyWallet, HDSegwitP2SHWallet, HDSegwitBech32Wallet } from '../class';
import { BlueCurrentTheme } from '../components/themes';
const bitcoin = require('bitcoinjs-lib');
const BlueCrypto = require('react-native-blue-crypto');
const encryption = require('../blue_modules/encryption');
@ -11,6 +12,7 @@ const BlueElectrum = require('../blue_modules/BlueElectrum');
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: BlueCurrentTheme.colors.background,
},
center: {
alignItems: 'center',
@ -18,11 +20,6 @@ const styles = StyleSheet.create({
});
export default class Selftest extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(),
title: 'Self test',
});
constructor(props) {
super(props);
this.state = {
@ -213,7 +210,7 @@ export default class Selftest extends Component {
render() {
if (this.state.isLoading) {
return <BlueLoading />;
return <BlueLoadingHook />;
}
return (
@ -261,3 +258,8 @@ Selftest.propTypes = {
goBack: PropTypes.func,
}),
};
Selftest.navigationOptions = () => ({
...BlueNavigationStyle(),
title: 'Self test',
});

View file

@ -12,7 +12,9 @@ import {
BlueFormLabel,
BlueTextCentered,
BlueBigCheckmark,
BlueNavigationStyle,
} from '../../BlueComponents';
import { BlueCurrentTheme } from '../../components/themes';
import BlueElectrum from '../../blue_modules/BlueElectrum';
const bitcoin = require('bitcoinjs-lib');
@ -23,7 +25,7 @@ const BROADCAST_RESULT = Object.freeze({
error: 'error',
});
export default function Broadcast() {
const Broadcast = () => {
const [tx, setTx] = useState('');
const [txHex, setTxHex] = useState('');
const [broadcastResult, setBroadcastResult] = useState(BROADCAST_RESULT.none);
@ -72,7 +74,7 @@ export default function Broadcast() {
/>
<BlueSpacing10 />
<BlueButton title="BROADCAST" onPress={handleBroadcast} disabled={broadcastResult === BROADCAST_RESULT.pending} />
<BlueButton title="Send" onPress={handleBroadcast} disabled={broadcastResult === BROADCAST_RESULT.pending} />
</BlueCard>
)}
{BROADCAST_RESULT.success === broadcastResult && <SuccessScreen tx={tx} />}
@ -80,7 +82,13 @@ export default function Broadcast() {
</KeyboardAvoidingView>
</SafeBlueArea>
);
}
};
export default Broadcast;
Broadcast.navigationOptions = () => ({
...BlueNavigationStyle(),
title: 'Broadcast',
});
const styles = StyleSheet.create({
wrapper: {
@ -101,7 +109,7 @@ const styles = StyleSheet.create({
width: '100%',
},
link: {
color: 'blue',
color: BlueCurrentTheme.colors.foregroundColor,
},
mainCard: {
padding: 0,
@ -128,7 +136,7 @@ const styles = StyleSheet.create({
backgroundColor: '#d2f8d6',
borderRadius: 4,
marginTop: 20,
color: '#37c0a1',
color: BlueCurrentTheme.colors.foregroundColor,
fontWeight: '500',
fontSize: 14,
paddingHorizontal: 16,

View file

@ -17,20 +17,15 @@ import {
SegwitP2SHWallet,
SegwitBech32Wallet,
} from '../../class';
import { BlueCurrentTheme } from '../../components/themes';
const loc = require('../../loc');
const EV = require('../../blue_modules/events');
const currency = require('../../blue_modules/currency');
const BlueElectrum = require('../../blue_modules/BlueElectrum');
const Bignumber = require('bignumber.js');
/** @type {AppStorage} */
const BlueApp = require('../../BlueApp');
export default class Confirm extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(null, false),
title: loc.send.confirm.header,
});
constructor(props) {
super(props);
@ -207,19 +202,19 @@ export default class Confirm extends Component {
const styles = StyleSheet.create({
transactionDetailsTitle: {
color: '#0c2550',
color: BlueCurrentTheme.colors.foregroundColor,
fontWeight: '500',
fontSize: 17,
marginBottom: 2,
},
transactionDetailsSubtitle: {
color: '#9aa0aa',
color: BlueCurrentTheme.colors.feeText,
fontWeight: '500',
fontSize: 15,
marginBottom: 20,
},
transactionAmountFiat: {
color: '#9aa0aa',
color: BlueCurrentTheme.colors.feeText,
fontWeight: '500',
fontSize: 15,
marginVertical: 20,
@ -230,12 +225,12 @@ const styles = StyleSheet.create({
justifyContent: 'center',
},
valueValue: {
color: '#0f5cc0',
color: BlueCurrentTheme.colors.alternativeTextColor2,
fontSize: 36,
fontWeight: '600',
},
valueUnit: {
color: '#0f5cc0',
color: BlueCurrentTheme.colors.alternativeTextColor2,
fontSize: 16,
marginHorizontal: 4,
paddingBottom: 6,
@ -248,19 +243,18 @@ const styles = StyleSheet.create({
marginVertical: 8,
},
separator: {
backgroundColor: BlueApp.settings.inputBorderColor,
height: 0.5,
margin: 16,
},
root: {
flex: 1,
paddingTop: 19,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
rootWrap: {
marginTop: 16,
alignItems: 'center',
justifyContent: 'space-between',
backgroundColor: '#FFFFFF',
},
flat: {
maxHeight: '55%',
@ -270,7 +264,6 @@ const styles = StyleSheet.create({
justifyContent: 'center',
paddingTop: 16,
paddingBottom: 16,
backgroundColor: '#FFFFFF',
},
cardText: {
color: '#37c0a1',
@ -284,7 +277,7 @@ const styles = StyleSheet.create({
marginVertical: 24,
},
txText: {
color: '#0c2550',
color: BlueCurrentTheme.colors.buttonTextColor,
fontSize: 15,
fontWeight: '500',
alignSelf: 'center',
@ -301,3 +294,8 @@ Confirm.propTypes = {
params: PropTypes.object,
}),
};
Confirm.navigationOptions = () => ({
...BlueNavigationStyle(null, false),
title: loc.send.confirm.header,
});

View file

@ -22,31 +22,11 @@ import { BitcoinUnit } from '../../models/bitcoinUnits';
import { Icon } from 'react-native-elements';
import Share from 'react-native-share';
import RNFS from 'react-native-fs';
/** @type {AppStorage} */
const BlueApp = require('../../BlueApp');
import { BlueCurrentTheme } from '../../components/themes';
const loc = require('../../loc');
const currency = require('../../blue_modules/currency');
export default class SendCreate extends Component {
static navigationOptions = ({ navigation, route }) => {
let headerRight;
if (route.params.exportTXN) {
headerRight = () => (
<TouchableOpacity style={styles.export} onPress={route.params.exportTXN}>
<Icon size={22} name="share-alternative" type="entypo" color={BlueApp.settings.foregroundColor} />
</TouchableOpacity>
);
} else {
headerRight = null;
}
return {
...BlueNavigationStyle,
title: loc.send.create.details,
headerRight,
};
};
constructor(props) {
super(props);
console.log('send/create constructor');
@ -183,13 +163,13 @@ export default class SendCreate extends Component {
const styles = StyleSheet.create({
transactionDetailsTitle: {
color: '#0c2550',
color: BlueCurrentTheme.colors.feeText,
fontWeight: '500',
fontSize: 17,
marginBottom: 2,
},
transactionDetailsSubtitle: {
color: '#9aa0aa',
color: BlueCurrentTheme.colors.foregroundColor,
fontWeight: '500',
fontSize: 15,
marginBottom: 20,
@ -201,20 +181,21 @@ const styles = StyleSheet.create({
alignSelf: 'flex-end',
},
separator: {
backgroundColor: BlueApp.settings.inputBorderColor,
backgroundColor: BlueCurrentTheme.colors.inputBorderColor,
height: 0.5,
marginVertical: 16,
},
root: {
flex: 1,
paddingTop: 19,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
card: {
alignItems: 'center',
flex: 1,
},
cardText: {
color: '#0c2550',
color: BlueCurrentTheme.colors.foregroundColor,
fontWeight: '500',
},
cardTx: {
@ -251,3 +232,22 @@ SendCreate.propTypes = {
params: PropTypes.object,
}),
};
SendCreate.navigationOptions = ({ navigation, route }) => {
let headerRight;
if (route.params.exportTXN) {
headerRight = () => (
<TouchableOpacity style={styles.export} onPress={route.params.exportTXN}>
<Icon size={22} name="share-alternative" type="entypo" color={BlueCurrentTheme.colors.foregroundColor} />
</TouchableOpacity>
);
} else {
headerRight = null;
}
return {
...BlueNavigationStyle,
title: loc.send.create.details,
headerRight,
};
};

View file

@ -40,6 +40,7 @@ import { BitcoinTransaction } from '../../models/bitcoinTransactionInfo';
import DocumentPicker from 'react-native-document-picker';
import RNFS from 'react-native-fs';
import DeeplinkSchemaMatch from '../../class/deeplink-schema-match';
import { BlueCurrentTheme } from '../../components/themes';
const bitcoin = require('bitcoinjs-lib');
const currency = require('../../blue_modules/currency');
const BigNumber = require('bignumber.js');
@ -53,34 +54,36 @@ const styles = StyleSheet.create({
loading: {
flex: 1,
paddingTop: 20,
backgroundColor: '#FFFFFF',
backgroundColor: BlueCurrentTheme.colors.background,
},
root: {
flex: 1,
justifyContent: 'space-between',
backgroundColor: '#FFFFFF',
backgroundColor: BlueCurrentTheme.colors.elevated,
},
scrollViewContent: {
flexWrap: 'wrap',
flexDirection: 'row',
},
modalContent: {
backgroundColor: '#FFFFFF',
backgroundColor: BlueCurrentTheme.colors.modal,
padding: 22,
justifyContent: 'center',
alignItems: 'center',
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
borderColor: 'rgba(0, 0, 0, 0.1)',
borderTopColor: BlueCurrentTheme.colors.borderTopColor,
borderWidth: BlueCurrentTheme.colors.borderWidth,
minHeight: 200,
height: 200,
},
advancedTransactionOptionsModalContent: {
backgroundColor: '#FFFFFF',
backgroundColor: BlueCurrentTheme.colors.modal,
padding: 22,
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
borderColor: 'rgba(0, 0, 0, 0.1)',
borderTopColor: BlueCurrentTheme.colors.borderTopColor,
borderWidth: BlueCurrentTheme.colors.borderWidth,
minHeight: 130,
},
bottomModal: {
@ -88,7 +91,7 @@ const styles = StyleSheet.create({
margin: 0,
},
feeSliderInput: {
backgroundColor: '#d2f8d6',
backgroundColor: BlueCurrentTheme.colors.feeLabel,
minWidth: 127,
height: 60,
borderRadius: 8,
@ -98,7 +101,7 @@ const styles = StyleSheet.create({
},
feeSliderText: {
fontWeight: '600',
color: '#37c0a1',
color: BlueCurrentTheme.colors.feeValue,
marginBottom: 0,
marginRight: 4,
textAlign: 'right',
@ -106,7 +109,7 @@ const styles = StyleSheet.create({
},
feeSliderUnit: {
fontWeight: '600',
color: '#37c0a1',
color: BlueCurrentTheme.colors.feeValue,
paddingRight: 4,
textAlign: 'left',
fontSize: 16,
@ -137,7 +140,6 @@ const styles = StyleSheet.create({
marginHorizontal: 56,
marginVertical: 16,
alignContent: 'center',
backgroundColor: '#FFFFFF',
minHeight: 44,
},
select: {
@ -159,21 +161,22 @@ const styles = StyleSheet.create({
marginVertical: 4,
},
selectLabel: {
color: '#0c2550',
color: BlueCurrentTheme.colors.buttonTextColor,
fontSize: 14,
},
of: {
alignSelf: 'flex-end',
marginRight: 18,
marginVertical: 8,
color: BlueCurrentTheme.colors.feeText,
},
memo: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderColor: BlueCurrentTheme.colors.formBorder,
borderBottomColor: BlueCurrentTheme.colors.formBorder,
borderWidth: 1,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
minHeight: 44,
height: 44,
marginHorizontal: 20,
@ -194,11 +197,11 @@ const styles = StyleSheet.create({
alignItems: 'center',
},
feeLabel: {
color: '#81868e',
color: BlueCurrentTheme.colors.feeText,
fontSize: 14,
},
feeRow: {
backgroundColor: '#d2f8d6',
backgroundColor: BlueCurrentTheme.colors.feeLabel,
minWidth: 40,
height: 25,
borderRadius: 4,
@ -208,24 +211,19 @@ const styles = StyleSheet.create({
paddingHorizontal: 10,
},
feeValue: {
color: '#37c0a1',
color: BlueCurrentTheme.colors.feeValue,
marginBottom: 0,
marginRight: 4,
textAlign: 'right',
},
feeUnit: {
color: '#37c0a1',
color: BlueCurrentTheme.colors.feeValue,
paddingRight: 4,
textAlign: 'left',
},
});
export default class SendDetails extends Component {
static navigationOptions = ({ navigation, route }) => ({
...BlueCreateTxNavigationStyle(navigation, route.params.withAdvancedOptionsMenuButton, route.params.advancedOptionsMenuButtonAction),
title: loc.send.header,
});
state = { isLoading: true };
constructor(props) {
@ -1082,3 +1080,8 @@ SendDetails.propTypes = {
}),
}),
};
SendDetails.navigationOptions = ({ navigation, route }) => ({
...BlueCreateTxNavigationStyle(navigation, route.params.withAdvancedOptionsMenuButton, route.params.advancedOptionsMenuButtonAction),
title: loc.send.header,
});

View file

@ -17,6 +17,7 @@ import {
import Clipboard from '@react-native-community/clipboard';
import {
BlueButton,
SecondButton,
BlueText,
SafeBlueArea,
BlueCard,
@ -34,6 +35,7 @@ import RNFS from 'react-native-fs';
import DocumentPicker from 'react-native-document-picker';
import { decodeUR, extractSingleWorkload } from 'bc-ur/dist';
import { Psbt } from 'bitcoinjs-lib';
import { BlueCurrentTheme } from '../../components/themes';
const loc = require('../../loc');
const EV = require('../../blue_modules/events');
const BlueElectrum = require('../../blue_modules/BlueElectrum');
@ -45,6 +47,7 @@ const { height, width } = Dimensions.get('window');
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
scrollViewContent: {
flexGrow: 1,
@ -86,15 +89,15 @@ const styles = StyleSheet.create({
flex: 1,
},
hexLabel: {
color: '#0c2550',
color: BlueCurrentTheme.colors.foregroundColor,
fontWeight: '500',
},
hexInput: {
borderColor: '#ebebeb',
backgroundColor: '#d2f8d6',
borderColor: BlueCurrentTheme.colors.formBorder,
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
borderRadius: 4,
marginTop: 20,
color: '#37c0a1',
color: BlueCurrentTheme.colors.foregroundColor,
fontWeight: '500',
fontSize: 14,
paddingHorizontal: 16,
@ -105,7 +108,7 @@ const styles = StyleSheet.create({
marginVertical: 24,
},
hexText: {
color: '#9aa0aa',
color: BlueCurrentTheme.colors.foregroundColor,
fontSize: 15,
fontWeight: '500',
alignSelf: 'center',
@ -117,11 +120,6 @@ const styles = StyleSheet.create({
});
export default class PsbtWithHardwareWallet extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(null, false),
title: loc.send.header,
});
cameraRef = null;
_onReadUniformResource = ur => {
@ -319,7 +317,7 @@ export default class PsbtWithHardwareWallet extends Component {
<Text style={styles.hexText}>Verify on coinb.in</Text>
</TouchableOpacity>
<BlueSpacing20 />
<BlueButton onPress={this.broadcast} title={loc.send.confirm.sendNow} />
<SecondButton onPress={this.broadcast} title={loc.send.confirm.sendNow} />
</BlueCard>
</View>
);
@ -394,36 +392,36 @@ export default class PsbtWithHardwareWallet extends Component {
<View style={styles.container}>
<BlueCard>
<BlueText testID="TextHelperForPSBT">
This is partially signed bitcoin transaction (PSBT). Please finish signing it with your hardware wallet.
This is a partially signed bitcoin transaction (PSBT). Please finish signing it with your hardware wallet.
</BlueText>
<BlueSpacing20 />
<DynamicQRCode value={this.state.psbt.toHex()} capacity={200} />
<BlueSpacing20 />
<BlueButton
<SecondButton
icon={{
name: 'qrcode',
type: 'font-awesome',
color: BlueApp.settings.buttonTextColor,
color: BlueCurrentTheme.colors.buttonTextColor,
}}
onPress={() => this.setState({ renderScanner: true, animatedQRCodeData: [] })}
title="Scan Signed Transaction"
/>
<BlueSpacing20 />
<BlueButton
<SecondButton
icon={{
name: 'file-import',
type: 'material-community',
color: BlueApp.settings.buttonTextColor,
color: BlueCurrentTheme.colors.buttonTextColor,
}}
onPress={this.openSignedTransaction}
title="Open Signed Transaction"
/>
<BlueSpacing20 />
<BlueButton
<SecondButton
icon={{
name: 'share-alternative',
type: 'entypo',
color: BlueApp.settings.buttonTextColor,
color: BlueCurrentTheme.colors.buttonTextColor,
}}
onPress={this.exportPSBT}
title="Export to file"
@ -453,3 +451,8 @@ PsbtWithHardwareWallet.propTypes = {
params: PropTypes.object,
}),
};
PsbtWithHardwareWallet.navigationOptions = () => ({
...BlueNavigationStyle(null, false),
title: loc.send.header,
});

View file

@ -6,12 +6,14 @@ import { Text } from 'react-native-elements';
import { BlueButton, SafeBlueArea, BlueCard } from '../../BlueComponents';
import { BitcoinUnit } from '../../models/bitcoinUnits';
import PropTypes from 'prop-types';
import { BlueCurrentTheme } from '../../components/themes';
const loc = require('../../loc');
const styles = StyleSheet.create({
root: {
flex: 1,
paddingTop: 19,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
amout: {
alignItems: 'center',
@ -24,12 +26,12 @@ const styles = StyleSheet.create({
paddingBottom: 16,
},
amountValue: {
color: '#0f5cc0',
color: BlueCurrentTheme.colors.alternativeTextColor2,
fontSize: 36,
fontWeight: '600',
},
amountUnit: {
color: '#0f5cc0',
color: BlueCurrentTheme.colors.alternativeTextColor2,
fontSize: 16,
marginHorizontal: 4,
paddingBottom: 6,
@ -61,11 +63,6 @@ const styles = StyleSheet.create({
});
export default class Success extends Component {
static navigationOptions = {
headerShown: false,
gesturesEnabled: false,
};
constructor(props) {
super(props);
console.log('send/success constructor');
@ -103,7 +100,26 @@ export default class Success extends Component {
)}
</BlueCard>
<View style={styles.ready}>
<LottieView style={styles.lottie} source={require('../../img/bluenice.json')} autoPlay loop={false} />
<LottieView
style={styles.lottie}
source={require('../../img/bluenice.json')}
autoPlay
loop={false}
colorFilters={[
{
keypath: 'spark',
color: BlueCurrentTheme.colors.success,
},
{
keypath: 'circle',
color: BlueCurrentTheme.colors.success,
},
{
keypath: 'Oval',
color: BlueCurrentTheme.colors.successCheck,
},
]}
/>
</View>
<BlueCard>
<BlueButton
@ -134,3 +150,8 @@ Success.propTypes = {
params: PropTypes.object,
}),
};
Success.navigationOptions = {
headerShown: false,
gesturesEnabled: false,
};

View file

@ -1,9 +1,8 @@
import React, { useEffect, useState } from 'react';
import { ScrollView, Platform, TouchableWithoutFeedback, TouchableOpacity, StyleSheet } from 'react-native';
import { BlueLoading, BlueText, BlueSpacing20, BlueListItem, SafeBlueArea, BlueNavigationStyle, BlueCard } from '../../BlueComponents';
import PropTypes from 'prop-types';
import { BlueLoading, BlueTextHooks, BlueSpacing20, BlueListItemHooks, BlueNavigationStyle, BlueCard } from '../../BlueComponents';
import { AppStorage } from '../../class';
import { useNavigation } from '@react-navigation/native';
import { useNavigation, useTheme } from '@react-navigation/native';
import HandoffSettings from '../../class/handoff';
const BlueApp: AppStorage = require('../../BlueApp');
const loc = require('../../loc');
@ -19,6 +18,7 @@ const GeneralSettings = () => {
const [isAdancedModeEnabled, setIsAdancedModeEnabled] = useState(false);
const [isHandoffUseEnabled, setIsHandoffUseEnabled] = useState(false);
const { navigate } = useNavigation();
const { colors } = useTheme();
const onAdvancedModeSwitch = async value => {
await BlueApp.setIsAdancedModeEnabled(value);
setIsAdancedModeEnabled(value);
@ -37,46 +37,59 @@ const GeneralSettings = () => {
})();
});
const stylesWithThemeHook = {
root: {
...styles.root,
backgroundColor: colors.background,
},
scroll: {
...styles.scroll,
backgroundColor: colors.background,
},
scrollBody: {
...styles.scrollBody,
backgroundColor: colors.background,
},
};
return isLoading ? (
<BlueLoading />
) : (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<ScrollView>
{BlueApp.getWallets().length > 1 && (
<>
<BlueListItem component={TouchableOpacity} onPress={() => navigate('DefaultView')} title="On Launch" chevron />
</>
)}
{Platform.OS === 'ios' ? (
<>
<BlueListItem
hideChevron
title="Continuity"
Component={TouchableWithoutFeedback}
switch={{ onValueChange: onHandOffEnabledSwitch, value: isHandoffUseEnabled }}
/>
<BlueCard>
<BlueText>
When enabled, you will be able to view selected wallets, and transactions, using your other Apple iCloud connected devices.
</BlueText>
</BlueCard>
<BlueSpacing20 />
</>
) : null}
<BlueListItem
Component={TouchableWithoutFeedback}
title={loc.settings.enable_advanced_mode}
switch={{ onValueChange: onAdvancedModeSwitch, value: isAdancedModeEnabled }}
/>
<BlueCard>
<BlueText>
When enabled, you will see advanced options such as different wallet types, the ability to specify the LNDHub instance you wish
to connect to and custom entropy during wallet creation.
</BlueText>
</BlueCard>
<BlueSpacing20 />
</ScrollView>
</SafeBlueArea>
<ScrollView style={stylesWithThemeHook.scroll}>
{BlueApp.getWallets().length > 1 && (
<>
<BlueListItemHooks component={TouchableOpacity} onPress={() => navigate('DefaultView')} title="On Launch" chevron />
</>
)}
{Platform.OS === 'ios' ? (
<>
<BlueListItemHooks
hideChevron
title="Continuity"
Component={TouchableWithoutFeedback}
switch={{ onValueChange: onHandOffEnabledSwitch, value: isHandoffUseEnabled }}
/>
<BlueCard>
<BlueTextHooks>
When enabled, you will be able to view selected wallets, and transactions, using your other Apple iCloud connected devices.
</BlueTextHooks>
</BlueCard>
<BlueSpacing20 />
</>
) : null}
<BlueListItemHooks
Component={TouchableWithoutFeedback}
title={loc.settings.enable_advanced_mode}
switch={{ onValueChange: onAdvancedModeSwitch, value: isAdancedModeEnabled }}
/>
<BlueCard>
<BlueTextHooks>
When enabled, you will see advanced options such as different wallet types, the ability to specify the LNDHub instance you wish to
connect to and custom entropy during wallet creation.
</BlueTextHooks>
</BlueCard>
<BlueSpacing20 />
</ScrollView>
);
};
@ -85,12 +98,4 @@ GeneralSettings.navigationOptions = () => ({
title: 'General',
});
GeneralSettings.propTypes = {
navigation: PropTypes.shape({
navigate: PropTypes.func,
popToTop: PropTypes.func,
goBack: PropTypes.func,
}),
};
export default GeneralSettings;

View file

@ -1,42 +1,48 @@
import React, { useEffect, useState } from 'react';
import { ScrollView, TouchableOpacity, StyleSheet } from 'react-native';
import { BlueNavigationStyle, BlueLoading, SafeBlueArea, BlueListItem } from '../../BlueComponents';
import { useNavigation } from '@react-navigation/native';
import { ScrollView, StyleSheet } from 'react-native';
import { SafeBlueArea, BlueListItemHooks, BlueNavigationStyle, BlueLoadingHook } from '../../BlueComponents';
import { useNavigation, useTheme } from '@react-navigation/native';
const loc = require('../../loc');
const styles = StyleSheet.create({
root: {
flex: 1,
},
});
const NetworkSettings = () => {
const [isLoading, setIsLoading] = useState(true);
const { navigate } = useNavigation();
const { colors } = useTheme();
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: colors.background,
},
});
useEffect(() => {
setIsLoading(false);
}, []);
const navigateToElectrumSettings = () => {
navigate('ElectrumSettings');
};
const navigateToLightningSettings = () => {
navigate('LightningSettings');
};
const navigateToBroadcast = () => {
navigate('Broadcast');
};
return isLoading ? (
<BlueLoading />
<BlueLoadingHook />
) : (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<ScrollView>
<BlueListItem title="Electrum server" component={TouchableOpacity} onPress={() => navigate('ElectrumSettings')} chevron />
<BlueListItem
title={loc.settings.lightning_settings}
component={TouchableOpacity}
onPress={() => navigate('LightningSettings')}
chevron
/>
<BlueListItem title="Broadcast transaction" component={TouchableOpacity} onPress={() => navigate('Broadcast')} chevron />
<BlueListItemHooks title="Electrum server" onPress={navigateToElectrumSettings} chevron />
<BlueListItemHooks title={loc.settings.lightning_settings} onPress={navigateToLightningSettings} chevron />
<BlueListItemHooks title="Broadcast transaction" onPress={navigateToBroadcast} chevron />
</ScrollView>
</SafeBlueArea>
);
};
NetworkSettings.navigationOptions = {
NetworkSettings.navigationOptions = () => ({
...BlueNavigationStyle(),
title: 'Network',
};
});
export default NetworkSettings;

View file

@ -1,15 +1,15 @@
import React, { useEffect, useState } from 'react';
import { ScrollView, Linking, Dimensions, Image, View, Text, StyleSheet } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { useNavigation, useTheme } from '@react-navigation/native';
import {
BlueTextCentered,
BlueLoading,
BlueSpacing20,
BlueButton,
SafeBlueArea,
BlueCard,
BlueListItemHooks,
BlueNavigationStyle,
BlueListItem,
BlueLoadingHook,
} from '../../BlueComponents';
import { getApplicationName, getVersion, getBundleId, getBuildNumber } from 'react-native-device-info';
import Rate, { AndroidMarket } from 'react-native-rate';
@ -17,46 +17,46 @@ import Rate, { AndroidMarket } from 'react-native-rate';
const { width, height } = Dimensions.get('window');
const loc = require('../../loc/');
const styles = StyleSheet.create({
root: {
flex: 1,
},
center: {
justifyContent: 'center',
alignItems: 'center',
marginTop: 54,
},
logo: {
width: 102,
height: 124,
},
textFree: {
maxWidth: 260,
marginVertical: 24,
color: '#9AA0AA',
fontSize: 15,
textAlign: 'center',
fontWeight: '500',
},
textBackup: {
maxWidth: 260,
marginBottom: 40,
color: '#0C2550',
fontSize: 15,
textAlign: 'center',
fontWeight: '500',
},
buildWith: {
backgroundColor: '#f9f9f9',
padding: 16,
paddingTop: 0,
borderRadius: 8,
},
});
const About = () => {
const [isLoading, setIsLoading] = useState(true);
const { navigate } = useNavigation();
const { colors } = useTheme();
const styles = StyleSheet.create({
root: {
flex: 1,
},
center: {
justifyContent: 'center',
alignItems: 'center',
marginTop: 54,
},
logo: {
width: 102,
height: 124,
},
textFree: {
maxWidth: 260,
marginVertical: 24,
color: '#9AA0AA',
fontSize: 15,
textAlign: 'center',
fontWeight: '500',
},
textBackup: {
maxWidth: 260,
marginBottom: 40,
color: colors.foregroundColor,
fontSize: 15,
textAlign: 'center',
fontWeight: '500',
},
buildWith: {
backgroundColor: colors.inputBackgroundColor,
padding: 16,
paddingTop: 0,
borderRadius: 8,
},
});
useEffect(() => {
setIsLoading(false);
@ -103,7 +103,7 @@ const About = () => {
};
return isLoading ? (
<BlueLoading />
<BlueLoadingHook />
) : (
<SafeBlueArea style={styles.root}>
<ScrollView testID="AboutScrollView">
@ -115,7 +115,7 @@ const About = () => {
<BlueButton onPress={handleOnRatePress} title="Leave us a review ⭐🙏" />
</View>
</BlueCard>
<BlueListItem
<BlueListItemHooks
leftIcon={{
name: 'twitter',
type: 'font-awesome',
@ -124,7 +124,7 @@ const About = () => {
onPress={handleOnTwitterPress}
title="Follow us on Twitter"
/>
<BlueListItem
<BlueListItemHooks
leftIcon={{
name: 'telegram',
type: 'font-awesome',
@ -133,11 +133,11 @@ const About = () => {
onPress={handleOnTelegramPress}
title="Telegram chat"
/>
<BlueListItem
<BlueListItemHooks
leftIcon={{
name: 'github',
type: 'font-awesome',
color: 'black',
color: colors.foregroundColor,
}}
onPress={handleOnGithubPress}
title="GitHub"
@ -154,7 +154,7 @@ const About = () => {
<BlueTextCentered>Electrum server</BlueTextCentered>
</View>
</BlueCard>
<BlueListItem
<BlueListItemHooks
leftIcon={{
name: 'book',
type: 'font-awesome',
@ -164,17 +164,17 @@ const About = () => {
onPress={handleOnReleaseNotesPress}
title="Release notes"
/>
<BlueListItem
<BlueListItemHooks
leftIcon={{
name: 'law',
type: 'octicon',
color: 'black',
color: colors.foregroundColor,
}}
chevron
onPress={handleOnLicensingPress}
title="MIT License"
/>
<BlueListItem
<BlueListItemHooks
leftIcon={{
name: 'flask',
type: 'font-awesome',
@ -204,6 +204,6 @@ const About = () => {
About.navigationOptions = () => ({
...BlueNavigationStyle(),
title: loc.settings.about,
headerTitle: loc.settings.about,
});
export default About;

View file

@ -1,28 +1,31 @@
import React, { useState, useEffect } from 'react';
import { FlatList, TouchableOpacity, ActivityIndicator, View, StyleSheet } from 'react-native';
import { SafeBlueArea, BlueNavigationStyle, BlueListItem, BlueText, BlueCard } from '../../BlueComponents';
import { SafeBlueArea, BlueListItemHooks, BlueTextHooks, BlueCard, BlueNavigationStyle } from '../../BlueComponents';
import PropTypes from 'prop-types';
import { Icon } from 'react-native-elements';
import { FiatUnit } from '../../models/fiatUnit';
import { useTheme } from '@react-navigation/native';
const loc = require('../../loc');
const currency = require('../../blue_modules/currency');
const data = Object.values(FiatUnit);
const styles = StyleSheet.create({
flex: {
flex: 1,
},
activity: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
const Currency = () => {
const [isSavingNewPreferredCurrency, setIsSavingNewPreferredCurrency] = useState(false);
const [selectedCurrency, setSelectedCurrency] = useState(null);
const { colors } = useTheme();
const styles = StyleSheet.create({
flex: {
flex: 1,
backgroundColor: colors.background,
},
activity: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: colors.background,
},
});
useEffect(() => {
const fetchCurrency = async () => {
@ -49,7 +52,7 @@ const Currency = () => {
extraData={data}
renderItem={({ item }) => {
return (
<BlueListItem
<BlueListItemHooks
disabled={isSavingNewPreferredCurrency}
title={`${item.endPointKey} (${item.symbol})`}
{...(selectedCurrency.endPointKey === item.endPointKey
@ -68,7 +71,7 @@ const Currency = () => {
}}
/>
<BlueCard>
<BlueText>Prices are obtained from CoinDesk</BlueText>
<BlueTextHooks>Prices are obtained from CoinDesk</BlueTextHooks>
</BlueCard>
</SafeBlueArea>
);

View file

@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import { TouchableOpacity, View, TouchableWithoutFeedback, StyleSheet } from 'react-native';
import { SafeBlueArea, BlueCard, BlueText, BlueNavigationStyle, BlueListItem } from '../../BlueComponents';
import { View, TouchableWithoutFeedback, StyleSheet } from 'react-native';
import { SafeBlueArea, BlueCard, BlueNavigationStyle, BlueListItemHooks, BlueTextHooks } from '../../BlueComponents';
import OnAppLaunch from '../../class/on-app-launch';
import { useNavigation } from '@react-navigation/native';
const BlueApp = require('../../BlueApp');
@ -56,7 +56,7 @@ const DefaultView = () => {
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.flex}>
<View>
<BlueListItem
<BlueListItemHooks
title="View All Wallets"
Component={TouchableWithoutFeedback}
switch={{
@ -66,10 +66,10 @@ const DefaultView = () => {
}}
/>
<BlueCard>
<BlueText>When disabled, BlueWallet will immediately open the selected wallet at launch.</BlueText>
<BlueTextHooks>When disabled, BlueWallet will immediately open the selected wallet at launch.</BlueTextHooks>
</BlueCard>
{!viewAllWalletsEnabled && (
<BlueListItem title="Default into" component={TouchableOpacity} onPress={selectWallet} rightTitle={defaultWalletLabel} chevron />
<BlueListItemHooks title="Default into" onPress={selectWallet} rightTitle={defaultWalletLabel} chevron />
)}
</View>
</SafeBlueArea>

View file

@ -4,8 +4,9 @@ import { View, TextInput, StyleSheet } from 'react-native';
import { AppStorage } from '../../class';
import AsyncStorage from '@react-native-community/async-storage';
import { ScrollView } from 'react-native-gesture-handler';
import { BlueLoading, BlueSpacing20, BlueButton, SafeBlueArea, BlueCard, BlueNavigationStyle, BlueText } from '../../BlueComponents';
import PropTypes from 'prop-types';
import { BlueLoading, BlueSpacing20, BlueButton, SafeBlueArea, BlueCard, BlueText, BlueNavigationStyle } from '../../BlueComponents';
import { BlueCurrentTheme } from '../../components/themes';
const loc = require('../../loc');
const BlueElectrum = require('../../blue_modules/BlueElectrum');
@ -15,7 +16,7 @@ const styles = StyleSheet.create({
},
status: {
textAlign: 'center',
color: '#9AA0AA',
color: BlueCurrentTheme.colors.feeText,
marginBottom: 4,
},
connectWrap: {
@ -33,13 +34,13 @@ const styles = StyleSheet.create({
borderRadius: 20,
},
containerConnected: {
backgroundColor: '#D2F8D6',
backgroundColor: BlueCurrentTheme.colors.feeLabel,
},
containerDisconnected: {
backgroundColor: '#F8D2D2',
},
textConnected: {
color: '#37C0A1',
color: BlueCurrentTheme.colors.feeValue,
fontWeight: 'bold',
},
textDisconnected: {
@ -48,19 +49,19 @@ const styles = StyleSheet.create({
},
hostname: {
textAlign: 'center',
color: '#0C2550',
color: BlueCurrentTheme.colors.foregroundColor,
},
explain: {
color: '#9AA0AA',
color: BlueCurrentTheme.colors.feeText,
marginBottom: -24,
},
inputWrap: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderColor: BlueCurrentTheme.colors.formBorder,
borderBottomColor: BlueCurrentTheme.colors.formBorder,
borderWidth: 1,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
minHeight: 44,
height: 44,
alignItems: 'center',
@ -76,11 +77,6 @@ const styles = StyleSheet.create({
});
export default class ElectrumSettings extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(),
title: loc.settings.electrum_settings,
});
constructor(props) {
super(props);
this.state = {
@ -223,9 +219,7 @@ export default class ElectrumSettings extends Component {
}
}
ElectrumSettings.propTypes = {
navigation: PropTypes.shape({
navigate: PropTypes.func,
goBack: PropTypes.func,
}),
};
ElectrumSettings.navigationOptions = () => ({
...BlueNavigationStyle(),
title: loc.settings.electrum_settings,
});

View file

@ -1,106 +1,100 @@
/* global alert */
import React, { Component } from 'react';
import React, { useEffect, useState, useCallback } from 'react';
import { ScrollView, Alert, Platform, TouchableOpacity, TouchableWithoutFeedback, StyleSheet } from 'react-native';
import {
BlueLoading,
BlueHeaderDefaultSub,
BlueListItem,
BlueLoadingHook,
SafeBlueArea,
BlueNavigationStyle,
BlueSpacing20,
BlueCard,
BlueText,
BlueListItemHooks,
BlueHeaderDefaultSubHooks,
BlueTextHooks,
BlueNavigationStyle,
} from '../../BlueComponents';
import PropTypes from 'prop-types';
import { AppStorage } from '../../class';
import { useNavigation, StackActions } from '@react-navigation/native';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import Biometric from '../../class/biometrics';
import { colors } from 'react-native-elements';
const BlueApp: AppStorage = require('../../BlueApp');
const prompt = require('../../blue_modules/prompt');
const loc = require('../../loc');
const styles = StyleSheet.create({
root: {
flex: 1,
},
});
export default class EncryptStorage extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(),
title: 'Security',
const EncryptStorage = () => {
const [isLoading, setIsLoading] = useState(true);
const [deleteWalletsAfterUninstall, setDeleteWalletsAfterUninstall] = useState(false);
const [biometrics, setBiometrics] = useState({ isDeviceBiometricCapable: false, isBiometricsEnabled: false, biometricsType: '' });
const [storageIsEncrypted, setStorageIsEncrypted] = useState(false);
const { navigate, dispatch } = useNavigation();
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: colors.background,
},
});
constructor(props) {
super(props);
this.state = {
isLoading: true,
language: loc.getLanguage(),
deleteWalletsAfterUninstall: false,
biometrics: { isDeviceBiometricCapable: false, isBiometricsEnabled: false, biometricsType: '' },
};
}
async componentDidMount() {
const initialState = useCallback(async () => {
const isBiometricsEnabled = await Biometric.isBiometricUseEnabled();
const isDeviceBiometricCapable = await Biometric.isDeviceBiometricCapable();
const biometricsType = (await Biometric.biometricType()) || 'biometrics';
this.setState({
isLoading: false,
advancedModeEnabled: await BlueApp.isAdancedModeEnabled(),
storageIsEncrypted: await BlueApp.storageIsEncrypted(),
deleteWalletsAfterUninstall: await BlueApp.isDeleteWalletAfterUninstallEnabled(),
biometrics: { isBiometricsEnabled, isDeviceBiometricCapable, biometricsType },
});
}
const deleteWalletsAfterUninstall = await BlueApp.isDeleteWalletAfterUninstallEnabled();
const isStorageEncrypted = await BlueApp.storageIsEncrypted();
setBiometrics(biometrics);
setStorageIsEncrypted(isStorageEncrypted);
setDeleteWalletsAfterUninstall(deleteWalletsAfterUninstall);
setBiometrics({ isBiometricsEnabled, isDeviceBiometricCapable, biometricsType });
setIsLoading(false);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
initialState();
}, [initialState]);
decryptStorage = async () => {
const decryptStorage = useCallback(async () => {
const password = await prompt(loc.settings.password, loc._.storage_is_encrypted).catch(() => {
this.setState({ isLoading: false });
setIsLoading(false);
});
try {
await BlueApp.decryptStorage(password);
this.props.navigation.popToTop();
dispatch(StackActions.popToTop());
} catch (e) {
if (password) {
alert(loc._.bad_password);
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
}
this.setState({
isLoading: false,
storageIsEncrypted: await BlueApp.storageIsEncrypted(),
deleteWalletAfterUninstall: await BlueApp.isDeleteWalletAfterUninstallEnabled(),
});
setIsLoading(false);
setStorageIsEncrypted(await BlueApp.storageIsEncrypted());
setDeleteWalletsAfterUninstall(await BlueApp.isDeleteWalletAfterUninstallEnabled());
}
};
}, [dispatch]);
onDeleteWalletsAfterUninstallSwitch = async value => {
const onDeleteWalletsAfterUninstallSwitch = useCallback(async value => {
await BlueApp.setResetOnAppUninstallTo(value);
this.setState({ deleteWalletsAfterUninstall: value });
};
setDeleteWalletsAfterUninstall(value);
}, []);
onEncryptStorageSwitch = value => {
this.setState({ isLoading: true }, async () => {
const onEncryptStorageSwitch = useCallback(
async value => {
setIsLoading(true);
if (value === true) {
let p1 = await prompt(loc.settings.password, loc.settings.password_explain).catch(() => {
this.setState({ isLoading: false });
setIsLoading(false);
p1 = undefined;
});
if (!p1) {
this.setState({ isLoading: false });
setIsLoading(false);
return;
}
const p2 = await prompt(loc.settings.password, loc.settings.retype_password).catch(() => {
this.setState({ isLoading: false });
setIsLoading(false);
});
if (p1 === p2) {
await BlueApp.encryptStorage(p1);
this.setState({
isLoading: false,
storageIsEncrypted: await BlueApp.storageIsEncrypted(),
});
setIsLoading(false);
setStorageIsEncrypted(await BlueApp.storageIsEncrypted());
} else {
this.setState({ isLoading: false });
setIsLoading(false);
alert(loc.settings.passwords_do_not_match);
}
} else {
@ -111,93 +105,100 @@ export default class EncryptStorage extends Component {
{
text: loc.send.details.cancel,
style: 'cancel',
onPress: () => this.setState({ isLoading: false }),
onPress: () => setIsLoading(false),
},
{
text: loc._.ok,
style: 'destructive',
onPress: this.decryptStorage,
onPress: decryptStorage,
},
],
{ cancelable: false },
);
}
});
},
[decryptStorage],
);
const onUseBiometricSwitch = useCallback(
async value => {
const isBiometricsEnabled = {
isDeviceBiometricCapable: biometrics.isDeviceBiometricCapable,
isBiometricsEnabled: biometrics.isBiometricsEnabled,
biometricsType: biometrics.biometricsType,
};
if (await Biometric.unlockWithBiometrics()) {
isBiometricsEnabled.isBiometricsEnabled = value;
await Biometric.setBiometricUseEnabled(value);
setBiometrics(isBiometricsEnabled);
}
},
[biometrics],
);
const navigateToPlausibleDeniability = () => {
navigate('PlausibleDeniability');
};
onUseBiometricSwitch = async value => {
const isBiometricsEnabled = this.state.biometrics;
if (await Biometric.unlockWithBiometrics()) {
isBiometricsEnabled.isBiometricsEnabled = value;
await Biometric.setBiometricUseEnabled(value);
this.setState({ biometrics: isBiometricsEnabled });
}
};
render() {
if (this.state.isLoading) {
return <BlueLoading />;
}
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<ScrollView>
{this.state.biometrics.isDeviceBiometricCapable && (
<>
<BlueHeaderDefaultSub leftText="biometrics" rightComponent={null} />
<BlueListItem
title={`Use ${this.state.biometrics.biometricsType}`}
Component={TouchableWithoutFeedback}
switch={{ value: this.state.biometrics.isBiometricsEnabled, onValueChange: this.onUseBiometricSwitch }}
/>
<BlueCard>
<BlueText>
{this.state.biometrics.biometricsType} will be used to confirm your identity prior to making a transaction, unlocking,
exporting or deleting a wallet. {this.state.biometrics.biometricsType} will not be used to unlock an encrypted storage.
</BlueText>
</BlueCard>
<BlueSpacing20 />
</>
)}
<BlueHeaderDefaultSub leftText="storage" rightComponent={null} />
<BlueListItem
testID="EncyptedAndPasswordProtected"
hideChevron
title="Encrypted and Password protected"
Component={TouchableWithoutFeedback}
switch={{ onValueChange: this.onEncryptStorageSwitch, value: this.state.storageIsEncrypted }}
/>
{Platform.OS === 'ios' && (
<BlueListItem
hideChevron
title="Delete if BlueWallet is uninstalled"
return isLoading ? (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<BlueLoadingHook />
</SafeBlueArea>
) : (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<ScrollView contentContainerStyle={styles.root}>
{biometrics.isDeviceBiometricCapable && (
<>
<BlueHeaderDefaultSubHooks leftText="biometrics" rightComponent={null} />
<BlueListItemHooks
title={`Use ${biometrics.biometricsType}`}
Component={TouchableWithoutFeedback}
switch={{
onValueChange: this.onDeleteWalletsAfterUninstallSwitch,
value: this.state.deleteWalletsAfterUninstall,
}}
switch={{ value: biometrics.isBiometricsEnabled, onValueChange: onUseBiometricSwitch }}
/>
)}
{this.state.storageIsEncrypted && (
<BlueListItem
onPress={() => this.props.navigation.navigate('PlausibleDeniability')}
disabled={!this.state.storageIsEncrypted}
title={loc.settings.plausible_deniability}
chevron
testID="PlausibleDeniabilityButton"
Component={TouchableOpacity}
/>
)}
</ScrollView>
</SafeBlueArea>
);
}
}
EncryptStorage.propTypes = {
navigation: PropTypes.shape({
navigate: PropTypes.func,
popToTop: PropTypes.func,
goBack: PropTypes.func,
}),
<BlueCard>
<BlueTextHooks>
{biometrics.biometricsType} will be used to confirm your identity prior to making a transaction, unlocking, exporting or
deleting a wallet. {biometrics.biometricsType} will not be used to unlock an encrypted storage.
</BlueTextHooks>
</BlueCard>
<BlueSpacing20 />
</>
)}
<BlueHeaderDefaultSubHooks leftText="storage" rightComponent={null} />
<BlueListItemHooks
testID="EncyptedAndPasswordProtected"
hideChevron
title="Encrypted and Password protected"
Component={TouchableWithoutFeedback}
switch={{ onValueChange: onEncryptStorageSwitch, value: storageIsEncrypted }}
/>
{Platform.OS === 'ios' && (
<BlueListItemHooks
hideChevron
title="Delete if BlueWallet is uninstalled"
Component={TouchableWithoutFeedback}
switch={{
onValueChange: onDeleteWalletsAfterUninstallSwitch,
value: deleteWalletsAfterUninstall,
}}
/>
)}
{storageIsEncrypted && (
<BlueListItemHooks
onPress={navigateToPlausibleDeniability}
title={loc.settings.plausible_deniability}
chevron
testID="PlausibleDeniabilityButton"
Component={TouchableOpacity}
/>
)}
</ScrollView>
</SafeBlueArea>
);
};
export default EncryptStorage;
EncryptStorage.navigationOptions = () => ({
...BlueNavigationStyle(),
headerTitle: 'Security',
});

View file

@ -1,81 +1,59 @@
import React, { Component } from 'react';
import React, { useState, useEffect, useCallback } from 'react';
import { FlatList, StyleSheet } from 'react-native';
import { BlueLoading, BlueText, SafeBlueArea, BlueListItem, BlueCard, BlueNavigationStyle } from '../../BlueComponents';
import PropTypes from 'prop-types';
import { SafeBlueArea, BlueListItemHooks, BlueCard, BlueLoadingHook, BlueNavigationStyle, BlueTextHooks } from '../../BlueComponents';
import { Icon } from 'react-native-elements';
import { AvailableLanguages } from '../../loc/languages';
const loc = require('../../loc');
const styles = StyleSheet.create({
flex: {
flex: 1,
},
});
export default class Language extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(),
title: loc.settings.language,
const Language = () => {
const [isLoading, setIsLoading] = useState(true);
const [language, setLanguage] = useState(loc.getLanguage());
const styles = StyleSheet.create({
flex: {
flex: 1,
},
});
constructor(props) {
super(props);
this.state = {
isLoading: true,
language: loc.getLanguage(),
availableLanguages: AvailableLanguages,
};
}
useEffect(() => {
setIsLoading(false);
}, []);
async componentDidMount() {
this.setState({
isLoading: false,
});
}
renderItem = ({ item }) => {
return (
<BlueListItem
onPress={() => {
console.log('setLanguage', item.value);
loc.saveLanguage(item.value);
return this.setState({ language: item.value });
}}
title={item.label}
{...(this.state.language === item.value
? {
rightIcon: <Icon name="check" type="octaicon" color="#0070FF" />,
}
: { hideChevron: true })}
/>
);
};
render() {
if (this.state.isLoading) {
return <BlueLoading />;
}
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.flex}>
<FlatList
style={styles.flex}
keyExtractor={(_item, index) => `${index}`}
data={this.state.availableLanguages}
extraData={this.state.availableLanguages}
renderItem={this.renderItem}
const renderItem = useCallback(
({ item }) => {
return (
<BlueListItemHooks
onPress={() => {
console.log('setLanguage', item.value);
loc.saveLanguage(item.value);
setLanguage(item.value);
}}
title={item.label}
{...(language === item.value
? {
rightIcon: <Icon name="check" type="octaicon" color="#0070FF" />,
}
: { hideChevron: true })}
/>
<BlueCard>
<BlueText>When selecting a new language, restarting BlueWallet may be required for the change to take effect.</BlueText>
</BlueCard>
</SafeBlueArea>
);
}
}
);
},
[language],
);
Language.propTypes = {
navigation: PropTypes.shape({
navigate: PropTypes.func,
goBack: PropTypes.func,
}),
return isLoading ? (
<BlueLoadingHook />
) : (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.flex}>
<FlatList style={styles.flex} keyExtractor={(_item, index) => `${index}`} data={AvailableLanguages} renderItem={renderItem} />
<BlueCard>
<BlueTextHooks>When selecting a new language, restarting BlueWallet may be required for the change to take effect.</BlueTextHooks>
</BlueCard>
</SafeBlueArea>
);
};
Language.navigationOptions = () => ({
...BlueNavigationStyle(),
headerTitle: loc.settings.language,
});
export default Language;

View file

@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react';
import { ScrollView, StyleSheet } from 'react-native';
import { BlueLoading, SafeBlueArea, BlueCard, BlueText, BlueNavigationStyle, BlueSpacing20 } from '../../BlueComponents';
import { SafeBlueArea, BlueCard, BlueTextHooks, BlueNavigationStyle, BlueSpacing20, BlueLoadingHook } from '../../BlueComponents';
/** @type {AppStorage} */
const styles = StyleSheet.create({
@ -17,34 +17,34 @@ const Licensing = () => {
}, []);
return isLoading ? (
<BlueLoading />
<BlueLoadingHook />
) : (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<ScrollView>
<BlueCard>
<BlueText>MIT License</BlueText>
<BlueTextHooks>MIT License</BlueTextHooks>
<BlueSpacing20 />
<BlueText>Copyright (c) 2018-2020 BlueWallet Services</BlueText>
<BlueTextHooks>Copyright (c) 2018-2020 BlueWallet Services</BlueTextHooks>
<BlueSpacing20 />
<BlueText>
<BlueTextHooks>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
</BlueText>
</BlueTextHooks>
<BlueSpacing20 />
<BlueText>
<BlueTextHooks>
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
</BlueText>
</BlueTextHooks>
<BlueSpacing20 />
<BlueText>
<BlueTextHooks>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</BlueText>
</BlueTextHooks>
</BlueCard>
</ScrollView>
</SafeBlueArea>

View file

@ -1,14 +1,22 @@
/* global alert */
import React, { Component } from 'react';
import React, { useState, useEffect, useCallback } from 'react';
import { View, TextInput, Linking, StyleSheet } from 'react-native';
import { AppStorage } from '../../class';
import AsyncStorage from '@react-native-community/async-storage';
import { BlueLoading, BlueSpacing20, BlueButton, SafeBlueArea, BlueCard, BlueNavigationStyle, BlueText } from '../../BlueComponents';
import PropTypes from 'prop-types';
import {
BlueSpacing20,
BlueButton,
SafeBlueArea,
BlueCard,
BlueNavigationStyle,
BlueLoadingHook,
BlueTextHooks,
} from '../../BlueComponents';
import { Button } from 'react-native-elements';
import { LightningCustodianWallet } from '../../class/wallets/lightning-custodian-wallet';
/** @type {AppStorage} */
const BlueApp = require('../../BlueApp');
import { useTheme } from '@react-navigation/native';
import { BlueCurrentTheme } from '../../components/themes';
const loc = require('../../loc');
const styles = StyleSheet.create({
@ -17,11 +25,11 @@ const styles = StyleSheet.create({
},
uri: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderColor: BlueCurrentTheme.colors.formBorder,
borderBottomColor: BlueCurrentTheme.colors.formBorder,
borderWidth: 1,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
minHeight: 44,
height: 44,
alignItems: 'center',
@ -39,94 +47,80 @@ const styles = StyleSheet.create({
},
});
export default class LightningSettings extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(),
title: loc.settings.lightning_settings,
});
const LightningSettings = () => {
const [isLoading, setIsLoading] = useState(true);
const [URI, setURI] = useState();
const { colors } = useTheme();
constructor(props) {
super(props);
this.state = {
isLoading: true,
};
}
useEffect(() => {
AsyncStorage.getItem(AppStorage.LNDHUB)
.then(setURI)
.then(() => setIsLoading(false))
.catch(() => setIsLoading(false));
}, []);
async componentDidMount() {
const URI = await AsyncStorage.getItem(AppStorage.LNDHUB);
this.setState({
isLoading: false,
URI,
});
}
save = () => {
this.setState({ isLoading: true }, async () => {
this.state.URI = this.state.URI ? this.state.URI : '';
try {
if (this.state.URI) {
await LightningCustodianWallet.isValidNodeAddress(this.state.URI);
// validating only if its not empty. empty means use default
}
await AsyncStorage.setItem(AppStorage.LNDHUB, this.state.URI);
alert('Your changes have been saved successfully');
} catch (error) {
alert('Not a valid LndHub URI');
console.log(error);
const save = useCallback(async () => {
setIsLoading(true);
try {
if (URI) {
await LightningCustodianWallet.isValidNodeAddress(URI);
// validating only if its not empty. empty means use default
}
this.setState({ isLoading: false });
});
};
await AsyncStorage.setItem(AppStorage.LNDHUB, URI);
alert('Your changes have been saved successfully');
} catch (error) {
alert('Not a valid LndHub URI');
console.log(error);
}
setIsLoading(false);
}, [URI]);
render() {
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<BlueCard>
<BlueText>{loc.settings.lightning_settings_explain}</BlueText>
</BlueCard>
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<BlueCard>
<BlueTextHooks>{loc.settings.lightning_settings_explain}</BlueTextHooks>
</BlueCard>
<Button
icon={{
name: 'github',
type: 'font-awesome',
color: BlueApp.settings.buttonTextColor,
backgroundColor: '#FFFFFF',
}}
onPress={() => {
Linking.openURL('https://github.com/BlueWallet/LndHub');
}}
titleStyle={{ color: BlueApp.settings.buttonAlternativeTextColor }}
title="github.com/BlueWallet/LndHub"
color={BlueApp.settings.buttonTextColor}
buttonStyle={styles.buttonStyle}
/>
<Button
icon={{
name: 'github',
type: 'font-awesome',
color: colors.foregroundColor,
}}
onPress={() => {
Linking.openURL('https://github.com/BlueWallet/LndHub');
}}
titleStyle={{ color: colors.buttonAlternativeTextColor }}
title="github.com/BlueWallet/LndHub"
color={colors.buttonTextColor}
buttonStyle={styles.buttonStyle}
/>
<BlueCard>
<View style={styles.uri}>
<TextInput
placeholder={LightningCustodianWallet.defaultBaseUri}
value={this.state.URI}
onChangeText={text => this.setState({ URI: text })}
numberOfLines={1}
style={styles.uriText}
placeholderTextColor="#81868e"
editable={!this.state.isLoading}
underlineColorAndroid="transparent"
/>
</View>
<BlueCard>
<View style={styles.uri}>
<TextInput
placeholder={LightningCustodianWallet.defaultBaseUri}
value={URI}
onChangeText={setURI}
numberOfLines={1}
style={styles.uriText}
placeholderTextColor="#81868e"
editable={!isLoading}
textContentType="URL"
autoCapitalize="none"
underlineColorAndroid="transparent"
/>
</View>
<BlueSpacing20 />
{this.state.isLoading ? <BlueLoading /> : <BlueButton onPress={this.save} title={loc.settings.save} />}
</BlueCard>
</SafeBlueArea>
);
}
}
LightningSettings.propTypes = {
navigation: PropTypes.shape({
navigate: PropTypes.func,
goBack: PropTypes.func,
}),
<BlueSpacing20 />
{isLoading ? <BlueLoadingHook /> : <BlueButton onPress={save} title={loc.settings.save} />}
</BlueCard>
</SafeBlueArea>
);
};
LightningSettings.navigationOptions = () => ({
...BlueNavigationStyle(),
title: loc.settings.lightning_settings,
});
export default LightningSettings;

View file

@ -1,29 +1,31 @@
import React, { useState, useEffect } from 'react';
import { ScrollView, StyleSheet } from 'react-native';
import { BlueLoading, SafeBlueArea, BlueCard, BlueText, BlueNavigationStyle } from '../../BlueComponents';
import { SafeBlueArea, BlueCard, BlueNavigationStyle, BlueLoadingHook, BlueTextHooks } from '../../BlueComponents';
import { useTheme } from '@react-navigation/native';
/** @type {AppStorage} */
const styles = StyleSheet.create({
root: {
flex: 1,
},
});
const ReleaseNotes = () => {
const [isLoading, setIsLoading] = useState(true);
const notes = require('../../release-notes');
const { colors } = useTheme();
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: colors.background,
},
});
useEffect(() => {
setIsLoading(false);
}, []);
return isLoading ? (
<BlueLoading />
<BlueLoadingHook />
) : (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<ScrollView>
<BlueCard>
<BlueText>{notes}</BlueText>
<BlueTextHooks>{notes}</BlueTextHooks>
</BlueCard>
</ScrollView>
</SafeBlueArea>

View file

@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import { ScrollView, TouchableOpacity, StyleSheet } from 'react-native';
import { BlueNavigationStyle, BlueLoading, SafeBlueArea, BlueHeaderDefaultSub, BlueListItem } from '../../BlueComponents';
import { ScrollView, TouchableOpacity, StyleSheet, StatusBar } from 'react-native';
import { BlueLoading, BlueListItemHooks, BlueHeaderDefaultSubHooks } from '../../BlueComponents';
import { useNavigation } from '@react-navigation/native';
const loc = require('../../loc');
@ -21,32 +21,29 @@ const Settings = () => {
return isLoading ? (
<BlueLoading />
) : (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<ScrollView>
<BlueHeaderDefaultSub leftText={loc.settings.header} rightComponent={null} />
<BlueListItem title="General" component={TouchableOpacity} onPress={() => navigate('GeneralSettings')} chevron />
<BlueListItem title={loc.settings.currency} component={TouchableOpacity} onPress={() => navigate('Currency')} chevron />
<BlueListItem title={loc.settings.language} component={TouchableOpacity} onPress={() => navigate('Language')} chevron />
<BlueListItem
title="Security"
onPress={() => navigate('EncryptStorage')}
component={TouchableOpacity}
testID="SecurityButton"
chevron
/>
<BlueListItem title="Network" component={TouchableOpacity} onPress={() => navigate('NetworkSettings')} chevron />
<BlueListItem
title={loc.settings.about}
component={TouchableOpacity}
onPress={() => navigate('About')}
testID="AboutButton"
chevron
/>
</ScrollView>
</SafeBlueArea>
<ScrollView style={styles.root}>
<StatusBar barStyle="default" />
<BlueHeaderDefaultSubHooks leftText={loc.settings.header} rightComponent={null} />
<BlueListItemHooks title="General" component={TouchableOpacity} onPress={() => navigate('GeneralSettings')} chevron />
<BlueListItemHooks title={loc.settings.currency} component={TouchableOpacity} onPress={() => navigate('Currency')} chevron />
<BlueListItemHooks title={loc.settings.language} component={TouchableOpacity} onPress={() => navigate('Language')} chevron />
<BlueListItemHooks
title="Security"
onPress={() => navigate('EncryptStorage')}
component={TouchableOpacity}
testID="SecurityButton"
chevron
/>
<BlueListItemHooks title="Network" component={TouchableOpacity} onPress={() => navigate('NetworkSettings')} chevron />
<BlueListItemHooks
title={loc.settings.about}
component={TouchableOpacity}
onPress={() => navigate('About')}
testID="AboutButton"
chevron
/>
</ScrollView>
);
};
Settings.navigationOptions = {
...BlueNavigationStyle,
};
export default Settings;

View file

@ -79,11 +79,6 @@ const styles = StyleSheet.create({
});
export default class CPFP extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(null, false),
title: 'Bump fee (CPFP)',
});
constructor(props) {
super(props);
let txid;
@ -276,3 +271,7 @@ CPFP.propTypes = {
}),
}),
};
CPFP.navigationOptions = () => ({
...BlueNavigationStyle(null, false),
title: 'Bump fee (CPFP)',
});

View file

@ -16,11 +16,6 @@ const styles = StyleSheet.create({
});
export default class RBFBumpFee extends CPFP {
static navigationOptions = () => ({
...BlueNavigationStyle(null, false),
title: 'Bump fee (RBF)',
});
async componentDidMount() {
console.log('transactions/RBFBumpFee - componentDidMount');
this.setState({
@ -125,3 +120,8 @@ RBFBumpFee.propTypes = {
}),
}),
};
RBFBumpFee.navigationOptions = () => ({
...BlueNavigationStyle(null, false),
title: 'Bump fee (RBF)',
});

View file

@ -16,11 +16,6 @@ const styles = StyleSheet.create({
});
export default class RBFCancel extends CPFP {
static navigationOptions = () => ({
...BlueNavigationStyle(null, false),
title: 'Cancel this transaction (RBF)',
});
async componentDidMount() {
console.log('transactions/RBFCancel - componentDidMount');
this.setState({
@ -130,3 +125,8 @@ RBFCancel.propTypes = {
}),
}),
};
RBFCancel.navigationOptions = () => ({
...BlueNavigationStyle(null, false),
title: 'Cancel this transaction (RBF)',
});

View file

@ -5,7 +5,6 @@ import {
SafeBlueArea,
BlueCard,
BlueText,
BlueHeaderDefaultSub,
BlueLoading,
BlueSpacing20,
BlueCopyToClipboardButton,
@ -14,6 +13,7 @@ import {
import HandoffSettings from '../../class/handoff';
import Handoff from 'react-native-handoff';
import PropTypes from 'prop-types';
import { BlueCurrentTheme } from '../../components/themes';
/** @type {AppStorage} */
const BlueApp = require('../../BlueApp');
const loc = require('../../loc');
@ -36,6 +36,7 @@ const styles = StyleSheet.create({
fontSize: 16,
fontWeight: '500',
marginBottom: 4,
color: BlueCurrentTheme.colors.foregroundColor,
},
rowValue: {
marginBottom: 26,
@ -44,6 +45,7 @@ const styles = StyleSheet.create({
txId: {
fontSize: 16,
fontWeight: '500',
color: BlueCurrentTheme.colors.foregroundColor,
},
txHash: {
marginBottom: 8,
@ -51,16 +53,29 @@ const styles = StyleSheet.create({
},
txLink: {
marginBottom: 26,
color: '#2f5fb3',
color: BlueCurrentTheme.colors.alternativeTextColor2,
},
save: {
marginHorizontal: 16,
justifyContent: 'center',
alignItems: 'center',
},
saveText: {
color: BlueCurrentTheme.colors.alternativeTextColor2,
},
memoTextInput: {
fontSize: 24,
color: '#2f5fb3',
flexDirection: 'row',
borderColor: BlueCurrentTheme.colors.formBorder,
borderBottomColor: BlueCurrentTheme.colors.formBorder,
borderWidth: 1,
borderBottomWidth: 0.5,
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
minHeight: 44,
height: 44,
alignItems: 'center',
marginVertical: 8,
borderRadius: 4,
paddingHorizontal: 8,
},
});
@ -79,16 +94,6 @@ function arrDiff(a1, a2) {
}
export default class TransactionsDetails extends Component {
static navigationOptions = ({ navigation, route }) => ({
...BlueNavigationStyle(),
title: '',
headerRight: () => (
<TouchableOpacity disabled={route.params.isLoading === true} style={styles.save} onPress={route.params.handleOnSaveButtonTapped}>
<Text style={styles.saveText}>{loc.wallets.details.save}</Text>
</TouchableOpacity>
),
});
constructor(props) {
super(props);
const hash = props.route.params.hash;
@ -160,7 +165,6 @@ export default class TransactionsDetails extends Component {
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<StatusBar barStyle="dark-content" />
{this.state.isHandOffUseEnabled && (
<Handoff
title={`Bitcoin Transaction ${this.state.tx.hash}`}
@ -168,7 +172,7 @@ export default class TransactionsDetails extends Component {
url={`https://blockstream.info/tx/${this.state.tx.hash}`}
/>
)}
<BlueHeaderDefaultSub leftText={loc.transactions.details.title} rightComponent={null} />
<StatusBar barStyle="default" />
<ScrollView style={styles.scroll}>
<BlueCard>
<View>
@ -276,3 +280,17 @@ TransactionsDetails.propTypes = {
setParams: PropTypes.func,
}),
};
TransactionsDetails.navigationOptions = ({ navigation, route }) => ({
...BlueNavigationStyle(),
title: loc.transactions.details.title,
headerStyle: {
...BlueNavigationStyle().headerStyle,
backgroundColor: BlueCurrentTheme.colors.customHeader,
},
headerRight: () => (
<TouchableOpacity disabled={route.params.isLoading === true} style={styles.save} onPress={route.params.handleOnSaveButtonTapped}>
<Text style={styles.saveText}>{loc.wallets.details.save}</Text>
</TouchableOpacity>
),
});

View file

@ -18,6 +18,7 @@ import { BitcoinUnit } from '../../models/bitcoinUnits';
import { Icon } from 'react-native-elements';
import Handoff from 'react-native-handoff';
import HandoffSettings from '../../class/handoff';
import { BlueCurrentTheme } from '../../components/themes';
/** @type {AppStorage} */
const BlueApp = require('../../BlueApp');
const loc = require('../../loc');
@ -40,12 +41,12 @@ const styles = StyleSheet.create({
alignItems: 'center',
},
value: {
color: '#2f5fb3',
color: BlueCurrentTheme.colors.alternativeTextColor2,
fontSize: 36,
fontWeight: '600',
},
valueUnit: {
color: '#2f5fb3',
color: BlueCurrentTheme.colors.alternativeTextColor2,
fontSize: 16,
fontWeight: '600',
},
@ -58,7 +59,7 @@ const styles = StyleSheet.create({
fontSize: 14,
},
iconRoot: {
backgroundColor: '#ccddf9',
backgroundColor: BlueCurrentTheme.colors.success,
width: 120,
height: 120,
borderRadius: 60,
@ -94,7 +95,7 @@ const styles = StyleSheet.create({
},
confirmations: {
borderRadius: 11,
backgroundColor: '#eef0f4',
backgroundColor: BlueCurrentTheme.colors.lightButton,
width: 109,
height: 21,
alignSelf: 'center',
@ -132,11 +133,6 @@ const styles = StyleSheet.create({
});
export default class TransactionsStatus extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(),
title: '',
});
constructor(props) {
super(props);
const hash = props.route.params.hash;
@ -251,7 +247,6 @@ export default class TransactionsStatus extends Component {
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<StatusBar barStyle="dark-content" />
{this.state.isHandOffUseEnabled && (
<Handoff
title={`Bitcoin Transaction ${this.state.tx.hash}`}
@ -259,6 +254,7 @@ export default class TransactionsStatus extends Component {
url={`https://blockstream.info/tx/${this.state.tx.hash}`}
/>
)}
<StatusBar barStyle="default" />
<View style={styles.container}>
<BlueCard>
<View style={styles.center}>
@ -285,7 +281,7 @@ export default class TransactionsStatus extends Component {
<View style={styles.iconRoot}>
<View>
<Icon name="check" size={50} type="font-awesome" color="#0f5cc0" />
<Icon name="check" size={50} type="font-awesome" color={BlueCurrentTheme.colors.successCheck} />
</View>
<View style={[styles.iconWrap, styles.margin]}>
{(() => {
@ -436,3 +432,12 @@ TransactionsStatus.propTypes = {
params: PropTypes.object,
}),
};
TransactionsStatus.navigationOptions = () => ({
...BlueNavigationStyle(),
title: '',
headerStyle: {
...BlueNavigationStyle().headerStyle,
backgroundColor: BlueCurrentTheme.colors.customHeader,
},
});

View file

@ -22,14 +22,13 @@ import {
BitcoinButton,
BlueFormLabel,
BlueButton,
SafeBlueArea,
BlueNavigationStyle,
BlueButtonLink,
BlueSpacing20,
} from '../../BlueComponents';
import PropTypes from 'prop-types';
import { HDSegwitBech32Wallet, SegwitP2SHWallet, HDSegwitP2SHWallet, LightningCustodianWallet, AppStorage } from '../../class';
import { BlueCurrentTheme } from '../../components/themes';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { Icon } from 'react-native-elements';
const EV = require('../../blue_modules/events');
@ -41,14 +40,15 @@ const styles = StyleSheet.create({
loading: {
flex: 1,
paddingTop: 20,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
label: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderColor: BlueCurrentTheme.colors.formBorder,
borderBottomColor: BlueCurrentTheme.colors.formBorder,
borderWidth: 1,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
minHeight: 44,
height: 44,
marginHorizontal: 20,
@ -86,16 +86,16 @@ const styles = StyleSheet.create({
marginHorizontal: 20,
},
advancedText: {
color: '#0c2550',
color: BlueCurrentTheme.colors.feeText,
fontWeight: '500',
},
lndUri: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderColor: BlueCurrentTheme.colors.formBorder,
borderBottomColor: BlueCurrentTheme.colors.formBorder,
borderWidth: 1,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
minHeight: 44,
height: 44,
alignItems: 'center',
@ -113,6 +113,10 @@ const styles = StyleSheet.create({
},
noPadding: {
paddingHorizontal: 0,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
root: {
backgroundColor: BlueCurrentTheme.colors.elevated,
},
});
@ -181,251 +185,250 @@ export default class WalletsAdd extends Component {
}
return (
<SafeBlueArea>
<StatusBar barStyle="light-content" />
<ScrollView>
<KeyboardAvoidingView enabled behavior={Platform.OS === 'ios' ? 'padding' : null} keyboardVerticalOffset={62}>
<BlueFormLabel>{loc.wallets.add.wallet_name}</BlueFormLabel>
<View style={styles.label}>
<TextInput
testID="WalletNameInput"
value={this.state.label}
placeholderTextColor="#81868e"
placeholder="my first wallet"
onChangeText={text => {
this.setLabel(text);
}}
style={styles.textInputCommon}
editable={!this.state.isLoading}
underlineColorAndroid="transparent"
/>
</View>
<BlueFormLabel>{loc.wallets.add.wallet_type}</BlueFormLabel>
<ScrollView style={styles.root}>
<StatusBar barStyle="default" />
<BlueSpacing20 />
<KeyboardAvoidingView enabled behavior={Platform.OS === 'ios' ? 'padding' : null} keyboardVerticalOffset={62}>
<BlueFormLabel>{loc.wallets.add.wallet_name}</BlueFormLabel>
<View style={styles.label}>
<TextInput
testID="WalletNameInput"
value={this.state.label}
placeholderTextColor="#81868e"
placeholder="my first wallet"
onChangeText={text => {
this.setLabel(text);
}}
style={styles.textInputCommon}
editable={!this.state.isLoading}
underlineColorAndroid="transparent"
/>
</View>
<BlueFormLabel>{loc.wallets.add.wallet_type}</BlueFormLabel>
<View style={styles.buttons}>
<BitcoinButton
testID="ActivateBitcoinButton"
active={this.state.activeBitcoin}
onPress={() => {
Keyboard.dismiss();
this.setState({
activeBitcoin: true,
activeLightning: false,
});
}}
style={styles.button}
/>
<View style={styles.or}>
<BlueTextCentered style={styles.orCenter}>{loc.wallets.add.or}</BlueTextCentered>
</View>
<LightningButton
active={this.state.activeLightning}
onPress={() => {
Keyboard.dismiss();
this.setState({
activeBitcoin: false,
activeLightning: true,
});
}}
style={styles.button}
/>
<View style={styles.buttons}>
<BitcoinButton
testID="ActivateBitcoinButton"
active={this.state.activeBitcoin}
onPress={() => {
Keyboard.dismiss();
this.setState({
activeBitcoin: true,
activeLightning: false,
});
}}
style={styles.button}
/>
<View style={styles.or}>
<BlueTextCentered style={styles.orCenter}>{loc.wallets.add.or}</BlueTextCentered>
</View>
<LightningButton
active={this.state.activeLightning}
onPress={() => {
Keyboard.dismiss();
this.setState({
activeBitcoin: false,
activeLightning: true,
});
}}
style={styles.button}
/>
</View>
<View style={styles.advanced}>
{(() => {
if (this.state.activeBitcoin && this.state.isAdvancedOptionsEnabled) {
return (
<View>
<BlueSpacing20 />
<Text style={styles.advancedText}>{loc.settings.advanced_options}</Text>
<BlueListItem
containerStyle={styles.noPadding}
bottomDivider={false}
onPress={() => {
this.onSelect(0, HDSegwitBech32Wallet.type);
<View style={styles.advanced}>
{(() => {
if (this.state.activeBitcoin && this.state.isAdvancedOptionsEnabled) {
return (
<View>
<BlueSpacing20 />
<Text style={styles.advancedText}>{loc.settings.advanced_options}</Text>
<BlueListItem
containerStyle={styles.noPadding}
bottomDivider={false}
onPress={() => {
this.onSelect(0, HDSegwitBech32Wallet.type);
}}
title={HDSegwitBech32Wallet.typeReadable}
{...(this.state.selectedIndex === 0
? {
rightIcon: <Icon name="check" type="octaicon" color="#0070FF" />,
}
: { hideChevron: true })}
/>
<BlueListItem
containerStyle={styles.noPadding}
bottomDivider={false}
onPress={() => {
this.onSelect(1, SegwitP2SHWallet.type);
}}
title={SegwitP2SHWallet.typeReadable}
{...(this.state.selectedIndex === 1
? {
rightIcon: <Icon name="check" type="octaicon" color="#0070FF" />,
}
: { hideChevron: true })}
/>
<BlueListItem
containerStyle={styles.noPadding}
bottomDivider={false}
onPress={() => {
this.onSelect(2, HDSegwitP2SHWallet.typeReadable.type);
}}
title={HDSegwitP2SHWallet.typeReadable}
{...(this.state.selectedIndex === 2
? {
rightIcon: <Icon name="check" type="octaicon" color="#0070FF" />,
}
: { hideChevron: true })}
/>
</View>
);
} else if (this.state.activeLightning && this.state.isAdvancedOptionsEnabled) {
return (
<>
<BlueSpacing20 />
<Text style={styles.advancedText}>{loc.settings.advanced_options}</Text>
<BlueSpacing20 />
<BlueText>Connect to your LNDHub</BlueText>
<View style={styles.lndUri}>
<TextInput
value={this.state.walletBaseURI}
onChangeText={text => {
this.setState({ walletBaseURI: text });
}}
title={HDSegwitBech32Wallet.typeReadable}
{...(this.state.selectedIndex === 0
? {
rightIcon: <Icon name="check" type="octaicon" color="#0070FF" />,
}
: { hideChevron: true })}
/>
<BlueListItem
containerStyle={styles.noPadding}
bottomDivider={false}
onPress={() => {
this.onSelect(1, SegwitP2SHWallet.type);
}}
title={SegwitP2SHWallet.typeReadable}
{...(this.state.selectedIndex === 1
? {
rightIcon: <Icon name="check" type="octaicon" color="#0070FF" />,
}
: { hideChevron: true })}
/>
<BlueListItem
containerStyle={styles.noPadding}
bottomDivider={false}
onPress={() => {
this.onSelect(2, HDSegwitP2SHWallet.typeReadable.type);
}}
title={HDSegwitP2SHWallet.typeReadable}
{...(this.state.selectedIndex === 2
? {
rightIcon: <Icon name="check" type="octaicon" color="#0070FF" />,
}
: { hideChevron: true })}
onSubmitEditing={Keyboard.dismiss}
placeholder="your node address"
clearButtonMode="while-editing"
autoCapitalize="none"
placeholderTextColor="#81868e"
style={styles.textInputCommon}
editable={!this.state.isLoading}
underlineColorAndroid="transparent"
/>
</View>
);
} else if (this.state.activeLightning && this.state.isAdvancedOptionsEnabled) {
return (
<>
<BlueSpacing20 />
<Text style={styles.advancedText}>{loc.settings.advanced_options}</Text>
<BlueSpacing20 />
<BlueText>Connect to your LNDHub</BlueText>
<View style={styles.lndUri}>
<TextInput
value={this.state.walletBaseURI}
onChangeText={text => {
this.setState({ walletBaseURI: text });
}}
onSubmitEditing={Keyboard.dismiss}
placeholder="your node address"
clearButtonMode="while-editing"
autoCapitalize="none"
placeholderTextColor="#81868e"
style={styles.textInputCommon}
editable={!this.state.isLoading}
underlineColorAndroid="transparent"
/>
</View>
</>
);
} else if (this.state.activeBitcoin === undefined && this.state.isAdvancedOptionsEnabled) {
return <View />;
}
})()}
<View style={styles.createButton}>
{!this.state.isLoading ? (
<BlueButton
testID="Create"
title={loc.wallets.add.create}
disabled={this.state.activeBitcoin === undefined}
onPress={() => {
this.setState({ isLoading: true }, async () => {
let w;
</>
);
} else if (this.state.activeBitcoin === undefined && this.state.isAdvancedOptionsEnabled) {
return <View />;
}
})()}
<View style={styles.createButton}>
{!this.state.isLoading ? (
<BlueButton
testID="Create"
title={loc.wallets.add.create}
disabled={this.state.activeBitcoin === undefined}
onPress={() => {
this.setState({ isLoading: true }, async () => {
let w;
if (this.state.activeLightning) {
this.createLightningWallet = async () => {
w = new LightningCustodianWallet();
w.setLabel(this.state.label || loc.wallets.details.title);
if (this.state.activeLightning) {
this.createLightningWallet = async () => {
w = new LightningCustodianWallet();
w.setLabel(this.state.label || loc.wallets.details.title);
try {
const lndhub =
this.state.walletBaseURI.trim().length > 0
? this.state.walletBaseURI
: LightningCustodianWallet.defaultBaseUri;
if (lndhub) {
const isValidNodeAddress = await LightningCustodianWallet.isValidNodeAddress(lndhub);
if (isValidNodeAddress) {
w.setBaseURI(lndhub);
w.init();
} else {
throw new Error('The provided node address is not valid LNDHub node.');
}
try {
const lndhub =
this.state.walletBaseURI.trim().length > 0
? this.state.walletBaseURI
: LightningCustodianWallet.defaultBaseUri;
if (lndhub) {
const isValidNodeAddress = await LightningCustodianWallet.isValidNodeAddress(lndhub);
if (isValidNodeAddress) {
w.setBaseURI(lndhub);
w.init();
} else {
throw new Error('The provided node address is not valid LNDHub node.');
}
await w.createAccount();
await w.authorize();
} catch (Err) {
this.setState({ isLoading: false });
console.warn('lnd create failure', Err);
return alert(Err);
// giving app, not adding anything
}
A(A.ENUM.CREATED_LIGHTNING_WALLET);
await w.generate();
BlueApp.wallets.push(w);
await BlueApp.saveToDisk();
EV(EV.enum.WALLETS_COUNT_CHANGED);
A(A.ENUM.CREATED_WALLET);
ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
this.props.navigation.navigate('PleaseBackupLNDHub', {
wallet: w,
});
};
this.createLightningWallet();
} else if (this.state.selectedIndex === 2) {
// zero index radio - HD segwit
w = new HDSegwitP2SHWallet();
w.setLabel(this.state.label || loc.wallets.details.title);
} else if (this.state.selectedIndex === 1) {
// btc was selected
// index 1 radio - segwit single address
w = new SegwitP2SHWallet();
w.setLabel(this.state.label || loc.wallets.details.title);
} else {
// btc was selected
// index 2 radio - hd bip84
w = new HDSegwitBech32Wallet();
w.setLabel(this.state.label || loc.wallets.details.title);
}
if (this.state.activeBitcoin) {
if (this.state.entropy) {
try {
await w.generateFromEntropy(this.state.entropy);
} catch (e) {
console.log(e.toString());
alert(e.toString());
this.props.navigation.goBack();
return;
}
} else {
await w.generate();
await w.createAccount();
await w.authorize();
} catch (Err) {
this.setState({ isLoading: false });
console.warn('lnd create failure', Err);
return alert(Err);
// giving app, not adding anything
}
A(A.ENUM.CREATED_LIGHTNING_WALLET);
await w.generate();
BlueApp.wallets.push(w);
await BlueApp.saveToDisk();
EV(EV.enum.WALLETS_COUNT_CHANGED);
A(A.ENUM.CREATED_WALLET);
ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
if (w.type === HDSegwitP2SHWallet.type || w.type === HDSegwitBech32Wallet.type) {
this.props.navigation.navigate('PleaseBackup', {
secret: w.getSecret(),
});
} else {
this.props.navigation.navigate('PleaseBackupLNDHub', {
wallet: w,
});
};
this.createLightningWallet();
} else if (this.state.selectedIndex === 2) {
// zero index radio - HD segwit
w = new HDSegwitP2SHWallet();
w.setLabel(this.state.label || loc.wallets.details.title);
} else if (this.state.selectedIndex === 1) {
// btc was selected
// index 1 radio - segwit single address
w = new SegwitP2SHWallet();
w.setLabel(this.state.label || loc.wallets.details.title);
} else {
// btc was selected
// index 2 radio - hd bip84
w = new HDSegwitBech32Wallet();
w.setLabel(this.state.label || loc.wallets.details.title);
}
if (this.state.activeBitcoin) {
if (this.state.entropy) {
try {
await w.generateFromEntropy(this.state.entropy);
} catch (e) {
console.log(e.toString());
alert(e.toString());
this.props.navigation.goBack();
return;
}
} else {
await w.generate();
}
});
}}
/>
) : (
<ActivityIndicator />
)}
</View>
<BlueButtonLink
testID="ImportWallet"
style={styles.import}
title={loc.wallets.add.import_wallet}
onPress={() => {
this.props.navigation.navigate('ImportWallet');
}}
/>
{this.state.isAdvancedOptionsEnabled && (
<BlueButtonLink
style={styles.import}
title={entropyTitle}
onPress={() => {
this.props.navigation.navigate('ProvideEntropy', { onGenerated: entropy => this.setState({ entropy }) });
BlueApp.wallets.push(w);
await BlueApp.saveToDisk();
EV(EV.enum.WALLETS_COUNT_CHANGED);
A(A.ENUM.CREATED_WALLET);
ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
if (w.type === HDSegwitP2SHWallet.type || w.type === HDSegwitBech32Wallet.type) {
this.props.navigation.navigate('PleaseBackup', {
secret: w.getSecret(),
});
} else {
this.props.navigation.goBack();
}
}
});
}}
/>
) : (
<ActivityIndicator />
)}
</View>
</KeyboardAvoidingView>
</ScrollView>
</SafeBlueArea>
<BlueButtonLink
testID="ImportWallet"
style={styles.import}
title={loc.wallets.add.import_wallet}
onPress={() => {
this.props.navigation.navigate('ImportWallet');
}}
/>
{this.state.isAdvancedOptionsEnabled && (
<BlueButtonLink
style={styles.import}
title={entropyTitle}
onPress={() => {
this.props.navigation.navigate('ProvideEntropy', { onGenerated: entropy => this.setState({ entropy }) });
}}
/>
)}
</View>
</KeyboardAvoidingView>
</ScrollView>
);
}
}

View file

@ -14,12 +14,6 @@ const styles = StyleSheet.create({
});
export default class BuyBitcoin extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: '',
headerLeft: null,
});
constructor(props) {
super(props);
const wallet = props.route.params.wallet;
@ -97,7 +91,7 @@ export default class BuyBitcoin extends Component {
return (
<SafeBlueArea style={styles.root}>
<StatusBar barStyle="light-content" />
<StatusBar barStyle="default" />
<WebView
source={{
uri,
@ -117,3 +111,9 @@ BuyBitcoin.propTypes = {
}),
}),
};
BuyBitcoin.navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: '',
headerLeft: null,
});

View file

@ -16,7 +16,7 @@ import {
StyleSheet,
StatusBar,
} from 'react-native';
import { BlueButton, SafeBlueArea, BlueCard, BlueSpacing20, BlueNavigationStyle, BlueText } from '../../BlueComponents';
import { SecondButton, SafeBlueArea, BlueCard, BlueSpacing20, BlueNavigationStyle, BlueText } from '../../BlueComponents';
import PropTypes from 'prop-types';
import { LightningCustodianWallet } from '../../class/wallets/lightning-custodian-wallet';
import { HDLegacyBreadwalletWallet } from '../../class/wallets/hd-legacy-breadwallet-wallet';
@ -26,6 +26,7 @@ import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import Biometric from '../../class/biometrics';
import { HDSegwitBech32Wallet, SegwitP2SHWallet, LegacyWallet, SegwitBech32Wallet, WatchOnlyWallet } from '../../class';
import { ScrollView } from 'react-native-gesture-handler';
import { BlueCurrentTheme } from '../../components/themes';
const EV = require('../../blue_modules/events');
const prompt = require('../../blue_modules/prompt');
/** @type {AppStorage} */
@ -45,36 +46,36 @@ const styles = StyleSheet.create({
alignItems: 'center',
},
saveText: {
color: '#0c2550',
color: BlueCurrentTheme.colors.outputValue,
},
address: {
alignItems: 'center',
flex: 1,
},
textLabel1: {
color: '#0c2550',
color: BlueCurrentTheme.colors.feeText,
fontWeight: '500',
fontSize: 14,
marginVertical: 12,
},
textLabel2: {
color: '#0c2550',
color: BlueCurrentTheme.colors.feeText,
fontWeight: '500',
fontSize: 14,
marginVertical: 16,
},
textValue: {
color: '#81868e',
color: BlueCurrentTheme.colors.outputValue,
fontWeight: '500',
fontSize: 14,
},
input: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderColor: BlueCurrentTheme.colors.formBorder,
borderBottomColor: BlueCurrentTheme.colors.formBorder,
borderWidth: 1,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
minHeight: 44,
height: 44,
alignItems: 'center',
@ -102,24 +103,6 @@ const styles = StyleSheet.create({
});
export default class WalletDetails extends Component {
static navigationOptions = ({ navigation, route }) => ({
...BlueNavigationStyle(),
title: loc.wallets.details.title,
headerRight: () => (
<TouchableOpacity
disabled={route.params.isLoading === true}
style={styles.save}
onPress={() => {
if (route.params.saveAction) {
route.params.saveAction();
}
}}
>
<Text style={styles.saveText}>{loc.wallets.details.save}</Text>
</TouchableOpacity>
),
});
constructor(props) {
super(props);
@ -200,7 +183,7 @@ export default class WalletDetails extends Component {
renderMarketplaceButton = () => {
return Platform.select({
android: (
<BlueButton
<SecondButton
onPress={() =>
this.props.navigation.navigate('Marketplace', {
fromWallet: this.state.wallet,
@ -210,7 +193,7 @@ export default class WalletDetails extends Component {
/>
),
ios: (
<BlueButton
<SecondButton
onPress={async () => {
Linking.openURL('https://bluewallet.io/marketplace-btc/');
}}
@ -230,7 +213,7 @@ export default class WalletDetails extends Component {
}
return (
<SafeBlueArea style={styles.root}>
<StatusBar barStyle="dark-content" />
<StatusBar barStyle="default" />
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<KeyboardAvoidingView behavior="position">
<ScrollView contentContainerStyle={styles.scrollViewContent}>
@ -309,7 +292,7 @@ export default class WalletDetails extends Component {
</>
)}
<BlueButton
<SecondButton
onPress={() =>
this.props.navigation.navigate('WalletExport', {
wallet: this.state.wallet,
@ -325,7 +308,7 @@ export default class WalletDetails extends Component {
this.state.wallet.type === HDSegwitBech32Wallet.type ||
this.state.wallet.type === HDSegwitP2SHWallet.type) && (
<>
<BlueButton
<SecondButton
onPress={() =>
this.props.navigation.navigate('WalletXpub', {
secret: this.state.wallet.getSecret(),
@ -341,7 +324,7 @@ export default class WalletDetails extends Component {
{this.state.wallet.type !== LightningCustodianWallet.type && (
<>
<BlueSpacing20 />
<BlueButton onPress={() => this.props.navigation.navigate('Broadcast')} title="Broadcast transaction" />
<SecondButton onPress={() => this.props.navigation.navigate('Broadcast')} title="Broadcast transaction" />
</>
)}
<BlueSpacing20 />
@ -397,6 +380,24 @@ export default class WalletDetails extends Component {
}
}
WalletDetails.navigationOptions = ({ navigation, route }) => ({
...BlueNavigationStyle(),
title: loc.wallets.details.title,
headerRight: () => (
<TouchableOpacity
disabled={route.params.isLoading === true}
style={styles.save}
onPress={() => {
if (route.params.saveAction) {
route.params.saveAction();
}
}}
>
<Text style={styles.saveText}>{loc.wallets.details.save}</Text>
</TouchableOpacity>
),
});
WalletDetails.propTypes = {
navigation: PropTypes.shape({
state: PropTypes.shape({

View file

@ -6,6 +6,7 @@ import PropTypes from 'prop-types';
import Privacy from '../../Privacy';
import Biometric from '../../class/biometrics';
import { LegacyWallet, LightningCustodianWallet, SegwitBech32Wallet, SegwitP2SHWallet, WatchOnlyWallet } from '../../class';
import { BlueCurrentTheme } from '../../components/themes';
/** @type {AppStorage} */
const BlueApp = require('../../BlueApp');
const loc = require('../../loc');
@ -18,6 +19,7 @@ const styles = StyleSheet.create({
},
root: {
flex: 1,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
scrollViewContent: {
alignItems: 'center',
@ -27,24 +29,18 @@ const styles = StyleSheet.create({
type: {
fontSize: 17,
fontWeight: '700',
color: '#0c2550',
color: BlueCurrentTheme.colors.foregroundColor,
},
secret: {
alignItems: 'center',
paddingHorizontal: 16,
fontSize: 16,
color: '#0C2550',
color: BlueCurrentTheme.colors.foregroundColor,
lineHeight: 24,
},
});
export default class WalletExport extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: loc.wallets.export.title,
headerLeft: null,
});
constructor(props) {
super(props);
const wallet = props.route.params.wallet;
@ -118,8 +114,9 @@ export default class WalletExport extends Component {
logo={require('../../img/qr-code.png')}
size={this.state.qrCodeHeight}
logoSize={70}
color={BlueApp.settings.foregroundColor}
logoBackgroundColor={BlueApp.settings.brandingColor}
color={BlueCurrentTheme.colors.foregroundColor}
logoBackgroundColor={BlueCurrentTheme.colors.brandingColor}
backgroundColor={BlueCurrentTheme.colors.background}
ecl="H"
/>
@ -147,3 +144,8 @@ WalletExport.propTypes = {
}),
}),
};
WalletExport.navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: loc.wallets.export.title,
headerLeft: null,
});

View file

@ -25,6 +25,7 @@ import Modal from 'react-native-modal';
import { Icon } from 'react-native-elements';
import { AppStorage } from '../../class';
import * as NavigationService from '../../NavigationService';
import { BlueCurrentTheme } from '../../components/themes';
const BlueApp: AppStorage = require('../../BlueApp');
const A = require('../../blue_modules/analytics');
@ -38,11 +39,6 @@ export default class HodlHodl extends Component {
constructor(props) {
super(props);
props.navigation.setParams({
handleLoginPress: this.handleLoginPress,
displayLoginButton: true,
handleMyContractsPress: this.handleMyContractsPress,
});
this.state = {
HodlApi: false,
isLoading: true,
@ -72,7 +68,7 @@ export default class HodlHodl extends Component {
this.setState({ HodlApi, hodlApiKey });
this.props.navigation.setParams({ displayLoginButton });
};
NavigationService.navigate('HodlHodlRoot', { params: { cb: handleLoginCallback }, screen: 'HodlHodlLogin' });
NavigationService.navigate('HodlHodlLoginRoot', { params: { cb: handleLoginCallback }, screen: 'HodlHodlLogin' });
};
handleMyContractsPress = () => {
@ -185,7 +181,11 @@ export default class HodlHodl extends Component {
const HodlApi = new HodlHodlApi(hodlApiKey);
this.setState({ HodlApi, hodlApiKey });
this.props.navigation.setParams({ displayLoginButton });
this.props.navigation.setParams({
handleLoginPress: this.handleLoginPress,
displayLoginButton: displayLoginButton,
handleMyContractsPress: this.handleMyContractsPress,
});
try {
await this.fetchMyCountry();
@ -204,16 +204,14 @@ export default class HodlHodl extends Component {
this.fetchListOfMethods();
}
_onPress(item) {
_onPress = item => {
const offers = this.state.offers.filter(value => value.id === item.id);
if (offers && offers[0]) {
NavigationService.navigate('HodlHodlViewOffer', {
offerToDisplay: offers[0],
});
this.props.navigation.navigate('HodlHodlViewOffer', { offerToDisplay: offers[0] });
} else {
Linking.openURL('https://hodlhodl.com/offers/' + item.id);
}
}
};
_onCountryPress(item) {
this.setState(
@ -716,7 +714,13 @@ export default class HodlHodl extends Component {
<View style={styles.grayTextContainerContainer}>
<View style={styles.grayTextContainer}>
<Icon name="place" type="material" size={20} color="#0c2550" containerStyle={styles.paddingLeft10} />
<Icon
name="place"
type="material"
size={20}
color={BlueCurrentTheme.colors.foregroundColor}
containerStyle={styles.paddingLeft10}
/>
{this.state.isLoading ? (
<ActivityIndicator />
) : (
@ -732,7 +736,13 @@ export default class HodlHodl extends Component {
>
<Text style={styles.blueText}>Filters</Text>
<Icon name="filter-list" type="material" size={24} color="#2f5fb3" containerStyle={styles.paddingLeft10} />
<Icon
name="filter-list"
type="material"
size={24}
color={BlueCurrentTheme.colors.foregroundColor}
containerStyle={styles.paddingLeft10}
/>
</TouchableOpacity>
</View>
</View>
@ -815,7 +825,7 @@ export default class HodlHodl extends Component {
render() {
return (
<SafeBlueArea>
<StatusBar barStyle="light-content" />
<StatusBar barStyle="default" />
<SectionList
refreshControl={<RefreshControl onRefresh={this._onRefreshOffers} refreshing={this.state.showShowFlatListRefreshControl} />}
renderItem={this.renderItem}
@ -848,7 +858,11 @@ HodlHodl.propTypes = {
HodlHodl.navigationOptions = ({ navigation, route }) => ({
...BlueNavigationStyle(navigation, true),
title: '',
headerLeft: () => {
headerStyle: {
...BlueNavigationStyle(navigation, true).headerStyle,
backgroundColor: BlueCurrentTheme.colors.customHeader,
},
headerRight: () => {
return route.params.displayLoginButton ? (
<BlueButtonLink title="Login" onPress={route.params.handleLoginPress} style={styles.marginHorizontal20} />
) : (
@ -864,7 +878,7 @@ const styles = StyleSheet.create({
color: '#9AA0AA',
},
modalContent: {
backgroundColor: '#FFFFFF',
backgroundColor: BlueCurrentTheme.colors.elevated,
padding: 22,
justifyContent: 'center',
alignItems: 'center',
@ -875,7 +889,7 @@ const styles = StyleSheet.create({
height: 400,
},
modalContentShort: {
backgroundColor: '#FFFFFF',
backgroundColor: BlueCurrentTheme.colors.elevated,
padding: 22,
justifyContent: 'center',
alignItems: 'center',
@ -892,14 +906,14 @@ const styles = StyleSheet.create({
Title: {
fontWeight: 'bold',
fontSize: 30,
color: '#0c2550',
color: BlueCurrentTheme.colors.foregroundColor,
},
BottomLine: {
fontSize: 10,
color: '#0c2550',
color: BlueCurrentTheme.colors.foregroundColor,
},
grayDropdownTextContainer: {
backgroundColor: '#EEF0F4',
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
borderRadius: 20,
height: 35,
top: 3,
@ -911,7 +925,7 @@ const styles = StyleSheet.create({
flexDirection: 'row',
},
grayTextContainerContainer: {
backgroundColor: '#EEF0F4',
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
borderRadius: 20,
height: 44,
justifyContent: 'center',
@ -925,7 +939,7 @@ const styles = StyleSheet.create({
flexDirection: 'row',
},
blueText: {
color: '#2f5fb3',
color: BlueCurrentTheme.colors.foregroundColor,
fontSize: 15,
fontWeight: '600',
},
@ -939,17 +953,17 @@ const styles = StyleSheet.create({
locationText: {
top: 0,
left: 5,
color: '#0c2550',
color: BlueCurrentTheme.colors.foregroundColor,
fontSize: 20,
fontWeight: '500',
},
nicknameText: {
color: '#0c2550',
color: BlueCurrentTheme.colors.foregroundColor,
fontSize: 18,
fontWeight: '600',
},
blueTextContainer: {
backgroundColor: '#CCDDF9',
backgroundColor: BlueCurrentTheme.colors.mainColor,
borderRadius: 20,
width: 110,
flex: 1,
@ -963,11 +977,11 @@ const styles = StyleSheet.create({
},
searchInputContainer: {
flexDirection: 'row',
borderColor: '#EEF0F4',
borderBottomColor: '#EEF0F4',
borderColor: BlueCurrentTheme.colors.inputBackgroundColor,
borderBottomColor: BlueCurrentTheme.colors.inputBackgroundColor,
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#EEF0F4',
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
minHeight: 48,
height: 48,
marginHorizontal: 20,
@ -997,40 +1011,44 @@ const styles = StyleSheet.create({
itemPrice: { fontWeight: '600', fontSize: 14, color: '#9AA0AA' },
minmax: { color: '#9AA0AA', fontSize: 12, paddingLeft: 10 },
noOffersWrapper: { height: '100%', justifyContent: 'center' },
noOffersText: { textAlign: 'center', color: '#9AA0AA', paddingHorizontal: 16 },
noOffersText: { textAlign: 'center', color: BlueCurrentTheme.colors.feeText, paddingHorizontal: 16 },
modalFlatList: { width: '100%' },
itemSeparator: { height: 0.5, width: '100%', backgroundColor: '#C8C8C8' },
itemNameWrapper: { backgroundColor: 'white', flex: 1, flexDirection: 'row', paddingTop: 20, paddingBottom: 20 },
itemNameBold: { fontSize: 20, color: '#0c2550', fontWeight: 'bold' },
itemNameNormal: { fontSize: 20, color: '#0c2550', fontWeight: 'normal' },
whiteBackground: { backgroundColor: 'white' },
filterCurrencyText: { fontSize: 16, color: '#9AA0AA' },
filteCurrencyTextWrapper: { color: '#9AA0AA', right: 0, position: 'absolute' },
currencyNativeName: { fontSize: 20, color: '#0c2550' },
itemSeparator: { height: 0.5, width: '100%', backgroundColor: BlueCurrentTheme.colors.lightBorder },
itemNameWrapper: { backgroundColor: BlueCurrentTheme.colors.elevated, flex: 1, flexDirection: 'row', paddingTop: 20, paddingBottom: 20 },
itemNameBold: { fontSize: 20, color: BlueCurrentTheme.colors.foregroundColor, fontWeight: 'bold' },
itemNameNormal: { fontSize: 20, color: BlueCurrentTheme.colors.foregroundColor, fontWeight: 'normal' },
whiteBackground: { backgroundColor: BlueCurrentTheme.colors.background },
filterCurrencyText: { fontSize: 16, color: BlueCurrentTheme.colors.foregroundColor },
filteCurrencyTextWrapper: { color: BlueCurrentTheme.colors.foregroundColor, right: 0, position: 'absolute' },
currencyNativeName: { fontSize: 20, color: BlueCurrentTheme.colors.foregroundColor },
currencyWrapper: { paddingLeft: 10, flex: 1, flexDirection: 'row' },
methodNameText: { fontSize: 16, color: '#9AA0AA' },
methodNameText: { fontSize: 16, color: BlueCurrentTheme.colors.foregroundColor },
searchTextInput: { fontSize: 17, flex: 1, marginHorizontal: 8, minHeight: 33, paddingLeft: 6, paddingRight: 6, color: '#81868e' },
iconWithOffset: { left: -10 },
paddingLeft10: { paddingLeft: 10 },
countryNativeNameBold: { fontSize: 20, color: '#0c2550', fontWeight: 'bold' },
countryNativeNameNormal: { fontSize: 20, color: '#0c2550', fontWeight: 'normal' },
countryNativeNameBold: { fontSize: 20, color: BlueCurrentTheme.colors.foregroundColor, fontWeight: 'bold' },
countryNativeNameNormal: { fontSize: 20, color: BlueCurrentTheme.colors.foregroundColor, fontWeight: 'normal' },
curSearchInput: { flex: 1, marginHorizontal: 8, minHeight: 33, paddingLeft: 6, paddingRight: 6, color: '#81868e' },
mthdSearchInput: { flex: 1, marginHorizontal: 8, minHeight: 33, paddingLeft: 6, paddingRight: 6, color: '#81868e' },
currencyTextBold: {
fontSize: 20,
color: '#0c2550',
color: BlueCurrentTheme.colors.foregroundColor,
fontWeight: 'bold',
},
currencyTextNormal: {
fontSize: 20,
color: '#0c2550',
color: BlueCurrentTheme.colors.foregroundColor,
fontWeight: 'normal',
},
currencyText: {
fontSize: 20,
color: BlueCurrentTheme.colors.foregroundColor,
},
noPaddingLeftOrRight: { paddingLeft: 0, paddingRight: 0 },
flexRow: { flexDirection: 'row' },
traderRatingText2: { color: '#9AA0AA' },
itemPriceWrapper: {
backgroundColor: '#EEF0F4',
backgroundColor: BlueCurrentTheme.colors.lightButton,
borderRadius: 20,
paddingLeft: 8,
paddingRight: 8,
@ -1043,8 +1061,8 @@ const styles = StyleSheet.create({
offersSectionList: { marginTop: 24, flex: 1 },
marginHorizontal20: { marginHorizontal: 20 },
avatarImage: { width: 40, height: 40, borderRadius: 40 },
avatarWrapper: { backgroundColor: 'white', flex: 1, flexDirection: 'row' },
avatarWrapperWrapper: { backgroundColor: 'white', paddingTop: 16, paddingBottom: 16 },
headerWrapper: { marginHorizontal: 20, marginBottom: 8 },
avatarWrapper: { backgroundColor: BlueCurrentTheme.colors.background, flex: 1, flexDirection: 'row' },
avatarWrapperWrapper: { backgroundColor: BlueCurrentTheme.colors.background, paddingTop: 16, paddingBottom: 16 },
headerWrapper: { backgroundColor: BlueCurrentTheme.colors.background, marginHorizontal: 20, marginBottom: 8 },
verifiedIcon: { marginTop: 5, marginRight: 5 },
});

View file

@ -1,7 +1,7 @@
import React, { Component } from 'react';
import React, { useRef } from 'react';
import { WebView } from 'react-native-webview';
import { BlueNavigationStyle, SafeBlueArea } from '../../BlueComponents';
import PropTypes from 'prop-types';
import { useRoute, useNavigation } from '@react-navigation/native';
const url = 'https://accounts.hodlhodl.com/accounts/request_access?attributes=api_key,api_signature_key';
@ -15,61 +15,44 @@ const INJECTED_JAVASCRIPT = `(function() {
})();`;
export default class HodlHodlLogin extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: 'Login',
headerLeft: null,
});
const HodlHodlLogin = () => {
const webView = useRef();
const { cb } = useRoute().params;
const navigation = useNavigation();
constructor(props) {
super(props);
return (
<SafeBlueArea>
<WebView
injectedJavaScript={INJECTED_JAVASCRIPT}
ref={webView}
source={{ uri: url }}
onMessage={e => {
// this is a handler which receives messages sent from within the browser
this.state = {
url: url,
};
}
if (lastTimeIvebeenHere && +new Date() - lastTimeIvebeenHere < 5000) return;
lastTimeIvebeenHere = +new Date();
// page can post messages several times, and that can confuse our react navigation, so we have protection
// against that
render() {
return (
<SafeBlueArea>
<WebView
injectedJavaScript={INJECTED_JAVASCRIPT}
ref={ref => (this.webview = ref)}
source={{ uri: this.state.url }}
onMessage={e => {
// this is a handler which receives messages sent from within the browser
let json = false;
try {
json = JSON.parse(e.nativeEvent.data);
} catch (_) {}
if (lastTimeIvebeenHere && +new Date() - lastTimeIvebeenHere < 5000) return;
lastTimeIvebeenHere = +new Date();
// page can post messages several times, and that can confuse our react navigation, so we have protection
// against that
let json = false;
try {
json = JSON.parse(e.nativeEvent.data);
} catch (_) {}
if (json && json.allowed && json.data && json.data.api_key) {
this.props.route.params.cb(json.data.api_key, json.data.api_signature_key);
this.props.navigation.pop();
}
}}
/>
</SafeBlueArea>
);
}
}
HodlHodlLogin.propTypes = {
route: PropTypes.shape({
params: PropTypes.shape({
cb: PropTypes.func.isRequired,
}),
}),
navigation: PropTypes.shape({
getParam: PropTypes.func,
navigate: PropTypes.func,
pop: PropTypes.func,
}),
if (json && json.allowed && json.data && json.data.api_key) {
cb(json.data.api_key, json.data.api_signature_key);
navigation.dangerouslyGetParent().pop();
}
}}
/>
</SafeBlueArea>
);
};
HodlHodlLogin.navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: 'Login',
headerLeft: null,
});
export default HodlHodlLogin;

View file

@ -19,22 +19,16 @@ import {
BlueNavigationStyle,
BlueSpacing10,
BlueSpacing20,
SafeBlueArea,
} from '../../BlueComponents';
import { AppStorage } from '../../class';
import { HodlHodlApi } from '../../class/hodl-hodl-api';
import Modal from 'react-native-modal';
import * as NavigationService from '../../NavigationService';
import { BlueCurrentTheme } from '../../components/themes';
const BlueApp: AppStorage = require('../../BlueApp');
export default class HodlHodlMyContracts extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: 'My contracts',
headerLeft: null,
});
constructor(props) {
super(props);
@ -64,13 +58,13 @@ export default class HodlHodlMyContracts extends Component {
render() {
if (this.state.isLoading) return <BlueLoading />;
return (
<SafeBlueArea>
<View style={styles.root}>
<FlatList
scrollEnabled={false}
keyExtractor={(item, index) => {
return item.id;
}}
ListEmptyComponent={() => <Text style={styles.emptyComponentText}>You dont have any contracts in progress</Text>}
ListEmptyComponent={() => <Text style={styles.emptyComponentText}>You don't have any contracts in progress</Text>}
style={styles.flatList}
ItemSeparatorComponent={() => <View style={styles.itemSeparatorComponent} />}
data={this.state.contracts}
@ -104,7 +98,7 @@ export default class HodlHodlMyContracts extends Component {
)}
/>
{this.renderContract()}
</SafeBlueArea>
</View>
);
}
@ -346,12 +340,16 @@ export default class HodlHodlMyContracts extends Component {
}
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
bottomModal: {
justifyContent: 'flex-end',
margin: 0,
},
modalContent: {
backgroundColor: '#FFFFFF',
backgroundColor: BlueCurrentTheme.colors.modal,
padding: 22,
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
@ -363,7 +361,7 @@ const styles = StyleSheet.create({
alignItems: 'center',
},
statusGreenWrapper: {
backgroundColor: '#d2f8d5',
backgroundColor: BlueCurrentTheme.colors.feeLabel,
borderRadius: 20,
height: 28,
justifyContent: 'center',
@ -374,10 +372,10 @@ const styles = StyleSheet.create({
},
statusGreenText: {
fontSize: 12,
color: '#37bfa0',
color: BlueCurrentTheme.colors.feeValue,
},
statusGrayWrapper: {
backgroundColor: '#ebebeb',
backgroundColor: BlueCurrentTheme.colors.lightBorder,
borderRadius: 20,
height: 28,
justifyContent: 'center',
@ -388,10 +386,10 @@ const styles = StyleSheet.create({
},
statusGrayText: {
fontSize: 12,
color: 'gray',
color: '#9AA0AA',
},
statusGrayWrapper2: {
backgroundColor: '#f8f8f8',
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
borderRadius: 5,
minHeight: 28,
maxHeight: 56,
@ -402,26 +400,36 @@ const styles = StyleSheet.create({
},
statusGrayText2: {
fontSize: 12,
color: 'gray',
color: '#9AA0AA',
},
btcText: {
fontWeight: 'bold',
fontSize: 18,
color: '#0c2550',
color: BlueCurrentTheme.colors.foregroundColor,
},
subheaderText: {
fontSize: 12,
fontWeight: 'bold',
color: '#0c2550',
color: BlueCurrentTheme.colors.feeText,
},
emptyComponentText: { textAlign: 'center', color: '#9AA0AA', paddingHorizontal: 16 },
loading: { backgroundColor: BlueCurrentTheme.colors.elevated },
emptyComponentText: { textAlign: 'center', color: '#9AA0AA', paddingHorizontal: 16, backgroundColor: BlueCurrentTheme.colors.elevated },
itemSeparatorComponent: { height: 0.5, width: '100%', backgroundColor: '#C8C8C8' },
flexDirectionRow: { flexDirection: 'row' },
flexDirectionColumn: { flexDirection: 'column' },
volumeBreakdownText: { fontSize: 18, color: '#0c2550' },
contractStatusText: { fontSize: 14, color: 'gray', fontWeight: 'normal' },
volumeBreakdownText: { fontSize: 18, color: BlueCurrentTheme.colors.foregroundColor },
contractStatusText: { fontSize: 13, color: 'gray', fontWeight: 'normal' },
cancelContractText: { color: '#d0021b', fontSize: 15, paddingTop: 20, fontWeight: '500', textAlign: 'center' },
openChatText: { color: '#1b02d0', fontSize: 15, paddingTop: 20, fontWeight: '500', textAlign: 'center' },
flatList: { paddingTop: 30 },
openChatText: { color: BlueCurrentTheme.colors.foregroundColor, fontSize: 15, paddingTop: 20, fontWeight: '500', textAlign: 'center' },
flatList: { paddingTop: 30, backgroundColor: BlueCurrentTheme.colors.elevated },
roleText: { fontSize: 14, color: 'gray', padding: 5 },
});
HodlHodlMyContracts.navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: 'My contracts',
headerStyle: {
backgroundColor: BlueCurrentTheme.colors.elevated,
},
headerRight: null,
});

View file

@ -7,16 +7,12 @@ import { HodlHodlApi } from '../../class/hodl-hodl-api';
import { Icon } from 'react-native-elements';
import { AppStorage } from '../../class';
import * as NavigationService from '../../NavigationService';
import { BlueCurrentTheme } from '../../components/themes';
const BlueApp: AppStorage = require('../../BlueApp');
const prompt = require('../../blue_modules/prompt');
export default class HodlHodlViewOffer extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(),
title: '',
});
constructor(props) {
super(props);
@ -75,7 +71,7 @@ export default class HodlHodlViewOffer extends Component {
const HodlApi = new HodlHodlApi(hodlApiKey);
this.setState({ HodlApi, hodlApiKey });
};
NavigationService.navigate('HodlHodlRoot', { params: { cb: handleLoginCallback }, screen: 'HodlHodlLogin' });
NavigationService.navigate('HodlHodl', { params: { cb: handleLoginCallback }, screen: 'HodlHodlLogin' });
};
async _onAcceptOfferPress(offer) {
@ -269,19 +265,19 @@ HodlHodlViewOffer.propTypes = {
const styles = StyleSheet.create({
modalContent: {
backgroundColor: '#FFFFFF',
backgroundColor: BlueCurrentTheme.colors.background,
padding: 22,
},
Title: {
fontWeight: '600',
fontSize: 24,
color: '#0c2550',
color: BlueCurrentTheme.colors.foregroundColor,
},
circleWhite: {
position: 'absolute',
bottom: 0,
right: 3,
backgroundColor: 'white',
backgroundColor: BlueCurrentTheme.colors.background,
width: 13,
height: 13,
borderRadius: 6,
@ -296,7 +292,7 @@ const styles = StyleSheet.create({
borderRadius: 5,
},
grayTextContainerContainer: {
backgroundColor: '#EEF0F4',
backgroundColor: BlueCurrentTheme.colors.lightButton,
borderRadius: 20,
height: 30,
justifyContent: 'center',
@ -306,7 +302,7 @@ const styles = StyleSheet.create({
paddingRight: 20,
},
greenTextContainerContainer: {
backgroundColor: '#d2f8d5',
backgroundColor: BlueCurrentTheme.colors.feeLabel,
borderRadius: 20,
height: 30,
justifyContent: 'center',
@ -323,7 +319,7 @@ const styles = StyleSheet.create({
},
priceText: {
top: 0,
color: '#37bfa0',
color: BlueCurrentTheme.colors.feeValue,
fontSize: 14,
fontWeight: '500',
},
@ -338,7 +334,7 @@ const styles = StyleSheet.create({
lineHeight: 23,
},
nicknameText: {
color: '#0c2550',
color: BlueCurrentTheme.colors.foregroundColor,
fontSize: 16,
fontWeight: 'bold',
},
@ -349,20 +345,35 @@ const styles = StyleSheet.create({
locationText: {
color: '#9BA0A9',
},
horizontalScrollIemHeader: { fontSize: 12, color: '#9AA0AA' },
horizontalScrollItemBody: { fontSize: 14, fontWeight: 'bold', color: '#0c2550' },
horizontalScrollIemHeader: { color: BlueCurrentTheme.colors.feeText },
horizontalScrollItemBody: { fontSize: 14, fontWeight: 'bold', color: BlueCurrentTheme.colors.foregroundColor },
horizontalScrollWrapper: { flexDirection: 'column', paddingTop: 20, paddingBottom: 20, paddingRight: 40 },
flexDirRow: { flexDirection: 'row' },
iconWithPadding: { paddingLeft: 16 },
_hr: {
borderWidth: 0,
borderBottomWidth: 1,
borderColor: '#ebebeb',
borderColor: BlueCurrentTheme.colors.lightBorder,
},
avatarImg: { width: 60, height: 60, borderRadius: 60 },
avatarWrapper: { backgroundColor: 'white', flex: 1, flexDirection: 'column', alignItems: 'center', marginTop: 32 },
avatarWrapper: {
backgroundColor: BlueCurrentTheme.colors.background,
flex: 1,
flexDirection: 'column',
alignItems: 'center',
marginTop: 32,
},
verifiedIcon: { marginTop: 3, marginRight: 5 },
traderWrapper: { alignItems: 'center', marginTop: 8 },
acceptOfferButtonWrapper: { width: '70%', alignItems: 'center' },
acceptOfferButtonWrapperWrapper: { marginTop: 24, alignItems: 'center' },
});
HodlHodlViewOffer.navigationOptions = () => ({
...BlueNavigationStyle(),
title: '',
headerStyle: {
...BlueNavigationStyle().headerStyle,
backgroundColor: BlueCurrentTheme.colors.customHeader,
},
});

View file

@ -4,12 +4,6 @@ import { BlueNavigationStyle, SafeBlueArea } from '../../BlueComponents';
import PropTypes from 'prop-types';
export default class HodlHodlWebview extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: '',
headerLeft: null,
});
constructor(props) {
super(props);
@ -36,3 +30,9 @@ HodlHodlWebview.propTypes = {
}),
}),
};
HodlHodlWebview.navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: '',
headerLeft: null,
});

View file

@ -13,28 +13,30 @@ import {
} from '../../BlueComponents';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import Privacy from '../../Privacy';
import { useNavigation, useRoute } from '@react-navigation/native';
import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
import WalletImport from '../../class/wallet-import';
const loc = require('../../loc');
const { width } = Dimensions.get('window');
const styles = StyleSheet.create({
root: {
flex: 1,
paddingTop: 40,
},
center: {
flex: 1,
alignItems: 'center',
},
});
const WalletsImport = () => {
const [isToolbarVisibleForAndroid, setIsToolbarVisibleForAndroid] = useState(false);
const route = useRoute();
const label = (route.params && route.params.label) || '';
const [importText, setImportText] = useState(label);
const navigation = useNavigation();
const { colors } = useTheme();
const styles = StyleSheet.create({
root: {
flex: 1,
paddingTop: 40,
backgroundColor: colors.elevated,
},
center: {
flex: 1,
alignItems: 'center',
backgroundColor: colors.elevated,
},
});
useEffect(() => {
Privacy.enableBlur();
@ -92,8 +94,8 @@ const WalletsImport = () => {
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<StatusBar barStyle="light-content" />
<StatusBar barStyle="default" />
<BlueSpacing20 />
<BlueFormLabel>{loc.wallets.import.explanation}</BlueFormLabel>
<BlueSpacing20 />
<BlueFormMultiInput
@ -148,8 +150,8 @@ const WalletsImport = () => {
);
};
WalletsImport.navigationOptions = {
WalletsImport.navigationOptions = ({ navigation, route }) => ({
...BlueNavigationStyle(),
title: loc.wallets.import.title,
};
});
export default WalletsImport;

View file

@ -23,6 +23,7 @@ import WalletImport from '../../class/wallet-import';
import ActionSheet from '../ActionSheet';
import ImagePicker from 'react-native-image-picker';
import * as NavigationService from '../../NavigationService';
import { BlueCurrentTheme } from '../../components/themes';
const EV = require('../../blue_modules/events');
const A = require('../../blue_modules/analytics');
const BlueApp: AppStorage = require('../../BlueApp');
@ -33,18 +34,6 @@ const LocalQRCode = require('@remobile/react-native-qrcode-local-image');
const WalletsListSections = { CAROUSEL: 'CAROUSEL', LOCALTRADER: 'LOCALTRADER', TRANSACTIONS: 'TRANSACTIONS' };
export default class WalletsList extends Component {
static navigationOptions = ({ navigation, route }) => {
return {
...BlueNavigationStyle(navigation, true),
title: '',
headerRight: () => (
<TouchableOpacity testID="SettingsButton" style={styles.headerTouch} onPress={() => NavigationService.navigate('Settings')}>
<Icon size={22} name="kebab-horizontal" type="octicon" color={BlueApp.settings.foregroundColor} />
</TouchableOpacity>
),
};
};
walletsCarousel = React.createRef();
constructor(props) {
@ -289,7 +278,7 @@ export default class WalletsList extends Component {
renderListHeaderComponent = () => {
return (
<View style={styles.listHeader}>
<View style={styles.listHeaderBack}>
<Text style={styles.listHeaderText}>{loc.transactions.list.title}</Text>
</View>
);
@ -316,7 +305,7 @@ export default class WalletsList extends Component {
return (
<TouchableOpacity
onPress={() => {
this.props.navigation.navigate('HodlHodlRoot', { params: { wallet: this.state.wallet }, screen: 'HodlHodl' });
this.props.navigation.navigate('HodlHodl', { params: { wallet: this.state.wallet }, screen: 'HodlHodl' });
}}
style={styles.ltRoot}
>
@ -527,7 +516,7 @@ export default class WalletsList extends Component {
render() {
return (
<View style={styles.root}>
<StatusBar barStyle="dark-content" />
<StatusBar barStyle="default" />
<View style={styles.walletsListWrapper}>
<SectionList
refreshControl={<RefreshControl onRefresh={this.refreshTransactions} refreshing={!this.state.isFlatListRefreshControlHidden} />}
@ -561,12 +550,12 @@ const styles = StyleSheet.create({
right: 0,
},
wrapper: {
backgroundColor: '#FFFFFF',
backgroundColor: BlueCurrentTheme.colors.brandingColor,
flex: 1,
},
walletsListWrapper: {
flex: 1,
backgroundColor: '#FFFFFF',
backgroundColor: BlueCurrentTheme.colors.brandingColor,
},
headerStyle: {
...Platform.select({
@ -595,7 +584,7 @@ const styles = StyleSheet.create({
fontWeight: 'bold',
fontSize: 24,
marginVertical: 8,
color: BlueApp.settings.foregroundColor,
color: BlueCurrentTheme.colors.foregroundColor,
},
ltRoot: {
flexDirection: 'row',
@ -603,7 +592,7 @@ const styles = StyleSheet.create({
alignItems: 'center',
marginHorizontal: 16,
marginVertical: 16,
backgroundColor: '#eef0f4',
backgroundColor: BlueCurrentTheme.colors.ballOutgoingExpired,
padding: 16,
borderRadius: 6,
},
@ -613,12 +602,12 @@ const styles = StyleSheet.create({
ltTextBig: {
fontSize: 16,
fontWeight: '600',
color: '#0C2550',
color: BlueCurrentTheme.colors.foregroundColor,
},
ltTextSmall: {
fontSize: 13,
fontWeight: '500',
color: '#9AA0AA',
color: BlueCurrentTheme.colors.alternativeTextColor,
},
ltButtonWrap: {
flexDirection: 'column',
@ -676,3 +665,22 @@ WalletsList.propTypes = {
params: PropTypes.object,
}),
};
WalletsList.navigationOptions = ({ navigation, route }) => {
return {
...BlueNavigationStyle(navigation, true),
title: '',
headerStyle: {
backgroundColor: BlueCurrentTheme.colors.customHeader,
borderBottomWidth: 0,
elevation: 0,
shadowOpacity: 0,
shadowOffset: { height: 0, width: 0 },
},
headerRight: () => (
<TouchableOpacity testID="SettingsButton" style={styles.headerTouch} onPress={() => NavigationService.navigate('Settings')}>
<Icon size={22} name="kebab-horizontal" type="octicon" color={BlueCurrentTheme.colors.foregroundColor} />
</TouchableOpacity>
),
};
};

View file

@ -5,12 +5,6 @@ import { BlueLoading, BlueNavigationStyle } from '../../BlueComponents';
import PropTypes from 'prop-types';
export default class Marketplace extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: 'Marketplace',
headerLeft: null,
});
webview = React.createRef();
constructor(props) {
@ -80,3 +74,9 @@ Marketplace.propTypes = {
params: PropTypes.object,
}),
};
Marketplace.navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: 'Marketplace',
headerLeft: null,
});

View file

@ -1,71 +1,73 @@
import React, { useEffect, useState, useCallback } from 'react';
import { ActivityIndicator, View, BackHandler, Text, ScrollView, StyleSheet, StatusBar } from 'react-native';
import { useNavigation, useRoute } from '@react-navigation/native';
import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
import { BlueSpacing20, SafeBlueArea, BlueNavigationStyle, BlueText, BlueButton } from '../../BlueComponents';
import Privacy from '../../Privacy';
const loc = require('../../loc');
const styles = StyleSheet.create({
flex: {
flex: 1,
},
loading: {
flex: 1,
paddingTop: 20,
},
word: {
width: 'auto',
marginRight: 8,
marginBottom: 8,
backgroundColor: '#f5f5f5',
paddingTop: 6,
paddingBottom: 6,
paddingLeft: 8,
paddingRight: 8,
borderRadius: 4,
},
wortText: {
color: '#81868E',
fontWeight: 'bold',
},
scrollViewContent: {
justifyContent: 'space-between',
},
please: {
alignItems: 'center',
paddingHorizontal: 16,
},
successText: {
textAlign: 'center',
fontWeight: 'bold',
color: '#0C2550',
},
pleaseText: {
paddingBottom: 10,
paddingRight: 0,
paddingLeft: 0,
color: '#0C2550',
},
secret: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
flexWrap: 'wrap',
marginTop: 14,
},
ok: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
flexWrap: 'wrap',
},
});
const loc = require('../../loc');
const PleaseBackup = () => {
const [isLoading, setIsLoading] = useState(true);
const route = useRoute();
const words = route.params.secret.split(' ');
const navigation = useNavigation();
const { colors } = useTheme();
const styles = StyleSheet.create({
flex: {
flex: 1,
backgroundColor: colors.elevated,
},
loading: {
flex: 1,
paddingTop: 20,
},
word: {
width: 'auto',
marginRight: 8,
marginBottom: 8,
backgroundColor: colors.inputBackgroundColor,
paddingTop: 6,
paddingBottom: 6,
paddingLeft: 8,
paddingRight: 8,
borderRadius: 4,
},
wortText: {
color: colors.labelText,
fontWeight: 'bold',
},
scrollViewContent: {
justifyContent: 'space-between',
},
please: {
alignItems: 'center',
paddingHorizontal: 16,
},
successText: {
textAlign: 'center',
fontWeight: 'bold',
color: colors.foregroundColor,
},
pleaseText: {
paddingBottom: 10,
paddingRight: 0,
paddingLeft: 0,
color: colors.foregroundColor,
},
secret: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
flexWrap: 'wrap',
marginTop: 14,
},
ok: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
flexWrap: 'wrap',
},
});
const handleBackButton = useCallback(() => {
navigation.dangerouslyGetParent().pop();
@ -102,7 +104,7 @@ const PleaseBackup = () => {
</View>
) : (
<SafeBlueArea style={styles.flex}>
<StatusBar barStyle="light-content" />
<StatusBar barStyle="default" />
<ScrollView contentContainerStyle={styles.scrollViewContent} testID="PleaseBackupScrollView">
<View style={styles.please}>
<BlueText style={styles.successText}>{loc.pleasebackup.success}</BlueText>

View file

@ -1,5 +1,5 @@
import React, { useState, useCallback, useEffect } from 'react';
import { useNavigation, useRoute } from '@react-navigation/native';
import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
import { View, Dimensions, StyleSheet, BackHandler, StatusBar } from 'react-native';
import {
SafeBlueArea,
@ -14,27 +14,27 @@ import QRCode from 'react-native-qrcode-svg';
import Privacy from '../../Privacy';
import { ScrollView } from 'react-native-gesture-handler';
const { height, width } = Dimensions.get('window');
const BlueApp = require('../../BlueApp');
const loc = require('../../loc');
const styles = StyleSheet.create({
root: {
flex: 1,
},
scrollViewContent: {
flexGrow: 1,
},
});
const PleaseBackupLNDHub = () => {
const { wallet } = useRoute().params;
const navigation = useNavigation();
const { colors } = useTheme();
const [qrCodeHeight, setQrCodeHeight] = useState(height > width ? width - 40 : width / 2);
const handleBackButton = useCallback(() => {
navigation.dangerouslyGetParent().pop();
return true;
}, [navigation]);
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: colors.elevated,
},
scrollViewContent: {
flexGrow: 1,
backgroundColor: colors.elevated,
},
});
useEffect(() => {
Privacy.enableBlur();
@ -52,7 +52,7 @@ const PleaseBackupLNDHub = () => {
return (
<SafeBlueArea style={styles.root}>
<StatusBar barStyle="light-content" />
<StatusBar barStyle="default" />
<ScrollView centerContent contentContainerStyle={styles.scrollViewContent} onLayout={onLayout}>
<BlueCard>
<View>
@ -67,8 +67,9 @@ const PleaseBackupLNDHub = () => {
logo={require('../../img/qr-code.png')}
logoSize={90}
size={qrCodeHeight}
color={BlueApp.settings.foregroundColor}
logoBackgroundColor={BlueApp.settings.brandingColor}
color={colors.foregroundColor}
logoBackgroundColor={colors.brandingColor}
backgroundColor={colors.background}
ecl="H"
/>

View file

@ -3,11 +3,10 @@ import PropTypes from 'prop-types';
import BN from 'bignumber.js';
import { Dimensions, View, ScrollView, Text, Image, TouchableOpacity, StyleSheet } from 'react-native';
import { Icon } from 'react-native-elements';
import { useNavigation, useRoute } from '@react-navigation/native';
import { SafeBlueArea, BlueNavigationStyle, BlueTabs } from '../../BlueComponents';
import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
import { BlueCurrentTheme } from '../../components/themes';
import { BlueSpacing20, SafeBlueArea, BlueNavigationStyle, BlueTabs } from '../../BlueComponents';
const loc = require('../../loc');
const BlueApp = require('../../BlueApp');
const ENTROPY_LIMIT = 256;
@ -133,7 +132,7 @@ const Dice = ({ push, sides }) => {
};
return (
<ScrollView style={styles.diceScroll} contentContainerStyle={styles.diceContainer}>
<ScrollView contentContainerStyle={styles.diceContainer}>
{[...Array(sides)].map((_, i) => (
<TouchableOpacity key={i} onPress={() => push(getEntropy(i, sides))}>
<View style={styles.diceRoot}>
@ -141,7 +140,7 @@ const Dice = ({ push, sides }) => {
<Icon style={styles.diceIcon} name={diceIcon(i + 1)} size={70} color="grey" type="font-awesome-5" />
) : (
<View style={styles.dice}>
<Text>{i + 1}</Text>
<Text style={styles.diceText}>{i + 1}</Text>
</View>
)}
</View>
@ -162,7 +161,7 @@ const Buttons = ({ pop, save }) => (
<View style={styles.buttonsBody}>
<View style={styles.buttonsRow}>
<View style={styles.buttonsIcon}>
<Icon name="undo" size={16} type="font-awesome" color={BlueApp.settings.buttonAlternativeTextColor} />
<Icon name="undo" size={16} type="font-awesome" color={BlueCurrentTheme.colors.buttonAlternativeTextColor} />
</View>
<Text style={styles.buttonsLabel}>{loc.entropy.undo}</Text>
</View>
@ -172,7 +171,7 @@ const Buttons = ({ pop, save }) => (
<View style={styles.buttonsBody}>
<View style={styles.buttonsRow}>
<View style={styles.buttonsIcon}>
<Icon name="arrow-down" size={16} type="font-awesome" color={BlueApp.settings.buttonAlternativeTextColor} />
<Icon name="arrow-down" size={16} type="font-awesome" color={BlueCurrentTheme.colors.buttonAlternativeTextColor} />
</View>
<Text style={[styles.buttonsLabel, styles.buttonsLabelRight]}>{loc.entropy.save}</Text>
</View>
@ -192,6 +191,7 @@ const Entropy = () => {
const navigation = useNavigation();
const [tab, setTab] = useState(1);
const [show, setShow] = useState(false);
const { colors } = useTheme();
const push = v => v && dispatch({ type: 'push', value: v.value, bits: v.bits });
const pop = () => dispatch({ type: 'pop' });
@ -207,6 +207,7 @@ const Entropy = () => {
return (
<SafeBlueArea>
<BlueSpacing20 />
<TouchableOpacity onPress={() => setShow(!show)}>
<View style={styles.entropy}>
<Text style={styles.entropyText}>{show ? hex : `${bits} of 256 bits`}</Text>
@ -218,25 +219,13 @@ const Entropy = () => {
onSwitch={setTab}
tabs={[
({ active }) => (
<Icon
name="toll"
type="material"
color={active ? BlueApp.settings.buttonAlternativeTextColor : BlueApp.settings.buttonBackgroundColor}
/>
<Icon name="toll" type="material" color={active ? colors.buttonAlternativeTextColor : colors.buttonBackgroundColor} />
),
({ active }) => (
<Icon
name="dice"
type="font-awesome-5"
color={active ? BlueApp.settings.buttonAlternativeTextColor : BlueApp.settings.buttonBackgroundColor}
/>
<Icon name="dice" type="font-awesome-5" color={active ? colors.buttonAlternativeTextColor : colors.buttonBackgroundColor} />
),
({ active }) => (
<Icon
name="dice-d20"
type="font-awesome-5"
color={active ? BlueApp.settings.buttonAlternativeTextColor : BlueApp.settings.buttonBackgroundColor}
/>
<Icon name="dice-d20" type="font-awesome-5" color={active ? colors.buttonAlternativeTextColor : colors.buttonBackgroundColor} />
),
]}
/>
@ -267,7 +256,7 @@ const styles = StyleSheet.create({
padding: 5,
marginLeft: 10,
marginRight: 10,
backgroundColor: '#f2f2f2',
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
borderRadius: 9,
minHeight: 49,
paddingHorizontal: 8,
@ -278,13 +267,13 @@ const styles = StyleSheet.create({
entropyText: {
fontSize: 15,
fontFamily: 'Courier',
color: BlueCurrentTheme.colors.foregroundColor,
},
coinRoot: {
flex: 1,
justifyContent: 'center',
flexDirection: 'row',
flexWrap: 'wrap',
backgroundColor: 'white',
},
coinBody: {
flex: 0.33,
@ -293,7 +282,7 @@ const styles = StyleSheet.create({
aspectRatio: 1,
borderWidth: 1,
borderRadius: 5,
borderColor: 'grey',
borderColor: BlueCurrentTheme.colors.lightButton,
margin: 10,
padding: 10,
},
@ -303,9 +292,6 @@ const styles = StyleSheet.create({
height: '100%',
borderRadius: 75,
},
diceScroll: {
backgroundColor: 'white',
},
diceContainer: {
alignItems: 'flex-start',
flexDirection: 'row',
@ -321,10 +307,13 @@ const styles = StyleSheet.create({
margin: 3,
borderWidth: 1,
borderRadius: 5,
borderColor: 'grey',
justifyContent: 'center',
alignItems: 'center',
aspectRatio: 1,
borderColor: BlueCurrentTheme.colors.buttonBackgroundColor,
},
diceText: {
color: BlueCurrentTheme.colors.foregroundColor,
},
diceIcon: {
margin: 3,
@ -346,7 +335,7 @@ const styles = StyleSheet.create({
buttonsBody: {
flex: 1,
minWidth: 130,
backgroundColor: BlueApp.settings.buttonBackgroundColor,
backgroundColor: BlueCurrentTheme.colors.buttonBackgroundColor,
},
buttonsRow: {
flex: 1,
@ -364,7 +353,7 @@ const styles = StyleSheet.create({
marginBottom: -11,
},
buttonsLabel: {
color: BlueApp.settings.buttonAlternativeTextColor,
color: BlueCurrentTheme.colors.buttonAlternativeTextColor,
fontWeight: '500',
left: 5,
backgroundColor: 'transparent',

View file

@ -7,6 +7,7 @@ import PropTypes from 'prop-types';
import { PlaceholderWallet, LightningCustodianWallet } from '../../class';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import WalletGradient from '../../class/wallet-gradient';
import { BlueCurrentTheme } from '../../components/themes';
const EV = require('../../blue_modules/events');
/** @type {AppStorage} */
const BlueApp = require('../../BlueApp');
@ -19,6 +20,7 @@ const styles = StyleSheet.create({
},
root: {
flex: 1,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
itemRoot: {
backgroundColor: 'transparent',
@ -66,17 +68,6 @@ const styles = StyleSheet.create({
});
export default class ReorderWallets extends Component {
static navigationOptions = ({ navigation, route }) => ({
...BlueNavigationStyle(
navigation,
true,
route.params && route.params.customCloseButtonFunction ? route.params.customCloseButtonFunction : undefined,
),
headerTitle: loc.wallets.reorder.title,
headerLeft: null,
gestureEnabled: false,
});
constructor(props) {
super(props);
this.state = {
@ -196,3 +187,14 @@ ReorderWallets.propTypes = {
goBack: PropTypes.func,
}),
};
ReorderWallets.navigationOptions = ({ navigation, route }) => ({
...BlueNavigationStyle(
navigation,
true,
route.params && route.params.customCloseButtonFunction ? route.params.customCloseButtonFunction : undefined,
),
headerTitle: loc.wallets.reorder.title,
headerLeft: null,
gestureEnabled: false,
});

View file

@ -1,83 +1,20 @@
/* eslint-disable react/prop-types */
import React, { useEffect, useState } from 'react';
import { View, ActivityIndicator, Image, Text, TouchableOpacity, FlatList, StyleSheet, StatusBar } from 'react-native';
import { SafeBlueArea, BlueNavigationStyle, BlueText, BlueSpacing20, BluePrivateBalance } from '../../BlueComponents';
import { SafeBlueArea, BlueText, BlueSpacing20, BluePrivateBalance, BlueNavigationStyle } from '../../BlueComponents';
import LinearGradient from 'react-native-linear-gradient';
import { LightningCustodianWallet } from '../../class/wallets/lightning-custodian-wallet';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import WalletGradient from '../../class/wallet-gradient';
import { useRoute } from '@react-navigation/native';
import { useRoute, useTheme } from '@react-navigation/native';
/** @type {AppStorage} */
const BlueApp = require('../../BlueApp');
const loc = require('../../loc');
const styles = StyleSheet.create({
root: {
flex: 1,
},
loading: {
flex: 1,
justifyContent: 'center',
alignContent: 'center',
paddingTop: 20,
},
itemRoot: {
backgroundColor: 'transparent',
padding: 10,
marginVertical: 17,
},
gradient: {
padding: 15,
borderRadius: 10,
minHeight: 164,
elevation: 5,
},
image: {
width: 99,
height: 94,
position: 'absolute',
bottom: 0,
right: 0,
},
transparentText: {
backgroundColor: 'transparent',
},
label: {
backgroundColor: 'transparent',
fontSize: 19,
color: '#fff',
},
balance: {
backgroundColor: 'transparent',
fontWeight: 'bold',
fontSize: 36,
color: '#fff',
},
latestTxLabel: {
backgroundColor: 'transparent',
fontSize: 13,
color: '#fff',
},
latestTxValue: {
backgroundColor: 'transparent',
fontWeight: 'bold',
fontSize: 16,
color: '#fff',
},
noWallets: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingTop: 20,
},
center: {
textAlign: 'center',
},
});
const SelectWallet = ({ navigation }) => {
const { chainType, onWalletSelect, availableWallets } = useRoute().params;
const [isLoading, setIsLoading] = useState(true);
const { colors } = useTheme();
let data = chainType
? BlueApp.getWallets().filter(item => item.chain === chainType && item.allowSend())
: BlueApp.getWallets().filter(item => item.allowSend()) || [];
@ -86,6 +23,70 @@ const SelectWallet = ({ navigation }) => {
// availableWallets if provided, overrides chainType argument and `allowSend()` check
data = availableWallets;
}
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: colors.background,
},
loading: {
flex: 1,
justifyContent: 'center',
alignContent: 'center',
paddingTop: 20,
},
itemRoot: {
backgroundColor: 'transparent',
padding: 10,
marginVertical: 17,
},
gradient: {
padding: 15,
borderRadius: 10,
minHeight: 164,
elevation: 5,
},
image: {
width: 99,
height: 94,
position: 'absolute',
bottom: 0,
right: 0,
},
transparentText: {
backgroundColor: 'transparent',
},
label: {
backgroundColor: 'transparent',
fontSize: 19,
color: '#fff',
},
balance: {
backgroundColor: 'transparent',
fontWeight: 'bold',
fontSize: 36,
color: '#fff',
},
latestTxLabel: {
backgroundColor: 'transparent',
fontSize: 13,
color: '#fff',
},
latestTxValue: {
backgroundColor: 'transparent',
fontWeight: 'bold',
fontSize: 16,
color: '#fff',
},
noWallets: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingTop: 20,
},
center: {
textAlign: 'center',
},
});
useEffect(() => {
setIsLoading(false);
@ -135,13 +136,14 @@ const SelectWallet = ({ navigation }) => {
if (isLoading) {
return (
<View style={styles.loading}>
<StatusBar barStyle="light-content" />
<ActivityIndicator />
</View>
);
} else if (data.length <= 0) {
return (
<SafeBlueArea style={styles.root}>
<StatusBar barStyle="dark-content" />
<StatusBar barStyle="light-content" />
<View style={styles.noWallets}>
<BlueText style={styles.center}>There are currently no Bitcoin wallets available.</BlueText>
<BlueSpacing20 />
@ -152,7 +154,7 @@ const SelectWallet = ({ navigation }) => {
} else {
return (
<SafeBlueArea style={styles.root}>
<StatusBar barStyle="dark-content" />
<StatusBar barStyle="default" />
<FlatList extraData={data} data={data} renderItem={renderItem} keyExtractor={(_item, index) => `${index}`} />
</SafeBlueArea>
);
@ -160,9 +162,10 @@ const SelectWallet = ({ navigation }) => {
};
SelectWallet.navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true, () => navigation.goBack(null)),
title: loc.wallets.select_wallet,
...BlueNavigationStyle(navigation, true),
headerRight: null,
headerTitle: loc.wallets.select_wallet,
headerBackTitleVisible: false,
});
export default SelectWallet;

View file

@ -36,6 +36,7 @@ import Modal from 'react-native-modal';
import * as NavigationService from '../../NavigationService';
import HandoffSettings from '../../class/handoff';
import Handoff from 'react-native-handoff';
import { BlueCurrentTheme } from '../../components/themes';
import ActionSheet from '../ActionSheet';
/** @type {AppStorage} */
const BlueApp = require('../../BlueApp');
@ -66,7 +67,7 @@ const styles = StyleSheet.create({
height: 200,
},
advancedTransactionOptionsModalContent: {
backgroundColor: '#FFFFFF',
backgroundColor: BlueCurrentTheme.colors.elevated,
padding: 22,
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
@ -98,10 +99,10 @@ const styles = StyleSheet.create({
marginBottom: 8,
fontWeight: 'bold',
fontSize: 24,
color: BlueApp.settings.foregroundColor,
color: BlueCurrentTheme.colors.foregroundColor,
},
marketplaceButton1: {
backgroundColor: '#f2f2f2',
backgroundColor: BlueCurrentTheme.colors.lightButton,
borderRadius: 9,
minHeight: 49,
flex: 1,
@ -112,7 +113,7 @@ const styles = StyleSheet.create({
},
marketplaceButton2: {
marginLeft: 5,
backgroundColor: '#f2f2f2',
backgroundColor: BlueCurrentTheme.colors.lightButton,
borderRadius: 9,
minHeight: 49,
flex: 1,
@ -122,16 +123,16 @@ const styles = StyleSheet.create({
alignItems: 'center',
},
marketpalceText1: {
color: '#062453',
color: BlueCurrentTheme.colors.cta2,
fontSize: 18,
},
marketpalceText2: {
color: '#062453',
color: BlueCurrentTheme.colors.cta2,
fontSize: 18,
marginHorizontal: 8,
},
list: {
backgroundColor: '#FFFFFF',
backgroundColor: BlueCurrentTheme.colors.background,
flex: 1,
},
emptyTxs: {
@ -173,34 +174,6 @@ const styles = StyleSheet.create({
});
export default class WalletTransactions extends Component {
static navigationOptions = ({ navigation, route }) => {
return {
headerRight: () => (
<TouchableOpacity
disabled={route.params.isLoading === true}
style={styles.walletDetails}
onPress={() =>
navigation.navigate('WalletDetails', {
wallet: route.params.wallet,
})
}
>
<Icon name="kebab-horizontal" type="octicon" size={22} color="#FFFFFF" />
</TouchableOpacity>
),
headerTitle: () => null,
headerStyle: {
backgroundColor: WalletGradient.headerColorFor(route.params.wallet.type),
borderBottomWidth: 0,
elevation: 0,
// shadowRadius: 0,
shadowOffset: { height: 0, width: 0 },
},
headerTintColor: '#FFFFFF',
headerBackTitleVisible: false,
};
};
walletBalanceText = null;
constructor(props) {
@ -833,3 +806,31 @@ WalletTransactions.propTypes = {
params: PropTypes.object,
}),
};
WalletTransactions.navigationOptions = ({ navigation, route }) => {
return {
headerRight: () => (
<TouchableOpacity
disabled={route.params.isLoading === true}
style={styles.walletDetails}
onPress={() =>
navigation.navigate('WalletDetails', {
wallet: route.params.wallet,
})
}
>
<Icon name="kebab-horizontal" type="octicon" size={22} color="#FFFFFF" />
</TouchableOpacity>
),
headerTitle: () => null,
headerStyle: {
backgroundColor: WalletGradient.headerColorFor(route.params.wallet.type),
borderBottomWidth: 0,
elevation: 0,
// shadowRadius: 0,
shadowOffset: { height: 0, width: 0 },
},
headerTintColor: '#FFFFFF',
headerBackTitleVisible: false,
};
};

View file

@ -5,6 +5,7 @@ import { BlueSpacing20, SafeBlueArea, BlueText, BlueNavigationStyle, BlueCopyTex
import PropTypes from 'prop-types';
import Privacy from '../../Privacy';
import Biometric from '../../class/biometrics';
import { BlueCurrentTheme } from '../../components/themes';
/** @type {AppStorage} */
const BlueApp = require('../../BlueApp');
const loc = require('../../loc');
@ -14,6 +15,7 @@ const styles = StyleSheet.create({
root: {
flex: 1,
paddingTop: 20,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
container: {
alignItems: 'center',
@ -23,12 +25,6 @@ const styles = StyleSheet.create({
});
export default class WalletXpub extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: loc.wallets.xpub.title,
headerLeft: null,
});
constructor(props) {
super(props);
@ -98,8 +94,9 @@ export default class WalletXpub extends Component {
logo={require('../../img/qr-code.png')}
size={this.state.qrCodeHeight}
logoSize={90}
color={BlueApp.settings.foregroundColor}
logoBackgroundColor={BlueApp.settings.brandingColor}
color={BlueCurrentTheme.colors.foregroundColor}
logoBackgroundColor={BlueCurrentTheme.colors.brandingColor}
backgroundColor={BlueCurrentTheme.colors.background}
ecl="H"
/>
@ -123,3 +120,9 @@ WalletXpub.propTypes = {
}),
}),
};
WalletXpub.navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
title: loc.wallets.xpub.title,
headerLeft: null,
});