Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

REF: Haptic feedback into a class with power state verification #5954

Merged
merged 5 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions App.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
} from 'react-native';
import { NavigationContainer, CommonActions } from '@react-navigation/native';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { navigationRef } from './NavigationService';
import * as NavigationService from './NavigationService';
import { Chain } from './models/bitcoinUnits';
Expand All @@ -32,6 +31,7 @@ import WidgetCommunication from './blue_modules/WidgetCommunication';
import ActionSheet from './screen/ActionSheet';
import HandoffComponent from './components/handoff';
import Privacy from './blue_modules/Privacy';
import triggerHapticFeedback, { HapticFeedbackTypes } from './class/hapticFeedback';
const A = require('./blue_modules/analytics');
const currency = require('./blue_modules/currency');

Expand Down Expand Up @@ -260,7 +260,7 @@ const App = () => {
};

const showClipboardAlert = ({ contentType }) => {
ReactNativeHapticFeedback.trigger('impactLight', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.ImpactLight);
BlueClipboard()
.getClipboardContent()
.then(clipboard => {
Expand Down
5 changes: 3 additions & 2 deletions UnlockWith.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import LottieView from 'lottie-react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { StackActions, useNavigation, useRoute } from '@react-navigation/native';
import { BlueStorageContext } from './blue_modules/storage-context';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { isHandset } from './blue_modules/environment';
import triggerHapticFeedback from './class/hapticFeedback';
const lottieJson = require('./img/bluewalletsplash.json');

const styles = StyleSheet.create({
Expand Down Expand Up @@ -86,7 +86,8 @@ const UnlockWith = () => {
const unlockWithKey = async () => {
setIsAuthenticating(true);
if (await startAndDecrypt()) {
ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback({ type: 'notificationSuccess' });
marcosrdz marked this conversation as resolved.
Show resolved Hide resolved

successfullyAuthenticated();
} else {
setIsAuthenticating(false);
Expand Down
11 changes: 11 additions & 0 deletions android/.settings/org.eclipse.buildship.core.prefs
Original file line number Diff line number Diff line change
@@ -1,2 +1,13 @@
arguments=
marcosrdz marked this conversation as resolved.
Show resolved Hide resolved
auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
connection.project.dir=
eclipse.preferences.version=1
gradle.user.home=
java.home=
jvm.arguments=
offline.mode=false
override.workspace.settings=false
show.console.view=false
show.executions.view=false
6 changes: 3 additions & 3 deletions blue_modules/storage-context.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { createContext, useEffect, useState } from 'react';
import { Alert } from 'react-native';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { useAsyncStorage } from '@react-native-async-storage/async-storage';
import { FiatUnit } from '../models/fiatUnit';
import Notifications from '../blue_modules/notifications';
import loc, { STORAGE_KEY as LOC_STORAGE_KEY } from '../loc';
import { LegacyWallet, WatchOnlyWallet } from '../class';
import alert from '../components/Alert';
import triggerHapticFeedback from '../class/hapticFeedback';
const BlueApp = require('../BlueApp');
const BlueElectrum = require('./BlueElectrum');
const currency = require('../blue_modules/currency');
Expand Down Expand Up @@ -177,12 +177,12 @@ export const BlueStorageProvider = ({ children }) => {

const addAndSaveWallet = async w => {
if (wallets.some(i => i.getID() === w.getID())) {
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback('notificationError');
Alert.alert('', 'This wallet has been previously imported.');
return;
}
const emptyWalletLabel = new LegacyWallet().getLabel();
ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback('notificationSuccess');
marcosrdz marked this conversation as resolved.
Show resolved Hide resolved
if (w.getLabel() === emptyWalletLabel) w.setLabel(loc.wallets.import_imported + ' ' + w.typeReadable);
w.setUserHasSavedExport(true);
addWallet(w);
Expand Down
25 changes: 25 additions & 0 deletions class/hapticFeedback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import DeviceInfo, { PowerState } from 'react-native-device-info';

// Define a const enum for HapticFeedbackTypes
export const enum HapticFeedbackTypes {
ImpactLight = 'impactLight',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iirc you dont need to specify string values to each enum for TS

ImpactMedium = 'impactMedium',
ImpactHeavy = 'impactHeavy',
Selection = 'selection',
NotificationSuccess = 'notificationSuccess',
NotificationWarning = 'notificationWarning',
NotificationError = 'notificationError'

Check warning on line 12 in class/hapticFeedback.ts

View workflow job for this annotation

GitHub Actions / test

Insert `,`
}

const triggerHapticFeedback = (type: HapticFeedbackTypes) => {
marcosrdz marked this conversation as resolved.
Show resolved Hide resolved
DeviceInfo.getPowerState().then((state: Partial<PowerState>) => {
if (!state.lowPowerMode) {
ReactNativeHapticFeedback.trigger(type, { ignoreAndroidSystemSettings: false, enableVibrateFallback: true });
} else {
console.log('Haptic feedback not triggered due to low power mode.');
}
});
};

export default triggerHapticFeedback;
4 changes: 2 additions & 2 deletions class/payjoin-transaction.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as bitcoin from 'bitcoinjs-lib';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import alert from '../components/Alert';
import { ECPairFactory } from 'ecpair';
import ecc from '../blue_modules/noble_ecc';
import triggerHapticFeedback from './hapticFeedback';
const ECPair = ECPairFactory(ecc);

const delay = milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds));
Expand Down Expand Up @@ -74,7 +74,7 @@ export default class PayjoinTransaction {
const result = await this.broadcastTx(txHex);
if (result === '') {
// TODO: Improve the wording of this error message
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback('notificationError');
marcosrdz marked this conversation as resolved.
Show resolved Hide resolved
alert('Something was wrong with the payjoin transaction, the original transaction sucessfully broadcast.');
}
});
Expand Down
18 changes: 9 additions & 9 deletions screen/lnd/ldkOpenChannel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import AddressInput from '../../components/AddressInput';
import AmountInput from '../../components/AmountInput';
import { BitcoinUnit } from '../../models/bitcoinUnits';
import loc from '../../loc';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { AbstractWallet, HDSegwitBech32Wallet, LightningLdkWallet } from '../../class';
import { ArrowPicker } from '../../components/ArrowPicker';
import { Psbt } from 'bitcoinjs-lib';
import Biometric from '../../class/biometrics';
import alert from '../../components/Alert';
import { useTheme } from '../../components/themes';
import Button from '../../components/Button';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../class/hapticFeedback';
const currency = require('../../blue_modules/currency');

type LdkOpenChannelProps = RouteProp<
Expand Down Expand Up @@ -67,7 +67,7 @@ const LdkOpenChannel = (props: any) => {
(async () => {
if (psbtOpenChannelStartedTs.current ? +new Date() - psbtOpenChannelStartedTs.current >= 5 * 60 * 1000 : false) {
// its 10 min actually, but lets check 5 min just for any case
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
return alert('Channel opening expired. Please try again');
}

Expand All @@ -93,7 +93,7 @@ const LdkOpenChannel = (props: any) => {
}
if (psbtOpenChannelStartedTs.current ? +new Date() - psbtOpenChannelStartedTs.current >= 5 * 60 * 1000 : false) {
// its 10 min actually, but lets check 5 min just for any case
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
setIsLoading(false);
return alert('Channel opening expired. Please try again');
}
Expand All @@ -102,14 +102,14 @@ const LdkOpenChannel = (props: any) => {
const res = await ldkWallet.fundingStateStepFinalize(tx.toHex()); // comment this out to debug
// const res = true; // debug
if (!res) {
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
setIsLoading(false);
return alert('Something wend wrong during opening channel tx broadcast');
}
fetchAndSaveWalletTransactions(ldkWallet.getID());
await new Promise(resolve => setTimeout(resolve, 3000)); // sleep to make sure network propagates
fetchAndSaveWalletTransactions(fundingWalletID);
ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
// @ts-ignore: Address types later
navigate('Success', { amount: undefined });
setIsLoading(false);
Expand All @@ -120,14 +120,14 @@ const LdkOpenChannel = (props: any) => {
try {
const amountSatsNumber = new BigNumber(fundingAmount.amountSats).toNumber();
if (!amountSatsNumber) {
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
return alert('Amount is not valid');
}

const pubkey = remoteHostWithPubkey.split('@')[0];
const host = remoteHostWithPubkey.split('@')[1];
if (!pubkey || !host) {
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
return alert('Remote node address is not valid');
}

Expand All @@ -141,7 +141,7 @@ const LdkOpenChannel = (props: any) => {
if (event) {
reason += event.reason + ' ' + event.text;
}
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
return alert('Initiating channel open failed: ' + reason);
}

Expand All @@ -162,7 +162,7 @@ const LdkOpenChannel = (props: any) => {
},
});
} catch (error: any) {
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
alert(error.message);
} finally {
setIsLoading(false);
Expand Down
14 changes: 7 additions & 7 deletions screen/lnd/lndCreateInvoice.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
View,
I18nManager,
} from 'react-native';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { Icon } from 'react-native-elements';
import { useFocusEffect, useNavigation, useRoute } from '@react-navigation/native';

Expand All @@ -31,6 +30,7 @@ import { parse } from 'url'; // eslint-disable-line n/no-deprecated-api
import { requestCameraAuthorization } from '../../helpers/scan-qr';
import { useTheme } from '../../components/themes';
import Button from '../../components/Button';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../class/hapticFeedback';
const currency = require('../../blue_modules/currency');

const LNDCreateInvoice = () => {
Expand Down Expand Up @@ -131,7 +131,7 @@ const LNDCreateInvoice = () => {
});
}
} else {
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
alert(loc.wallets.add_ln_wallet_first);
goBack();
}
Expand Down Expand Up @@ -179,15 +179,15 @@ const LNDCreateInvoice = () => {
? loc.formatString(loc.receive.maxSats, { max })
: loc.formatString(loc.receive.maxSatsFull, { max, currency: formatBalance(max, unit) });
}
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
alert(text);
setIsLoading(false);
return;
}
}

const invoiceRequest = await wallet.current.addInvoice(invoiceAmount, description);
ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);

// lets decode payreq and subscribe groundcontrol so we can receive push notification when our invoice is paid
/** @type LightningCustodianWallet */
Expand Down Expand Up @@ -223,7 +223,7 @@ const LNDCreateInvoice = () => {
walletID: wallet.current.getID(),
});
} catch (Err) {
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
setIsLoading(false);
alert(Err.message);
}
Expand All @@ -232,7 +232,7 @@ const LNDCreateInvoice = () => {
const processLnurl = async data => {
setIsLoading(true);
if (!wallet.current) {
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
alert(loc.wallets.no_ln_wallet_error);
return goBack();
}
Expand Down Expand Up @@ -307,7 +307,7 @@ const LNDCreateInvoice = () => {
} catch (Err) {
Keyboard.dismiss();
setIsLoading(false);
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
alert(Err.message);
}
};
Expand Down
6 changes: 3 additions & 3 deletions screen/lnd/lndViewInvoice.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useContext, useEffect, useRef, useState } from 'react';
import { View, Text, ScrollView, BackHandler, TouchableOpacity, StyleSheet, I18nManager, Image } from 'react-native';
import Share from 'react-native-share';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { Icon } from 'react-native-elements';
import QRCodeComponent from '../../components/QRCodeComponent';
import { useNavigation, useNavigationState, useRoute } from '@react-navigation/native';
Expand All @@ -14,6 +13,7 @@ import { SuccessView } from '../send/success';
import LNDCreateInvoice from './lndCreateInvoice';
import { useTheme } from '../../components/themes';
import Button from '../../components/Button';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../class/hapticFeedback';

const LNDViewInvoice = () => {
const { invoice, walletID } = useRoute().params;
Expand Down Expand Up @@ -129,7 +129,7 @@ const LNDViewInvoice = () => {
// invoice expired :-(
fetchAndSaveWalletTransactions(walletID);
setIsFetchingInvoices(false);
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
clearInterval(fetchInvoiceInterval.current);
fetchInvoiceInterval.current = undefined;
}
Expand Down Expand Up @@ -177,7 +177,7 @@ const LNDViewInvoice = () => {

useEffect(() => {
if (invoiceStatusChanged) {
ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
}
}, [invoiceStatusChanged]);

Expand Down
6 changes: 3 additions & 3 deletions screen/lnd/lnurlPay.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useState, useEffect, useContext } from 'react';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { I18nManager, Image, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { useNavigation, useRoute } from '@react-navigation/native';
Expand All @@ -16,6 +15,7 @@ import { BlueStorageContext } from '../../blue_modules/storage-context';
import alert from '../../components/Alert';
import { useTheme } from '../../components/themes';
import Button from '../../components/Button';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../class/hapticFeedback';
const prompt = require('../../helpers/prompt');
const currency = require('../../blue_modules/currency');

Expand Down Expand Up @@ -143,7 +143,7 @@ const LnurlPay = () => {
setPayButtonDisabled(false);

// success, probably
ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
if (wallet.last_paid_invoice_result && wallet.last_paid_invoice_result.payment_preimage) {
await LN.storeSuccess(decoded.payment_hash, wallet.last_paid_invoice_result.payment_preimage);
}
Expand All @@ -161,7 +161,7 @@ const LnurlPay = () => {
console.log(Err.message);
setIsLoading(false);
setPayButtonDisabled(false);
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
return alert(Err.message);
}
};
Expand Down