mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-22 15:04:50 +01:00
REF: Handoff in-app rather than browser
This commit is contained in:
parent
f1d52e8867
commit
359981ff9b
14 changed files with 108 additions and 49 deletions
31
App.js
31
App.js
|
@ -34,6 +34,7 @@ import Biometric from './class/biometrics';
|
|||
import WidgetCommunication from './blue_modules/WidgetCommunication';
|
||||
import changeNavigationBarColor from 'react-native-navigation-bar-color';
|
||||
import ActionSheet from './screen/ActionSheet';
|
||||
import HandoffComponent from './components/handoff';
|
||||
const A = require('./blue_modules/analytics');
|
||||
const currency = require('./blue_modules/currency');
|
||||
|
||||
|
@ -59,6 +60,7 @@ const App = () => {
|
|||
const colorScheme = useColorScheme();
|
||||
|
||||
const onNotificationReceived = async notification => {
|
||||
console.warn(notification);
|
||||
const payload = Object.assign({}, notification, notification.data);
|
||||
if (notification.data && notification.data.data) Object.assign(payload, notification.data.data);
|
||||
payload.foreground = true;
|
||||
|
@ -77,6 +79,30 @@ const App = () => {
|
|||
);
|
||||
};
|
||||
|
||||
const onUserActivityOpen = data => {
|
||||
console.warn(data);
|
||||
switch (data.activityType) {
|
||||
case HandoffComponent.activityTypes.ReceiveOnchain:
|
||||
NavigationService.navigate('ReceiveDetailsRoot', {
|
||||
screen: 'ReceiveDetails',
|
||||
params: {
|
||||
address: data.userInfo.address,
|
||||
},
|
||||
});
|
||||
break;
|
||||
case HandoffComponent.activityTypes.Xpub:
|
||||
NavigationService.navigate('WalletXpubRoot', {
|
||||
screen: 'WalletXpub',
|
||||
params: {
|
||||
xPub: data.userInfo.xpub,
|
||||
},
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (walletsInitialized) {
|
||||
addListeners();
|
||||
|
@ -90,6 +116,7 @@ const App = () => {
|
|||
AppState.removeEventListener('change', handleAppStateChange);
|
||||
eventEmitter.removeAllListeners('onNotificationReceived');
|
||||
eventEmitter.removeAllListeners('openSettings');
|
||||
eventEmitter.removeAllListeners('onUserActivityOpen');
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
@ -117,9 +144,11 @@ const App = () => {
|
|||
*/
|
||||
eventEmitter.addListener('onNotificationReceived', onNotificationReceived);
|
||||
eventEmitter.addListener('openSettings', openSettings);
|
||||
eventEmitter.addListener('onUserActivityOpen', onUserActivityOpen);
|
||||
};
|
||||
|
||||
const popInitialAction = async data => {
|
||||
console.warn(data);
|
||||
if (data) {
|
||||
const wallet = wallets.find(wallet => wallet.getID() === data.userInfo.url.split('wallet/')[1]);
|
||||
NavigationService.dispatch(
|
||||
|
@ -134,6 +163,7 @@ const App = () => {
|
|||
);
|
||||
} else {
|
||||
const url = await Linking.getInitialURL();
|
||||
console.warn(url);
|
||||
if (url) {
|
||||
if (DeeplinkSchemaMatch.hasSchema(url)) {
|
||||
handleOpenURL({ url });
|
||||
|
@ -295,6 +325,7 @@ const App = () => {
|
|||
};
|
||||
|
||||
const handleOpenURL = event => {
|
||||
console.warn(event);
|
||||
DeeplinkSchemaMatch.navigationRouteFor(event, value => NavigationService.navigate(...value), { wallets, addWallet, saveToDisk });
|
||||
};
|
||||
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
import React, { useContext } from 'react';
|
||||
import Handoff from 'react-native-handoff';
|
||||
import { BlueStorageContext } from '../blue_modules/storage-context';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const HandoffComponent = props => {
|
||||
const { isHandOffUseEnabled } = useContext(BlueStorageContext);
|
||||
|
||||
return isHandOffUseEnabled && props && props.url ? <Handoff {...props} /> : null;
|
||||
};
|
||||
export default HandoffComponent;
|
||||
|
||||
HandoffComponent.propTypes = {
|
||||
url: PropTypes.string,
|
||||
};
|
|
@ -1,5 +1,21 @@
|
|||
const HandoffComponent = () => {
|
||||
return null;
|
||||
import React, { useContext } from 'react';
|
||||
import Handoff from 'react-native-handoff';
|
||||
import { BlueStorageContext } from '../blue_modules/storage-context';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const HandoffComponent = props => {
|
||||
const { isHandOffUseEnabled } = useContext(BlueStorageContext);
|
||||
|
||||
return isHandOffUseEnabled ? <Handoff {...props} /> : null;
|
||||
};
|
||||
export default HandoffComponent;
|
||||
|
||||
HandoffComponent.propTypes = {
|
||||
url: PropTypes.string,
|
||||
};
|
||||
|
||||
export default HandoffComponent;
|
||||
HandoffComponent.activityTypes = {
|
||||
ReceiveOnchain: 'io.bluewallet.bluewallet.receiveonchain',
|
||||
Xpub: 'io.bluewallet.bluewallet.xpub',
|
||||
ViewInBlockExplorer: 'io.bluewallet.bluewallet.blockexplorer',
|
||||
};
|
||||
|
|
|
@ -83,6 +83,21 @@ static void InitializeFlipper(UIApplication *application) {
|
|||
}
|
||||
|
||||
|
||||
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
|
||||
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
|
||||
{
|
||||
|
||||
if (userActivity.activityType == NSUserActivityTypeBrowsingWeb) {
|
||||
return [RCTLinkingManager application:application
|
||||
continueUserActivity:userActivity
|
||||
restorationHandler:restorationHandler];
|
||||
}
|
||||
else {
|
||||
[EventEmitter.sharedInstance sendUserActivity:@{@"activityType": userActivity.activityType, @"userInfo": userActivity.userInfo}];
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
return [RCTLinkingManager application:app openURL:url options:options];
|
||||
}
|
||||
|
|
|
@ -91,6 +91,11 @@
|
|||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>NSUserActivityTypes</key>
|
||||
<array>
|
||||
<string>io.bluewallet.bluewallet.receiveonchain</string>
|
||||
<string>io.bluewallet.bluewallet.xpub</string>
|
||||
</array>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
|
|
|
@ -14,5 +14,6 @@
|
|||
+ (EventEmitter *)sharedInstance;
|
||||
- (void)sendNotification:(NSDictionary *)userInfo;
|
||||
- (void)openSettings;
|
||||
- (void)sendUserActivity:(NSDictionary *)userInfo;
|
||||
|
||||
@end
|
||||
|
|
|
@ -29,7 +29,7 @@ RCT_EXPORT_MODULE();
|
|||
}
|
||||
|
||||
- (NSArray<NSString *> *)supportedEvents {
|
||||
return @[@"onNotificationReceived",@"openSettings"];
|
||||
return @[@"onNotificationReceived",@"openSettings",@"onUserActivityOpen"];
|
||||
}
|
||||
|
||||
- (void)sendNotification:(NSDictionary *)userInfo
|
||||
|
@ -37,6 +37,11 @@ RCT_EXPORT_MODULE();
|
|||
[sharedInstance sendEventWithName:@"onNotificationReceived" body:userInfo];
|
||||
}
|
||||
|
||||
- (void)sendUserActivity:(NSDictionary *)userInfo
|
||||
{
|
||||
[sharedInstance sendEventWithName:@"onUserActivityOpen" body:userInfo];
|
||||
}
|
||||
|
||||
|
||||
- (void)openSettings
|
||||
{
|
||||
|
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -19803,8 +19803,8 @@
|
|||
}
|
||||
},
|
||||
"react-native-handoff": {
|
||||
"version": "git+https://github.com/marcosrdz/react-native-handoff.git#f5becc63f3e36bf2da1ed1fc60fc690323e73602",
|
||||
"from": "git+https://github.com/marcosrdz/react-native-handoff.git#f5becc63f3e36bf2da1ed1fc60fc690323e73602"
|
||||
"version": "git+https://github.com/BlueWallet/react-native-handoff.git#31d005f93d31099d0e564590a3bbd052b8a02b39",
|
||||
"from": "git+https://github.com/BlueWallet/react-native-handoff.git#31d005f93d31099d0e564590a3bbd052b8a02b39"
|
||||
},
|
||||
"react-native-haptic-feedback": {
|
||||
"version": "git+https://github.com/junina-de/react-native-haptic-feedback.git#8e4d598ad9be886325316b0e2140df8df624a91f",
|
||||
|
|
|
@ -152,7 +152,7 @@
|
|||
"react-native-fingerprint-scanner": "https://github.com/BlueWallet/react-native-fingerprint-scanner#ce644673681716335d786727bab998f7e632ab5e",
|
||||
"react-native-fs": "2.18.0",
|
||||
"react-native-gesture-handler": "1.10.3",
|
||||
"react-native-handoff": "https://github.com/marcosrdz/react-native-handoff#f5becc63f3e36bf2da1ed1fc60fc690323e73602",
|
||||
"react-native-handoff": "https://github.com/BlueWallet/react-native-handoff#31d005f93d31099d0e564590a3bbd052b8a02b39",
|
||||
"react-native-haptic-feedback": "https://github.com/junina-de/react-native-haptic-feedback.git#8e4d598ad9be886325316b0e2140df8df624a91f",
|
||||
"react-native-idle-timer": "https://github.com/BlueWallet/react-native-idle-timer#8587876d68ab5920e79619726aeca9e672beaf2b",
|
||||
"react-native-image-picker": "4.1.1",
|
||||
|
|
|
@ -407,6 +407,8 @@ const ReceiveDetails = () => {
|
|||
} else {
|
||||
obtainWalletAddress();
|
||||
}
|
||||
} else if (!wallet && address) {
|
||||
setAddressBIP21Encoded(address);
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
|
@ -507,9 +509,9 @@ const ReceiveDetails = () => {
|
|||
<StatusBar barStyle="light-content" />
|
||||
{address !== undefined && showAddress && (
|
||||
<HandoffComponent
|
||||
title={`Bitcoin Transaction ${address}`}
|
||||
type="io.bluewallet.bluewallet"
|
||||
url={`https://blockstream.info/address/${address}`}
|
||||
title={loc.send.details_address}
|
||||
type={HandoffComponent.activityTypes.ReceiveOnchain}
|
||||
userInfo={{ address: address }}
|
||||
/>
|
||||
)}
|
||||
{showConfirmedBalance ? renderConfirmedBalance() : null}
|
||||
|
|
|
@ -129,9 +129,9 @@ const TransactionsDetails = () => {
|
|||
return (
|
||||
<SafeBlueArea>
|
||||
<HandoffComponent
|
||||
title={`Bitcoin Transaction ${tx.hash}`}
|
||||
type="io.bluewallet.bluewallet"
|
||||
url={`https://blockstream.info/tx/${tx.hash}`}
|
||||
title={loc.transactions.details_title}
|
||||
type={HandoffComponent.activityTypes.ViewInBlockExplorer}
|
||||
url={`https://mempool.space/tx/${tx.hash}`}
|
||||
/>
|
||||
<StatusBar barStyle="default" />
|
||||
<ScrollView style={styles.scroll}>
|
||||
|
|
|
@ -369,9 +369,9 @@ const TransactionsStatus = () => {
|
|||
return (
|
||||
<SafeBlueArea>
|
||||
<HandoffComponent
|
||||
title={`Bitcoin Transaction ${tx.hash}`}
|
||||
type="io.bluewallet.bluewallet"
|
||||
url={`https://blockstream.info/tx/${tx.hash}`}
|
||||
title={loc.transactions.details_title}
|
||||
type={HandoffComponent.activityTypes.ViewInBlockExplorer}
|
||||
url={`https://mempool.space/tx/${tx.hash}`}
|
||||
/>
|
||||
|
||||
<StatusBar barStyle="default" />
|
||||
|
|
|
@ -25,7 +25,6 @@ import { BlueAlertWalletExportReminder } from '../../BlueComponents';
|
|||
import WalletGradient from '../../class/wallet-gradient';
|
||||
import navigationStyle from '../../components/navigationStyle';
|
||||
import { LightningCustodianWallet, LightningLdkWallet, MultisigHDWallet, WatchOnlyWallet } from '../../class';
|
||||
import HandoffComponent from '../../components/handoff';
|
||||
import ActionSheet from '../ActionSheet';
|
||||
import loc from '../../loc';
|
||||
import { FContainer, FButton } from '../../components/FloatButtons';
|
||||
|
@ -560,13 +559,6 @@ const WalletTransactions = () => {
|
|||
return (
|
||||
<View style={styles.flex}>
|
||||
<StatusBar barStyle="light-content" backgroundColor={WalletGradient.headerColorFor(wallet.type)} animated />
|
||||
{wallet.chain === Chain.ONCHAIN && wallet.type !== MultisigHDWallet.type && (
|
||||
<HandoffComponent
|
||||
title={`Bitcoin Wallet ${wallet.getLabel()}`}
|
||||
type="io.bluewallet.bluewallet"
|
||||
url={`https://blockpath.com/search/addr?q=${wallet.getXpub()}`}
|
||||
/>
|
||||
)}
|
||||
<TransactionsNavigationHeader
|
||||
wallet={wallet}
|
||||
onWalletUnitChange={passedWallet =>
|
||||
|
|
|
@ -8,6 +8,7 @@ import Biometric from '../../class/biometrics';
|
|||
import loc from '../../loc';
|
||||
import { BlueStorageContext } from '../../blue_modules/storage-context';
|
||||
import QRCodeComponent from '../../components/QRCodeComponent';
|
||||
import HandoffComponent from '../../components/handoff';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
root: {
|
||||
|
@ -23,12 +24,11 @@ const styles = StyleSheet.create({
|
|||
|
||||
const WalletXpub = () => {
|
||||
const { wallets } = useContext(BlueStorageContext);
|
||||
const { walletID } = useRoute().params;
|
||||
const { walletID, xPub } = useRoute().params;
|
||||
const wallet = wallets.find(w => w.getID() === walletID);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [xPub, setXPub] = useState();
|
||||
const [xPubText, setXPubText] = useState();
|
||||
const { goBack } = useNavigation();
|
||||
const { goBack, setParams } = useNavigation();
|
||||
const { colors } = useTheme();
|
||||
const [qrCodeSize, setQRCodeSize] = useState(90);
|
||||
const stylesHook = StyleSheet.create({ root: { backgroundColor: colors.elevated } });
|
||||
|
@ -45,9 +45,12 @@ const WalletXpub = () => {
|
|||
return goBack();
|
||||
}
|
||||
}
|
||||
setXPub(wallet.getXpub());
|
||||
setParams({ xPub: wallet.getXpub() });
|
||||
setXPubText(wallet.getXpub());
|
||||
setIsLoading(false);
|
||||
} else if (xPub) {
|
||||
setXPubText(xPub);
|
||||
setIsLoading(false);
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
|
@ -55,7 +58,7 @@ const WalletXpub = () => {
|
|||
Privacy.disableBlur();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [goBack, walletID]),
|
||||
}, [goBack, walletID, xPub]),
|
||||
);
|
||||
|
||||
const onLayout = e => {
|
||||
|
@ -71,15 +74,19 @@ const WalletXpub = () => {
|
|||
<SafeBlueArea style={[styles.root, stylesHook.root]} onLayout={onLayout}>
|
||||
<StatusBar barStyle="light-content" />
|
||||
<View style={styles.container}>
|
||||
<View>
|
||||
<BlueText>{wallet.typeReadable}</BlueText>
|
||||
</View>
|
||||
<BlueSpacing20 />
|
||||
|
||||
{wallet && (
|
||||
<>
|
||||
<View>
|
||||
<BlueText>{wallet.typeReadable}</BlueText>
|
||||
</View>
|
||||
<BlueSpacing20 />
|
||||
</>
|
||||
)}
|
||||
<QRCodeComponent value={xPub} size={qrCodeSize} />
|
||||
|
||||
<BlueSpacing20 />
|
||||
<BlueCopyTextToClipboard text={xPubText} />
|
||||
<HandoffComponent title={loc.wallets.xpub_title} type={HandoffComponent.activityTypes.Xpub} userInfo={{ xpub: xPubText }} />
|
||||
</View>
|
||||
</SafeBlueArea>
|
||||
);
|
||||
|
|
Loading…
Add table
Reference in a new issue