ADD: Copying Block Explorer Link #2597

This commit is contained in:
marcosrdz 2021-02-10 00:18:40 -05:00
parent 3601c566fc
commit 459d2155e0
6 changed files with 148 additions and 89 deletions

View File

@ -29,9 +29,7 @@ import { LightningCustodianWallet, MultisigHDWallet } from './class';
import { BitcoinUnit } from './models/bitcoinUnits';
import * as NavigationService from './NavigationService';
import WalletGradient from './class/wallet-gradient';
import ToolTip from 'react-native-tooltip';
import { BlurView } from '@react-native-community/blur';
import showPopupMenu from 'react-native-popup-menu-android';
import NetworkTransactionFees, { NetworkTransactionFee, NetworkTransactionFeeType } from './models/networkTransactionFees';
import Biometric from './class/biometrics';
import { getSystemName } from 'react-native-device-info';
@ -43,6 +41,7 @@ import { BlueCurrentTheme } from './components/themes';
import loc, { formatBalance, formatBalanceWithoutSuffix, formatBalancePlain, removeTrailingZeros, transactionTimeToReadable } from './loc';
import Lnurl from './class/lnurl';
import { BlueStorageContext } from './blue_modules/storage-context';
import ToolTipMenu from './components/TooltipMenu';
/** @type {AppStorage} */
const { height, width } = Dimensions.get('window');
const aspectRatio = height / width;
@ -232,7 +231,7 @@ export class BlueWalletNavigationHeader extends Component {
static contextType = BlueStorageContext;
walletBalanceText = React.createRef();
tooltip = React.createRef();
constructor(props) {
super(props);
this.state = {
@ -271,45 +270,6 @@ export class BlueWalletNavigationHeader extends Component {
await this.context.saveToDisk();
};
showAndroidTooltip = () => {
showPopupMenu(this.toolTipMenuOptions(), this.handleToolTipSelection, this.walletBalanceText.current);
};
handleToolTipSelection = item => {
if (item === 'balanceCopy' || item.id === 'balanceCopy') {
this.handleCopyPress();
} else if (item === 'balancePrivacy' || item.id === 'balancePrivacy') {
this.handleBalanceVisibility();
}
};
toolTipMenuOptions() {
return Platform.select({
// NOT WORKING ATM.
// ios: [
// { text: this.state.wallet.hideBalance ? loc.transactions.details_balance_show : loc.transactions.details_balance_hide, onPress: this.handleBalanceVisibility },
// { text: loc.transactions.details_copy, onPress: this.handleCopyPress },
// ],
android: this.state.wallet.hideBalance
? [
{
id: 'balancePrivacy',
label: this.state.wallet.hideBalance ? loc.transactions.details_balance_show : loc.transactions.details_balance_hide,
},
]
: [
{
id: 'balancePrivacy',
label: this.state.wallet.hideBalance ? loc.transactions.details_balance_show : loc.transactions.details_balance_hide,
},
{
id: 'balanceCopy',
label: loc.transactions.details_copy,
},
],
});
}
changeWalletBalanceUnit = () => {
let walletPreviousPreferredUnit = this.state.wallet.getPreferredBalanceUnit();
const wallet = this.state.wallet;
@ -336,6 +296,19 @@ export class BlueWalletNavigationHeader extends Component {
this.props.onManageFundsPressed();
};
showToolTipMenu = () => {
this.tooltip.current.showMenu();
};
handleToolTipOnPress = item => {
console.warn(item);
if (item === 'copyToClipboard') {
this.handleCopyPress();
} else if (item === 'walletBalanceVisibility') {
this.handleBalanceVisibility();
}
};
render() {
return (
<LinearGradient
@ -362,7 +335,6 @@ export class BlueWalletNavigationHeader extends Component {
right: 0,
}}
/>
<Text
numberOfLines={1}
style={{
@ -373,35 +345,38 @@ export class BlueWalletNavigationHeader extends Component {
>
{this.state.wallet.getLabel()}
</Text>
{Platform.OS === 'ios' && (
<ToolTip
ref={tooltip => (this.tooltip = tooltip)}
actions={
this.state.wallet.hideBalance
? [
{
text: this.state.wallet.hideBalance ? loc.transactions.details_balance_show : loc.transactions.details_balance_hide,
onPress: this.handleBalanceVisibility,
},
]
: [
{
text: this.state.wallet.hideBalance ? loc.transactions.details_balance_show : loc.transactions.details_balance_hide,
onPress: this.handleBalanceVisibility,
},
{
text: loc.transactions.details_copy,
onPress: this.handleCopyPress,
},
]
}
/>
)}
<ToolTipMenu
ref={this.tooltip}
anchorRef={this.walletBalanceText}
actions={
this.state.wallet.hideBalance
? [
{
id: 'walletBalanceVisibility',
text: this.state.wallet.hideBalance ? loc.transactions.details_balance_show : loc.transactions.details_balance_hide,
onPress: this.handleBalanceVisibility,
},
]
: [
{
id: 'walletBalanceVisibility',
text: this.state.wallet.hideBalance ? loc.transactions.details_balance_show : loc.transactions.details_balance_hide,
onPress: this.handleBalanceVisibility,
},
{
id: 'copyToClipboard',
text: loc.transactions.details_copy,
onPress: () => this.handleCopyPress,
},
]
}
onPress={this.handleToolTipOnPress}
/>
<TouchableOpacity
style={styles.balance}
onPress={this.changeWalletBalanceUnit}
ref={this.walletBalanceText}
onLongPress={() => (Platform.OS === 'ios' ? this.tooltip.showMenu() : this.showAndroidTooltip())}
onLongPress={this.showToolTipMenu}
>
{this.state.wallet.hideBalance ? (
<BluePrivateBalance />

View File

@ -0,0 +1,37 @@
import React, { forwardRef, useEffect } from 'react';
import PropTypes from 'prop-types';
import { View } from 'react-native';
import showPopupMenu from 'react-native-popup-menu-android';
export const ToolTipAction = { text: '', onPress: () => {}, id: '' };
ToolTipAction.propTypes = {
text: PropTypes.string.isRequired,
onPress: PropTypes.func.isRequired,
id: PropTypes.string,
};
const ToolTipMenu = (props, ref) => {
const handleToolTipSelection = selection => {
props.onPress(selection.id);
};
const showMenu = () => {
const actions = props.actions.map(action => ({ id: action.id, label: action.text }));
showPopupMenu(actions, handleToolTipSelection, props.anchorRef.current);
};
useEffect(() => {
ref.current.showMenu = showMenu;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [ref]);
return <View ref={ref}>{props.children}</View>;
};
export default forwardRef(ToolTipMenu);
ToolTipMenu.propTypes = {
actions: PropTypes.arrayOf(PropTypes.shape).isRequired,
anchorRef: PropTypes.node,
children: PropTypes.node,
onPress: PropTypes.func.isRequired,
};

View File

@ -0,0 +1,24 @@
import React, { useRef, forwardRef, useEffect } from 'react';
import ToolTip from 'react-native-tooltip';
import PropTypes from 'prop-types';
import { View } from 'react-native';
const ToolTipMenu = (props, ref) => {
const toolTip = useRef(null);
const showMenu = () => {
console.log('Showing ToolTip');
toolTip.current?.showMenu();
};
useEffect(() => {
ref.current.showMenu = showMenu;
}, [ref]);
return <View ref={ref}>{ref.current && <ToolTip ref={toolTip} actions={props.actions} />}</View>;
};
export default forwardRef(ToolTipMenu);
ToolTipMenu.propTypes = {
actions: PropTypes.arrayOf(PropTypes.shape).isRequired,
};

View File

@ -0,0 +1,8 @@
// eslint-disable-next-line no-unused-vars
import React, { forwardRef } from 'react';
const ToolTipMenu = (props, ref) => {
return props.children;
};
export default forwardRef(ToolTipMenu);

View File

@ -65,10 +65,8 @@
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "8"
notificationPayloadFile = "BlueWalletWatch Extension/PushNotificationPayload.apns">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/BlueWallet">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B40D4E2F225841EC00428FCC"
@ -76,7 +74,7 @@
BlueprintName = "BlueWalletWatch"
ReferencedContainer = "container:BlueWallet.xcodeproj">
</BuildableReference>
</RemoteRunnable>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
@ -86,10 +84,8 @@
debugDocumentVersioning = "YES"
launchAutomaticallySubstyle = "8"
notificationPayloadFile = "BlueWalletWatch Extension/PushNotificationPayload.apns">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/BlueWallet">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B40D4E2F225841EC00428FCC"
@ -97,16 +93,7 @@
BlueprintName = "BlueWalletWatch"
ReferencedContainer = "container:BlueWallet.xcodeproj">
</BuildableReference>
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B40D4E2F225841EC00428FCC"
BuildableName = "BlueWalletWatch.app"
BlueprintName = "BlueWalletWatch"
ReferencedContainer = "container:BlueWallet.xcodeproj">
</BuildableReference>
</MacroExpansion>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">

View File

@ -1,5 +1,5 @@
/* global alert */
import React, { useContext, useEffect, useState } from 'react';
import React, { useContext, useEffect, useRef, useState } from 'react';
import { View, ScrollView, TouchableOpacity, Text, TextInput, Linking, StatusBar, StyleSheet, Keyboard } from 'react-native';
import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
import { BlueCard, BlueCopyToClipboardButton, BlueLoading, BlueSpacing20, BlueText, SafeBlueArea } from '../../BlueComponents';
@ -7,6 +7,8 @@ import navigationStyle from '../../components/navigationStyle';
import HandoffComponent from '../../components/handoff';
import loc from '../../loc';
import { BlueStorageContext } from '../../blue_modules/storage-context';
import Clipboard from '@react-native-community/clipboard';
import ToolTipMenu from '../../components/TooltipMenu';
const dayjs = require('dayjs');
function onlyUnique(value, index, self) {
@ -33,6 +35,8 @@ const TransactionsDetails = () => {
const [tx, setTX] = useState();
const [memo, setMemo] = useState();
const { colors } = useTheme();
const openTransactionOnBlockExplorerRef = useRef();
const toolTip = useRef();
const stylesHooks = StyleSheet.create({
rowCaption: {
color: colors.foregroundColor,
@ -123,6 +127,14 @@ const TransactionsDetails = () => {
});
};
const handleCopyPress = () => {
Clipboard.setString(`https://blockstream.info/tx/${tx.hash}`);
};
const showToolTipMenu = () => {
toolTip.current.showMenu();
};
if (isLoading || !tx) {
return <BlueLoading />;
}
@ -182,7 +194,23 @@ const TransactionsDetails = () => {
<BlueCopyToClipboardButton stringToCopy={tx.hash} />
</View>
<BlueText style={styles.txHash}>{tx.hash}</BlueText>
<TouchableOpacity onPress={handleOnOpenTransactionOnBlockExporerTapped}>
<ToolTipMenu
ref={toolTip}
anchorRef={openTransactionOnBlockExplorerRef}
actions={[
{
id: 'copyToClipboard',
text: loc.transactions.details_copy,
onPress: handleCopyPress,
},
]}
onPress={handleCopyPress}
/>
<TouchableOpacity
ref={openTransactionOnBlockExplorerRef}
onPress={handleOnOpenTransactionOnBlockExporerTapped}
onLongPress={showToolTipMenu}
>
<BlueText style={[styles.txLink, stylesHooks.txLink]}>{loc.transactions.details_show_in_block_explorer}</BlueText>
</TouchableOpacity>
</>