mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2024-11-19 01:40:12 +01:00
Merge branch 'master' into limpbrains-multisig-passphrase
This commit is contained in:
commit
de8c46da17
2
.bundle/config
Normal file
2
.bundle/config
Normal file
@ -0,0 +1,2 @@
|
||||
BUNDLE_PATH: "vendor/bundle"
|
||||
BUNDLE_FORCE_RUBY_PLATFORM: 1
|
@ -18,6 +18,8 @@
|
||||
"react/jsx-handler-names": "off", // activated by standard-react config
|
||||
"react/display-name": "off",
|
||||
"react-native/no-inline-styles": "error",
|
||||
"react-native/no-unused-styles": "error",
|
||||
"react-native/no-single-element-style-arrays": "error",
|
||||
"prettier/prettier": [
|
||||
"warn",
|
||||
{
|
||||
|
5
.gitattributes
vendored
5
.gitattributes
vendored
@ -1,5 +0,0 @@
|
||||
*.pbxproj -text
|
||||
*.patch -text
|
||||
# Windows files should use crlf line endings
|
||||
# https://help.github.com/articles/dealing-with-line-endings/
|
||||
*.bat text eol=crlf
|
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -92,7 +92,7 @@ jobs:
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: 29
|
||||
emulator-build: 6110076 # tmp fix for https://github.com/ReactiveCircus/android-emulator-runner/issues/160
|
||||
emulator-build: 6885378 # tmp fix for https://github.com/ReactiveCircus/android-emulator-runner/issues/160
|
||||
target: google_apis
|
||||
avd-name: Pixel_API_29_AOSP
|
||||
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -camera-back none -camera-front none -partition-size 2047
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -20,6 +20,7 @@ DerivedData
|
||||
*.hmap
|
||||
*.ipa
|
||||
*.xcuserstate
|
||||
*.hprof
|
||||
|
||||
# Android/IntelliJ
|
||||
#
|
||||
|
1
.ruby-version
Normal file
1
.ruby-version
Normal file
@ -0,0 +1 @@
|
||||
2.7.4
|
38
App.js
38
App.js
@ -39,7 +39,7 @@ import Privacy from './blue_modules/Privacy';
|
||||
const A = require('./blue_modules/analytics');
|
||||
const currency = require('./blue_modules/currency');
|
||||
|
||||
const eventEmitter = new NativeEventEmitter(NativeModules.EventEmitter);
|
||||
const eventEmitter = Platform.OS === 'ios' ? new NativeEventEmitter(NativeModules.EventEmitter) : undefined;
|
||||
const { EventEmitter } = NativeModules;
|
||||
|
||||
const ClipboardContentType = Object.freeze({
|
||||
@ -54,9 +54,8 @@ if (Platform.OS === 'android') {
|
||||
}
|
||||
|
||||
const App = () => {
|
||||
const { walletsInitialized, wallets, addWallet, saveToDisk, fetchAndSaveWalletTransactions, refreshAllWalletTransactions } = useContext(
|
||||
BlueStorageContext,
|
||||
);
|
||||
const { walletsInitialized, wallets, addWallet, saveToDisk, fetchAndSaveWalletTransactions, refreshAllWalletTransactions } =
|
||||
useContext(BlueStorageContext);
|
||||
const appState = useRef(AppState.currentState);
|
||||
const clipboardContent = useRef();
|
||||
const colorScheme = useColorScheme();
|
||||
@ -114,9 +113,9 @@ const App = () => {
|
||||
return () => {
|
||||
Linking.removeEventListener('url', handleOpenURL);
|
||||
AppState.removeEventListener('change', handleAppStateChange);
|
||||
eventEmitter.removeAllListeners('onNotificationReceived');
|
||||
eventEmitter.removeAllListeners('openSettings');
|
||||
eventEmitter.removeAllListeners('onUserActivityOpen');
|
||||
eventEmitter?.removeAllListeners('onNotificationReceived');
|
||||
eventEmitter?.removeAllListeners('openSettings');
|
||||
eventEmitter?.removeAllListeners('onUserActivityOpen');
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
@ -145,9 +144,9 @@ const App = () => {
|
||||
When a notification on iOS is shown while the app is on foreground;
|
||||
On willPresent on AppDelegate.m
|
||||
*/
|
||||
eventEmitter.addListener('onNotificationReceived', onNotificationReceived);
|
||||
eventEmitter.addListener('openSettings', openSettings);
|
||||
eventEmitter.addListener('onUserActivityOpen', onUserActivityOpen);
|
||||
eventEmitter?.addListener('onNotificationReceived', onNotificationReceived);
|
||||
eventEmitter?.addListener('openSettings', openSettings);
|
||||
eventEmitter?.addListener('onUserActivityOpen', onUserActivityOpen);
|
||||
};
|
||||
|
||||
const popInitialAction = async data => {
|
||||
@ -387,25 +386,6 @@ const styles = StyleSheet.create({
|
||||
root: {
|
||||
flex: 1,
|
||||
},
|
||||
space: {
|
||||
marginHorizontal: 8,
|
||||
},
|
||||
modalContent: {
|
||||
padding: 22,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderTopLeftRadius: 16,
|
||||
borderTopRightRadius: 16,
|
||||
borderColor: 'rgba(0, 0, 0, 0.1)',
|
||||
minHeight: 200,
|
||||
height: 200,
|
||||
},
|
||||
modelContentButtonLayout: {
|
||||
flexDirection: 'row',
|
||||
margin: 16,
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'flex-end',
|
||||
},
|
||||
});
|
||||
|
||||
export default App;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* eslint react/prop-types: "off", react-native/no-inline-styles: "off" */
|
||||
import React, { Component, forwardRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Icon, Input, Text, Header, ListItem, Avatar } from 'react-native-elements';
|
||||
import { Icon, Text, Header, ListItem, Avatar } from 'react-native-elements';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Alert,
|
||||
@ -11,9 +11,7 @@ import {
|
||||
InputAccessoryView,
|
||||
Keyboard,
|
||||
KeyboardAvoidingView,
|
||||
PixelRatio,
|
||||
Platform,
|
||||
PlatformColor,
|
||||
SafeAreaView,
|
||||
StyleSheet,
|
||||
Switch,
|
||||
@ -28,6 +26,7 @@ import NetworkTransactionFees, { NetworkTransactionFee, NetworkTransactionFeeTyp
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { useTheme } from '@react-navigation/native';
|
||||
import { BlueCurrentTheme } from './components/themes';
|
||||
import PlusIcon from './components/icons/PlusIcon';
|
||||
import loc, { formatStringAddTwoWhiteSpaces } from './loc';
|
||||
|
||||
const { height, width } = Dimensions.get('window');
|
||||
@ -38,8 +37,6 @@ if (aspectRatio > 1.6) {
|
||||
} else {
|
||||
isIpad = true;
|
||||
}
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
Platform.OS === 'android' ? (ActivityIndicator.defaultProps.color = PlatformColor('?attr/colorControlActivated')) : null;
|
||||
|
||||
export const BlueButton = props => {
|
||||
const { colors } = useTheme();
|
||||
@ -389,6 +386,7 @@ export const BlueTextCentered = props => {
|
||||
const { colors } = useTheme();
|
||||
return <Text {...props} style={{ color: colors.foregroundColor, textAlign: 'center' }} />;
|
||||
};
|
||||
|
||||
export const BlueListItem = React.memo(props => {
|
||||
const { colors } = useTheme();
|
||||
|
||||
@ -472,24 +470,6 @@ export const BlueFormLabel = props => {
|
||||
);
|
||||
};
|
||||
|
||||
export const BlueFormInput = props => {
|
||||
const { colors } = useTheme();
|
||||
return (
|
||||
<Input
|
||||
{...props}
|
||||
inputStyle={{ color: colors.foregroundColor, maxWidth: width - 105 }}
|
||||
containerStyle={{
|
||||
marginTop: 5,
|
||||
borderColor: colors.inputBorderColor,
|
||||
borderBottomColor: colors.inputBorderColor,
|
||||
borderWidth: 0.5,
|
||||
borderBottomWidth: 0.5,
|
||||
backgroundColor: colors.inputBackgroundColor,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const BlueFormMultiInput = props => {
|
||||
const { colors } = useTheme();
|
||||
|
||||
@ -523,19 +503,6 @@ export const BlueFormMultiInput = props => {
|
||||
);
|
||||
};
|
||||
|
||||
export const BlueHeader = props => {
|
||||
return (
|
||||
<Header
|
||||
{...props}
|
||||
backgroundColor="transparent"
|
||||
outerContainerStyles={{
|
||||
borderBottomColor: 'transparent',
|
||||
borderBottomWidth: 0,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const BlueHeaderDefaultSub = props => {
|
||||
const { colors } = useTheme();
|
||||
|
||||
@ -592,7 +559,7 @@ export const BlueHeaderDefaultMain = props => {
|
||||
>
|
||||
{props.leftText}
|
||||
</Text>
|
||||
<BluePlusIcon onPress={props.onNewWalletPress} Component={TouchableOpacity} />
|
||||
<PlusIcon onPress={props.onNewWalletPress} Component={TouchableOpacity} />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
@ -605,14 +572,6 @@ export const BlueSpacing40 = props => {
|
||||
return <View {...props} style={{ height: 50 }} />;
|
||||
};
|
||||
|
||||
export const BlueSpacingVariable = props => {
|
||||
if (isIpad) {
|
||||
return <BlueSpacing40 {...props} />;
|
||||
} else {
|
||||
return <BlueSpacing {...props} />;
|
||||
}
|
||||
};
|
||||
|
||||
export class is {
|
||||
static ipad() {
|
||||
return isIpad;
|
||||
@ -690,299 +649,6 @@ export const BlueLoading = props => {
|
||||
);
|
||||
};
|
||||
|
||||
const stylesBlueIcon = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
box1: {
|
||||
position: 'relative',
|
||||
top: 15,
|
||||
},
|
||||
box: {
|
||||
alignSelf: 'flex-end',
|
||||
paddingHorizontal: 14,
|
||||
paddingTop: 8,
|
||||
},
|
||||
boxIncoming: {
|
||||
position: 'relative',
|
||||
},
|
||||
ball: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
},
|
||||
ballIncoming: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
transform: [{ rotate: '-45deg' }],
|
||||
justifyContent: 'center',
|
||||
},
|
||||
ballIncomingWithoutRotate: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
},
|
||||
ballReceive: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderBottomLeftRadius: 15,
|
||||
transform: [{ rotate: '-45deg' }],
|
||||
},
|
||||
ballOutgoing: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
transform: [{ rotate: '225deg' }],
|
||||
justifyContent: 'center',
|
||||
},
|
||||
ballOutgoingWithoutRotate: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
},
|
||||
ballOutgoingExpired: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
ballTransparrent: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
ballDimmed: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
backgroundColor: 'gray',
|
||||
},
|
||||
});
|
||||
|
||||
export const BluePlusIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
const stylesBlueIconHooks = StyleSheet.create({
|
||||
ball: {
|
||||
backgroundColor: colors.buttonBackgroundColor,
|
||||
},
|
||||
});
|
||||
return (
|
||||
<Avatar
|
||||
rounded
|
||||
containerStyle={[stylesBlueIcon.ball, stylesBlueIconHooks.ball]}
|
||||
icon={{ name: 'add', size: 22, type: 'ionicons', color: colors.foregroundColor }}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const BlueTransactionIncomingIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
const stylesBlueIconHooks = StyleSheet.create({
|
||||
ballIncoming: {
|
||||
backgroundColor: colors.ballReceive,
|
||||
},
|
||||
});
|
||||
return (
|
||||
<View {...props}>
|
||||
<View style={stylesBlueIcon.boxIncoming}>
|
||||
<View style={[stylesBlueIcon.ballIncoming, stylesBlueIconHooks.ballIncoming]}>
|
||||
<Icon {...props} name="arrow-down" size={16} type="font-awesome" color={colors.incomingForegroundColor} />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export const BlueTransactionPendingIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
|
||||
const stylesBlueIconHooks = StyleSheet.create({
|
||||
ball: {
|
||||
backgroundColor: colors.buttonBackgroundColor,
|
||||
},
|
||||
});
|
||||
return (
|
||||
<View {...props}>
|
||||
<View style={stylesBlueIcon.boxIncoming}>
|
||||
<View style={[stylesBlueIcon.ball, stylesBlueIconHooks.ball]}>
|
||||
<Icon
|
||||
{...props}
|
||||
name="kebab-horizontal"
|
||||
size={16}
|
||||
type="octicon"
|
||||
color={colors.foregroundColor}
|
||||
iconStyle={{ left: 0, top: 7 }}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export const BlueTransactionExpiredIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
const stylesBlueIconHooks = StyleSheet.create({
|
||||
ballOutgoingExpired: {
|
||||
backgroundColor: colors.ballOutgoingExpired,
|
||||
},
|
||||
});
|
||||
return (
|
||||
<View {...props}>
|
||||
<View style={stylesBlueIcon.boxIncoming}>
|
||||
<View style={[stylesBlueIcon.ballOutgoingExpired, stylesBlueIconHooks.ballOutgoingExpired]}>
|
||||
<Icon {...props} name="clock" size={16} type="octicon" color="#9AA0AA" iconStyle={{ left: 0, top: 0 }} />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export const BlueTransactionOnchainIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
const stylesBlueIconHooks = StyleSheet.create({
|
||||
ballIncoming: {
|
||||
backgroundColor: colors.ballReceive,
|
||||
},
|
||||
});
|
||||
return (
|
||||
<View {...props}>
|
||||
<View style={stylesBlueIcon.boxIncoming}>
|
||||
<View style={[stylesBlueIcon.ballIncoming, stylesBlueIconHooks.ballIncoming]}>
|
||||
<Icon
|
||||
{...props}
|
||||
name="link"
|
||||
size={16}
|
||||
type="font-awesome"
|
||||
color={colors.incomingForegroundColor}
|
||||
iconStyle={{ left: 0, top: 0, transform: [{ rotate: '-45deg' }] }}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export const BlueTransactionOffchainIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
const stylesBlueIconHooks = StyleSheet.create({
|
||||
ballOutgoingWithoutRotate: {
|
||||
backgroundColor: colors.ballOutgoing,
|
||||
},
|
||||
});
|
||||
return (
|
||||
<View {...props}>
|
||||
<View style={stylesBlueIcon.boxIncoming}>
|
||||
<View style={[stylesBlueIcon.ballOutgoingWithoutRotate, stylesBlueIconHooks.ballOutgoingWithoutRotate]}>
|
||||
<Icon
|
||||
{...props}
|
||||
name="bolt"
|
||||
size={16}
|
||||
type="font-awesome"
|
||||
color={colors.outgoingForegroundColor}
|
||||
iconStyle={{ left: 0, marginTop: 6 }}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export const BlueTransactionOffchainIncomingIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
const stylesBlueIconHooks = StyleSheet.create({
|
||||
ballIncomingWithoutRotate: {
|
||||
backgroundColor: colors.ballReceive,
|
||||
},
|
||||
});
|
||||
return (
|
||||
<View {...props}>
|
||||
<View style={stylesBlueIcon.boxIncoming}>
|
||||
<View style={[stylesBlueIcon.ballIncomingWithoutRotate, stylesBlueIconHooks.ballIncomingWithoutRotate]}>
|
||||
<Icon
|
||||
{...props}
|
||||
name="bolt"
|
||||
size={16}
|
||||
type="font-awesome"
|
||||
color={colors.incomingForegroundColor}
|
||||
iconStyle={{ left: 0, marginTop: 6 }}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export const BlueTransactionOutgoingIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
const stylesBlueIconHooks = StyleSheet.create({
|
||||
ballOutgoing: {
|
||||
backgroundColor: colors.ballOutgoing,
|
||||
},
|
||||
});
|
||||
return (
|
||||
<View {...props}>
|
||||
<View style={stylesBlueIcon.boxIncoming}>
|
||||
<View style={[stylesBlueIcon.ballOutgoing, stylesBlueIconHooks.ballOutgoing]}>
|
||||
<Icon {...props} name="arrow-down" size={16} type="font-awesome" color={colors.outgoingForegroundColor} />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const sendReceiveScanButtonFontSize =
|
||||
PixelRatio.roundToNearestPixel(Dimensions.get('window').width / 26) > 22
|
||||
? 22
|
||||
: PixelRatio.roundToNearestPixel(Dimensions.get('window').width / 26);
|
||||
export const BlueReceiveButtonIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
|
||||
return (
|
||||
<TouchableOpacity accessibilityRole="button" {...props} style={{ flex: 1 }}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
backgroundColor: colors.buttonBackgroundColor,
|
||||
}}
|
||||
>
|
||||
<View style={{ flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<View
|
||||
style={{
|
||||
left: 5,
|
||||
backgroundColor: 'transparent',
|
||||
transform: [{ rotate: '-45deg' }],
|
||||
alignItems: 'center',
|
||||
marginRight: 8,
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
{...props}
|
||||
name="arrow-down"
|
||||
size={sendReceiveScanButtonFontSize}
|
||||
type="font-awesome"
|
||||
color={colors.buttonAlternativeTextColor}
|
||||
/>
|
||||
</View>
|
||||
<Text
|
||||
style={{
|
||||
color: colors.buttonAlternativeTextColor,
|
||||
fontWeight: '500',
|
||||
fontSize: sendReceiveScanButtonFontSize,
|
||||
left: 5,
|
||||
backgroundColor: 'transparent',
|
||||
}}
|
||||
>
|
||||
{formatStringAddTwoWhiteSpaces(loc.receive.header)}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
||||
export class BlueReplaceFeeSuggestions extends Component {
|
||||
static propTypes = {
|
||||
onFeeSelected: PropTypes.func.isRequired,
|
||||
|
6
Gemfile
Normal file
6
Gemfile
Normal file
@ -0,0 +1,6 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
|
||||
ruby '2.7.4'
|
||||
|
||||
gem 'cocoapods', '~> 1.11', '>= 1.11.2'
|
100
Gemfile.lock
Normal file
100
Gemfile.lock
Normal file
@ -0,0 +1,100 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.5)
|
||||
rexml
|
||||
activesupport (6.1.4.4)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
zeitwerk (~> 2.3)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
algoliasearch (1.27.5)
|
||||
httpclient (~> 2.8, >= 2.8.3)
|
||||
json (>= 1.5.1)
|
||||
atomos (0.1.3)
|
||||
claide (1.1.0)
|
||||
cocoapods (1.11.2)
|
||||
addressable (~> 2.8)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.11.2)
|
||||
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
||||
cocoapods-downloader (>= 1.4.0, < 2.0)
|
||||
cocoapods-plugins (>= 1.0.0, < 2.0)
|
||||
cocoapods-search (>= 1.0.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.4.0, < 2.0)
|
||||
cocoapods-try (>= 1.1.0, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
escape (~> 0.0.4)
|
||||
fourflusher (>= 2.3.0, < 3.0)
|
||||
gh_inspector (~> 1.0)
|
||||
molinillo (~> 0.8.0)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (>= 1.0, < 3.0)
|
||||
xcodeproj (>= 1.21.0, < 2.0)
|
||||
cocoapods-core (1.11.2)
|
||||
activesupport (>= 5.0, < 7)
|
||||
addressable (~> 2.8)
|
||||
algoliasearch (~> 1.0)
|
||||
concurrent-ruby (~> 1.1)
|
||||
fuzzy_match (~> 2.0.4)
|
||||
nap (~> 1.0)
|
||||
netrc (~> 0.11)
|
||||
public_suffix (~> 4.0)
|
||||
typhoeus (~> 1.0)
|
||||
cocoapods-deintegrate (1.0.5)
|
||||
cocoapods-downloader (1.5.1)
|
||||
cocoapods-plugins (1.0.0)
|
||||
nap
|
||||
cocoapods-search (1.0.1)
|
||||
cocoapods-trunk (1.6.0)
|
||||
nap (>= 0.8, < 2.0)
|
||||
netrc (~> 0.11)
|
||||
cocoapods-try (1.2.0)
|
||||
colored2 (3.1.2)
|
||||
concurrent-ruby (1.1.9)
|
||||
escape (0.0.4)
|
||||
ethon (0.15.0)
|
||||
ffi (>= 1.15.0)
|
||||
ffi (1.15.5)
|
||||
fourflusher (2.3.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.9.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.6.1)
|
||||
minitest (5.15.0)
|
||||
molinillo (0.8.0)
|
||||
nanaimo (0.3.0)
|
||||
nap (1.1.0)
|
||||
netrc (0.11.0)
|
||||
public_suffix (4.0.6)
|
||||
rexml (3.2.5)
|
||||
ruby-macho (2.5.1)
|
||||
typhoeus (1.4.0)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (2.0.4)
|
||||
concurrent-ruby (~> 1.0)
|
||||
xcodeproj (1.21.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.3.0)
|
||||
rexml (~> 3.2.4)
|
||||
zeitwerk (2.5.4)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
cocoapods (~> 1.11, >= 1.11.2)
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.7.4p191
|
||||
|
||||
BUNDLED WITH
|
||||
2.2.27
|
@ -52,7 +52,6 @@ import Marketplace from './screen/wallets/marketplace';
|
||||
import ReorderWallets from './screen/wallets/reorderWallets';
|
||||
import SelectWallet from './screen/wallets/selectWallet';
|
||||
import ProvideEntropy from './screen/wallets/provideEntropy';
|
||||
import AOPP from './screen/wallets/aopp';
|
||||
|
||||
import TransactionDetails from './screen/transactions/details';
|
||||
import TransactionStatus from './screen/transactions/transactionStatus';
|
||||
@ -84,6 +83,7 @@ import LdkInfo from './screen/lnd/ldkInfo';
|
||||
import LNDViewAdditionalInvoiceInformation from './screen/lnd/lndViewAdditionalInvoiceInformation';
|
||||
import LnurlPay from './screen/lnd/lnurlPay';
|
||||
import LnurlPaySuccess from './screen/lnd/lnurlPaySuccess';
|
||||
import LnurlAuth from './screen/lnd/lnurlAuth';
|
||||
import UnlockWith from './UnlockWith';
|
||||
import DrawerList from './screen/wallets/drawerList';
|
||||
import { isDesktop, isTablet, isHandset } from './blue_modules/environment';
|
||||
@ -153,6 +153,7 @@ const WalletsRoot = () => {
|
||||
<WalletsStack.Screen name="IsItMyAddress" component={IsItMyAddress} options={IsItMyAddress.navigationOptions(theme)} />
|
||||
<WalletsStack.Screen name="LnurlPay" component={LnurlPay} options={LnurlPay.navigationOptions(theme)} />
|
||||
<WalletsStack.Screen name="LnurlPaySuccess" component={LnurlPaySuccess} options={LnurlPaySuccess.navigationOptions(theme)} />
|
||||
<WalletsStack.Screen name="LnurlAuth" component={LnurlAuth} options={LnurlAuth.navigationOptions(theme)} />
|
||||
<WalletsStack.Screen
|
||||
name="Success"
|
||||
component={Success}
|
||||
@ -436,7 +437,7 @@ const InitRoot = () => (
|
||||
<InitStack.Screen
|
||||
name="ReorderWallets"
|
||||
component={ReorderWalletsStackRoot}
|
||||
options={{ headerShown: false, gestureEnabled: false, stackPresentation: isDesktop ? 'containedModal' : 'fullScreenModal' }}
|
||||
options={{ headerShown: false, gestureEnabled: false, stackPresentation: isDesktop ? 'containedModal' : 'modal' }}
|
||||
/>
|
||||
<InitStack.Screen
|
||||
name={isHandset ? 'Navigation' : 'DrawerRoot'}
|
||||
@ -484,19 +485,6 @@ const ExportMultisigCoordinationSetupRoot = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const AOPPStack = createNativeStackNavigator();
|
||||
const AOPPRoot = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<AOPPStack.Navigator screenOptions={{ headerHideShadow: true }}>
|
||||
<AOPPStack.Screen name="SelectWallet" component={SelectWallet} options={SelectWallet.navigationOptions(theme)} />
|
||||
<AOPPStack.Screen name="AOPP" component={AOPP} options={AOPP.navigationOptions(theme)} />
|
||||
<AOPPStack.Screen name="SignVerify" component={SignVerify} options={SignVerify.navigationOptions(theme)} />
|
||||
</AOPPStack.Navigator>
|
||||
);
|
||||
};
|
||||
|
||||
const RootStack = createNativeStackNavigator();
|
||||
const NavigationDefaultOptions = { headerShown: false, stackPresentation: isDesktop ? 'containedModal' : 'modal' };
|
||||
const Navigation = () => {
|
||||
@ -530,7 +518,6 @@ const Navigation = () => {
|
||||
<RootStack.Screen name="SelectWallet" component={SelectWallet} />
|
||||
<RootStack.Screen name="ReceiveDetailsRoot" component={ReceiveDetailsStackRoot} options={NavigationDefaultOptions} />
|
||||
<RootStack.Screen name="LappBrowserRoot" component={LappBrowserStackRoot} options={NavigationDefaultOptions} />
|
||||
<RootStack.Screen name="AOPPRoot" component={AOPPRoot} options={NavigationDefaultOptions} />
|
||||
<RootStack.Screen name="LDKOpenChannelRoot" component={LDKOpenChannelRoot} options={NavigationDefaultOptions} />
|
||||
|
||||
<RootStack.Screen
|
||||
|
@ -31,10 +31,6 @@ const styles = StyleSheet.create({
|
||||
width: 64,
|
||||
height: 64,
|
||||
},
|
||||
encrypted: {
|
||||
width: 0.5,
|
||||
height: 20,
|
||||
},
|
||||
});
|
||||
|
||||
const UnlockWith = () => {
|
||||
|
@ -14,9 +14,8 @@ import { FiatUnit } from './models/fiatUnit';
|
||||
import { MultisigHDWallet } from './class';
|
||||
|
||||
function WatchConnectivity() {
|
||||
const { walletsInitialized, wallets, fetchWalletTransactions, saveToDisk, txMetadata, preferredFiatCurrency } = useContext(
|
||||
BlueStorageContext,
|
||||
);
|
||||
const { walletsInitialized, wallets, fetchWalletTransactions, saveToDisk, txMetadata, preferredFiatCurrency } =
|
||||
useContext(BlueStorageContext);
|
||||
const isReachable = useReachability();
|
||||
const isInstalled = useInstalled(); // true | false
|
||||
const messagesListenerActive = useRef(false);
|
||||
|
@ -140,7 +140,7 @@ android {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 1
|
||||
versionName "6.2.17"
|
||||
versionName "6.2.19"
|
||||
multiDexEnabled true
|
||||
missingDimensionStrategy 'react-native-camera', 'general'
|
||||
testBuildType System.getProperty('testBuildType', 'debug') // This will later be used to control the test apk build type
|
||||
@ -218,7 +218,7 @@ dependencies {
|
||||
// Run this once to be able to run the application with BUCK
|
||||
// puts all compile dependencies into folder libs for BUCK to use
|
||||
task copyDownloadableDepsToLibs(type: Copy) {
|
||||
from configurations.compile
|
||||
from configurations.implementation
|
||||
into 'libs'
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,6 @@
|
||||
<data android:scheme="bluewallet" />
|
||||
<data android:scheme="lapp" />
|
||||
<data android:scheme="blue" />
|
||||
<data android:scheme="aopp" />
|
||||
<data android:scheme="bankid" />
|
||||
<data android:scheme="swish" />
|
||||
<data android:scheme="http" />
|
||||
|
36
android/app/src/main/res/drawable/rn_edit_text_material.xml
Normal file
36
android/app/src/main/res/drawable/rn_edit_text_material.xml
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<inset xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material"
|
||||
android:insetRight="@dimen/abc_edit_text_inset_horizontal_material"
|
||||
android:insetTop="@dimen/abc_edit_text_inset_top_material"
|
||||
android:insetBottom="@dimen/abc_edit_text_inset_bottom_material">
|
||||
|
||||
<selector>
|
||||
<!--
|
||||
This file is a copy of abc_edit_text_material (https://bit.ly/3k8fX7I).
|
||||
The item below with state_pressed="false" and state_focused="false" causes a NullPointerException.
|
||||
NullPointerException:tempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)'
|
||||
|
||||
<item android:state_pressed="false" android:state_focused="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
|
||||
|
||||
For more info, see https://bit.ly/3CdLStv (react-native/pull/29452) and https://bit.ly/3nxOMoR.
|
||||
-->
|
||||
<item android:state_enabled="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
|
||||
<item android:drawable="@drawable/abc_textfield_activated_mtrl_alpha"/>
|
||||
</selector>
|
||||
|
||||
</inset>
|
@ -3,6 +3,7 @@
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
@ -47,7 +47,13 @@ allprojects {
|
||||
includeModule("com.wei.android.lib", "fingerprintidentify")
|
||||
}
|
||||
}
|
||||
mavenCentral()
|
||||
mavenCentral {
|
||||
// We don't want to fetch react-native from Maven Central as there are
|
||||
// older versions over there.
|
||||
content {
|
||||
excludeGroup "com.facebook.react"
|
||||
}
|
||||
}
|
||||
mavenLocal()
|
||||
maven {
|
||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||
# Default value: -Xmx1024m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
@ -31,4 +31,4 @@ org.gradle.configureondemand=true
|
||||
org.gradle.jvmargs=-Xmx4g -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
# Version of flipper SDK to use with React Native
|
||||
FLIPPER_VERSION=0.128.4
|
||||
FLIPPER_VERSION=0.127.0
|
4
blue_modules/BlueElectrum.d.ts
vendored
4
blue_modules/BlueElectrum.d.ts
vendored
@ -69,9 +69,7 @@ export function getMempoolTransactionsByAddress(address: string): Promise<Mempoo
|
||||
|
||||
export function estimateCurrentBlockheight(): number;
|
||||
|
||||
export function multiGetHistoryByAddress(
|
||||
addresses: string[],
|
||||
): Promise<
|
||||
export function multiGetHistoryByAddress(addresses: string[]): Promise<
|
||||
Record<
|
||||
string,
|
||||
{
|
||||
|
@ -1,72 +0,0 @@
|
||||
import Frisbee from 'frisbee';
|
||||
import url from 'url';
|
||||
|
||||
export default class AOPP {
|
||||
static typeAny = 'any';
|
||||
static typeP2wpkh = 'p2wpkh';
|
||||
static typeP2sh = 'p2sh';
|
||||
static typeP2pkh = 'p2pkh';
|
||||
|
||||
static getSegwitByAddressFormat(addressType) {
|
||||
if (![AOPP.typeP2wpkh, AOPP.typeP2sh, AOPP.typeP2pkh].includes(addressType)) {
|
||||
throw new Error('Work only for limited types');
|
||||
}
|
||||
switch (addressType) {
|
||||
case 'p2wpkh':
|
||||
return 'p2wpkh';
|
||||
case 'p2sh':
|
||||
return 'p2sh(p2wpkh)';
|
||||
case 'p2pkh':
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
constructor(uri) {
|
||||
this.uri = uri;
|
||||
const { protocol, query } = url.parse(uri, true); // eslint-disable-line node/no-deprecated-api
|
||||
|
||||
if (protocol !== 'aopp:') throw new Error('Unsupported protocol');
|
||||
if (query.v !== '0') throw new Error('Unsupported version');
|
||||
if (!query.msg) throw new Error('Message required');
|
||||
if (query.msg.lenth > 1024) throw new Error('Message is too big');
|
||||
if (query.asset && query.asset !== 'btc') throw new Error('Unsupported asset');
|
||||
if (query.format) {
|
||||
if (![AOPP.typeAny, AOPP.typeP2wpkh, AOPP.typeP2sh, AOPP.typeP2pkh].includes(query.format)) {
|
||||
throw new Error('Unsupported address format');
|
||||
}
|
||||
} else {
|
||||
query.format = 'any';
|
||||
}
|
||||
if (!query.callback) throw new Error('Callback required');
|
||||
|
||||
this.v = Number(query.v);
|
||||
this.msg = query.msg;
|
||||
this.format = query.format;
|
||||
this.callback = query.callback;
|
||||
|
||||
// parse callback url
|
||||
const { hostname } = url.parse(this.callback, true); // eslint-disable-line node/no-deprecated-api
|
||||
if (!hostname) throw new Error('Wrong callback');
|
||||
|
||||
this.callbackHostname = hostname;
|
||||
|
||||
this._api = new Frisbee({
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async send({ address, signature }) {
|
||||
const res = await this._api.post(this.callback, {
|
||||
body: {
|
||||
version: this.v,
|
||||
address,
|
||||
signature,
|
||||
},
|
||||
});
|
||||
|
||||
if (res.err) throw res.err;
|
||||
}
|
||||
}
|
@ -17,8 +17,7 @@ class DeeplinkSchemaMatch {
|
||||
lowercaseString.startsWith('lightning:') ||
|
||||
lowercaseString.startsWith('blue:') ||
|
||||
lowercaseString.startsWith('bluewallet:') ||
|
||||
lowercaseString.startsWith('lapp:') ||
|
||||
lowercaseString.startsWith('aopp:')
|
||||
lowercaseString.startsWith('lapp:')
|
||||
);
|
||||
}
|
||||
|
||||
@ -206,15 +205,7 @@ class DeeplinkSchemaMatch {
|
||||
} else {
|
||||
const urlObject = url.parse(event.url, true); // eslint-disable-line node/no-deprecated-api
|
||||
(async () => {
|
||||
if (urlObject.protocol === 'aopp:') {
|
||||
completionHandler([
|
||||
'AOPPRoot',
|
||||
{
|
||||
screen: 'AOPP',
|
||||
params: { uri: event.url },
|
||||
},
|
||||
]);
|
||||
} else if (urlObject.protocol === 'bluewallet:' || urlObject.protocol === 'lapp:' || urlObject.protocol === 'blue:') {
|
||||
if (urlObject.protocol === 'bluewallet:' || urlObject.protocol === 'lapp:' || urlObject.protocol === 'blue:') {
|
||||
switch (urlObject.host) {
|
||||
case 'openlappbrowser': {
|
||||
console.log('opening LAPP', urlObject.query.url);
|
||||
|
@ -1,6 +1,9 @@
|
||||
import { bech32 } from 'bech32';
|
||||
import bolt11 from 'bolt11';
|
||||
import { isTorDaemonDisabled } from '../blue_modules/environment';
|
||||
import { parse } from 'url'; // eslint-disable-line node/no-deprecated-api
|
||||
import { createHmac } from 'crypto';
|
||||
import secp256k1 from 'secp256k1';
|
||||
const CryptoJS = require('crypto-js');
|
||||
const createHash = require('create-hash');
|
||||
const torrific = require('../blue_modules/torrific');
|
||||
@ -12,6 +15,7 @@ const ONION_REGEX = /^(http:\/\/[^/:@]+\.onion(?::\d{1,5})?)(\/.*)?$/; // regex
|
||||
export default class Lnurl {
|
||||
static TAG_PAY_REQUEST = 'payRequest'; // type of LNURL
|
||||
static TAG_WITHDRAW_REQUEST = 'withdrawRequest'; // type of LNURL
|
||||
static TAG_LOGIN_REQUEST = 'login'; // type of LNURL
|
||||
|
||||
constructor(url, AsyncStorage) {
|
||||
this._lnurl = url;
|
||||
@ -285,6 +289,37 @@ export default class Lnurl {
|
||||
return this?._lnurlPayServicePayload?.commentAllowed ? parseInt(this._lnurlPayServicePayload.commentAllowed) : false;
|
||||
}
|
||||
|
||||
authenticate(secret) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this._lnurl) throw new Error('this._lnurl is not set');
|
||||
|
||||
const url = parse(Lnurl.getUrlFromLnurl(this._lnurl), true); // eslint-disable-line node/no-deprecated-api
|
||||
|
||||
const hmac = createHmac('sha256', secret);
|
||||
hmac.on('readable', async () => {
|
||||
try {
|
||||
const privateKey = hmac.read();
|
||||
if (!privateKey) return;
|
||||
const privateKeyBuf = Buffer.from(privateKey, 'hex');
|
||||
const publicKey = secp256k1.publicKeyCreate(privateKeyBuf);
|
||||
const signatureObj = secp256k1.sign(Buffer.from(url.query.k1, 'hex'), privateKeyBuf);
|
||||
const derSignature = secp256k1.signatureExport(signatureObj.signature);
|
||||
|
||||
const reply = await this.fetchGet(`${url.href}&sig=${derSignature.toString('hex')}&key=${publicKey.toString('hex')}`);
|
||||
if (reply.status === 'OK') {
|
||||
resolve();
|
||||
} else {
|
||||
reject(reply.reason);
|
||||
}
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
hmac.write(url.hostname);
|
||||
hmac.end();
|
||||
});
|
||||
}
|
||||
|
||||
static isLightningAddress(address) {
|
||||
// ensure only 1 `@` present:
|
||||
if (address.split('@').length !== 2) return false;
|
||||
|
@ -29,7 +29,7 @@ export class AbstractHDWallet extends LegacyWallet {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const Constructor = (this.constructor as unknown) as AbstractHDWalletStatics;
|
||||
const Constructor = this.constructor as unknown as AbstractHDWalletStatics;
|
||||
this.next_free_address_index = 0;
|
||||
this.next_free_change_address_index = 0;
|
||||
this.internal_addresses_cache = {}; // index => address
|
||||
@ -133,7 +133,7 @@ export class AbstractHDWallet extends LegacyWallet {
|
||||
let txs = [];
|
||||
try {
|
||||
txs = await BlueElectrum.getTransactionsByAddress(address);
|
||||
} catch (Err) {
|
||||
} catch (Err: any) {
|
||||
console.warn('BlueElectrum.getTransactionsByAddress()', Err.message);
|
||||
}
|
||||
if (txs.length === 0) {
|
||||
@ -171,7 +171,7 @@ export class AbstractHDWallet extends LegacyWallet {
|
||||
let txs = [];
|
||||
try {
|
||||
txs = await BlueElectrum.getTransactionsByAddress(address);
|
||||
} catch (Err) {
|
||||
} catch (Err: any) {
|
||||
console.warn('BlueElectrum.getTransactionsByAddress()', Err.message);
|
||||
}
|
||||
if (txs.length === 0) {
|
||||
|
@ -53,7 +53,7 @@ export class AbstractWallet {
|
||||
masterFingerprint: number | false;
|
||||
|
||||
constructor() {
|
||||
const Constructor = (this.constructor as unknown) as WalletStatics;
|
||||
const Constructor = this.constructor as unknown as WalletStatics;
|
||||
|
||||
this.type = Constructor.type;
|
||||
this.typeReadable = Constructor.typeReadable;
|
||||
@ -84,7 +84,7 @@ export class AbstractWallet {
|
||||
}
|
||||
|
||||
getID(): string {
|
||||
const thisWithPassphrase = (this as unknown) as WalletWithPassphrase;
|
||||
const thisWithPassphrase = this as unknown as WalletWithPassphrase;
|
||||
const passphrase = thisWithPassphrase.getPassphrase ? thisWithPassphrase.getPassphrase() : '';
|
||||
const path = this._derivationPath ?? '';
|
||||
const string2hash = this.type + this.getSecret() + passphrase + path;
|
||||
|
@ -620,7 +620,7 @@ export class LegacyWallet extends AbstractWallet {
|
||||
// undefined, true so it can verify Electrum signatures without errors
|
||||
try {
|
||||
return bitcoinMessage.verify(message, address, signature, undefined, true);
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
if (e.message === 'checkSegwitAlways can only be used with a compressed pubkey signature flagbyte') {
|
||||
// If message created with uncompressed private key, it will throw this error
|
||||
// in this case we should re-try with checkSegwitAlways flag off
|
||||
|
@ -667,6 +667,10 @@ export class LightningCustodianWallet extends LegacyWallet {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
authenticate(lnurl) {
|
||||
return lnurl.authenticate(this.secret);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -338,7 +338,7 @@ const styles = StyleSheet.create({
|
||||
disabledButton: {
|
||||
opacity: 0.5,
|
||||
},
|
||||
enabledButton: {
|
||||
enabledButon: {
|
||||
opacity: 1,
|
||||
},
|
||||
outdatedRateContainer: {
|
||||
|
@ -48,7 +48,7 @@ export const ArrowPicker = (props: ArrowPickerProps) => {
|
||||
styles.wrapperCustom,
|
||||
]}
|
||||
>
|
||||
<Icon size={24} name="chevron-left" type="ionicons" />
|
||||
<Icon size={24} name="chevron-left" type="ionicons" tvParallaxProperties={undefined} />
|
||||
</Pressable>
|
||||
<View style={{ width: 200 }}>
|
||||
<Text style={[styles.text, stylesHook.text]}>{props.isItemUnknown ? loc.send.fee_custom : keys[keyIndex]}</Text>
|
||||
@ -72,7 +72,7 @@ export const ArrowPicker = (props: ArrowPickerProps) => {
|
||||
styles.wrapperCustom,
|
||||
]}
|
||||
>
|
||||
<Icon size={24} name="chevron-right" type="ionicons" />
|
||||
<Icon size={24} name="chevron-right" type="ionicons" tvParallaxProperties={undefined} />
|
||||
</Pressable>
|
||||
</View>
|
||||
);
|
||||
|
@ -61,9 +61,6 @@ const styles = StyleSheet.create({
|
||||
nodeAlias: {
|
||||
marginVertical: 16,
|
||||
},
|
||||
pending: {
|
||||
marginVertical: 8,
|
||||
},
|
||||
canSendBar: {
|
||||
height: 14,
|
||||
maxHeight: 14,
|
||||
|
@ -16,37 +16,9 @@ const MultipleStepsListItem = props => {
|
||||
checked = false,
|
||||
} = props;
|
||||
const stylesHook = StyleSheet.create({
|
||||
root: {
|
||||
flex: 1,
|
||||
backgroundColor: colors.elevated,
|
||||
},
|
||||
textBtc: {
|
||||
color: colors.buttonAlternativeTextColor,
|
||||
},
|
||||
textDestinationFirstFour: {
|
||||
color: colors.buttonAlternativeTextColor,
|
||||
},
|
||||
textBtcUnitValue: {
|
||||
color: colors.buttonAlternativeTextColor,
|
||||
},
|
||||
textDestination: {
|
||||
color: colors.foregroundColor,
|
||||
},
|
||||
modalContentShort: {
|
||||
backgroundColor: colors.elevated,
|
||||
},
|
||||
modalContent: {
|
||||
backgroundColor: colors.elevated,
|
||||
},
|
||||
textFiat: {
|
||||
color: colors.alternativeTextColor,
|
||||
},
|
||||
provideKeyButton: {
|
||||
backgroundColor: colors.buttonDisabledBackgroundColor,
|
||||
},
|
||||
exportButton: {
|
||||
backgroundColor: colors.buttonDisabledBackgroundColor,
|
||||
},
|
||||
provideKeyButtonText: {
|
||||
color: colors.buttonTextColor,
|
||||
},
|
||||
@ -56,15 +28,9 @@ const MultipleStepsListItem = props => {
|
||||
vaultKeyText: {
|
||||
color: colors.alternativeTextColor,
|
||||
},
|
||||
feeFiatText: {
|
||||
color: colors.alternativeTextColor,
|
||||
},
|
||||
vaultKeyCircleSuccess: {
|
||||
backgroundColor: colors.msSuccessBG,
|
||||
},
|
||||
vaultKeyTextSigned: {
|
||||
color: colors.msSuccessBG,
|
||||
},
|
||||
rowPartialLeftText: {
|
||||
color: colors.alternativeTextColor,
|
||||
},
|
||||
@ -258,15 +224,6 @@ const styles = StyleSheet.create({
|
||||
alignContent: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
grayButton: {
|
||||
marginTop: 24,
|
||||
marginLeft: 40,
|
||||
height: 48,
|
||||
borderRadius: 8,
|
||||
justifyContent: 'center',
|
||||
paddingHorizontal: 16,
|
||||
marginBottom: 8,
|
||||
},
|
||||
activityIndicator: {
|
||||
marginLeft: 40,
|
||||
},
|
||||
@ -281,15 +238,6 @@ const styles = StyleSheet.create({
|
||||
rowPartialLeftText: {
|
||||
textAlign: 'center',
|
||||
},
|
||||
vaultKeyTextSignedWrapper: { justifyContent: 'center', alignItems: 'center', paddingLeft: 16 },
|
||||
vaultKeyTextSigned: { fontSize: 18, fontWeight: 'bold' },
|
||||
exportButton: {
|
||||
height: 48,
|
||||
borderRadius: 8,
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
});
|
||||
|
||||
export default MultipleStepsListItem;
|
||||
|
@ -2,24 +2,23 @@
|
||||
import React, { useState, useMemo, useCallback, useContext, useEffect, useRef } from 'react';
|
||||
import { Linking, StyleSheet, View } from 'react-native';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import { BitcoinUnit } from '../models/bitcoinUnits';
|
||||
import * as NavigationService from '../NavigationService';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { useNavigation, useTheme } from '@react-navigation/native';
|
||||
|
||||
import { BitcoinUnit } from '../models/bitcoinUnits';
|
||||
import * as NavigationService from '../NavigationService';
|
||||
import loc, { formatBalanceWithoutSuffix, transactionTimeToReadable } from '../loc';
|
||||
import Lnurl from '../class/lnurl';
|
||||
import { BlueStorageContext } from '../blue_modules/storage-context';
|
||||
import ToolTipMenu from './TooltipMenu';
|
||||
import {
|
||||
BlueListItem,
|
||||
BlueTransactionExpiredIcon,
|
||||
BlueTransactionIncomingIcon,
|
||||
BlueTransactionOffchainIcon,
|
||||
BlueTransactionOffchainIncomingIcon,
|
||||
BlueTransactionOnchainIcon,
|
||||
BlueTransactionOutgoingIcon,
|
||||
BlueTransactionPendingIcon,
|
||||
} from '../BlueComponents';
|
||||
import { BlueListItem } from '../BlueComponents';
|
||||
import TransactionExpiredIcon from '../components/icons/TransactionExpiredIcon';
|
||||
import TransactionIncomingIcon from '../components/icons/TransactionIncomingIcon';
|
||||
import TransactionOffchainIcon from '../components/icons/TransactionOffchainIcon';
|
||||
import TransactionOffchainIncomingIcon from '../components/icons/TransactionOffchainIncomingIcon';
|
||||
import TransactionOnchainIcon from '../components/icons/TransactionOnchainIcon';
|
||||
import TransactionOutgoingIcon from '../components/icons/TransactionOutgoingIcon';
|
||||
import TransactionPendingIcon from '../components/icons/TransactionPendingIcon';
|
||||
|
||||
export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUnit.BTC, walletID }) => {
|
||||
const [subtitleNumberOfLines, setSubtitleNumberOfLines] = useState(1);
|
||||
@ -114,7 +113,7 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
||||
if (item.category === 'receive' && item.confirmations < 3) {
|
||||
return (
|
||||
<View style={styles.iconWidth}>
|
||||
<BlueTransactionPendingIcon />
|
||||
<TransactionPendingIcon />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@ -122,7 +121,7 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
||||
if (item.type && item.type === 'bitcoind_tx') {
|
||||
return (
|
||||
<View style={styles.iconWidth}>
|
||||
<BlueTransactionOnchainIcon />
|
||||
<TransactionOnchainIcon />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@ -130,7 +129,7 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
||||
// is it lightning offchain payment?
|
||||
return (
|
||||
<View style={styles.iconWidth}>
|
||||
<BlueTransactionOffchainIcon />
|
||||
<TransactionOffchainIcon />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@ -143,14 +142,14 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
||||
if (invoiceExpiration < now) {
|
||||
return (
|
||||
<View style={styles.iconWidth}>
|
||||
<BlueTransactionExpiredIcon />
|
||||
<TransactionExpiredIcon />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return (
|
||||
<View style={styles.iconWidth}>
|
||||
<BlueTransactionOffchainIncomingIcon />
|
||||
<TransactionOffchainIncomingIcon />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@ -159,19 +158,19 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
||||
if (!item.confirmations) {
|
||||
return (
|
||||
<View style={styles.iconWidth}>
|
||||
<BlueTransactionPendingIcon />
|
||||
<TransactionPendingIcon />
|
||||
</View>
|
||||
);
|
||||
} else if (item.value < 0) {
|
||||
return (
|
||||
<View style={styles.iconWidth}>
|
||||
<BlueTransactionOutgoingIcon />
|
||||
<TransactionOutgoingIcon />
|
||||
</View>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<View style={styles.iconWidth}>
|
||||
<BlueTransactionIncomingIcon />
|
||||
<TransactionIncomingIcon />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ import { BlueStorageContext } from '../blue_modules/storage-context';
|
||||
import { isHandset, isTablet, isDesktop } from '../blue_modules/environment';
|
||||
|
||||
const nStyles = StyleSheet.create({
|
||||
root: {},
|
||||
container: {
|
||||
borderRadius: 10,
|
||||
minHeight: Platform.OS === 'ios' ? 164 : 181,
|
||||
@ -118,9 +117,6 @@ const iStyles = StyleSheet.create({
|
||||
fontSize: 19,
|
||||
writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr',
|
||||
},
|
||||
activity: {
|
||||
marginTop: 40,
|
||||
},
|
||||
balance: {
|
||||
backgroundColor: 'transparent',
|
||||
fontWeight: 'bold',
|
||||
@ -258,17 +254,16 @@ WalletCarouselItem.propTypes = {
|
||||
};
|
||||
|
||||
const cStyles = StyleSheet.create({
|
||||
loading: {
|
||||
position: 'absolute',
|
||||
alignItems: 'center',
|
||||
},
|
||||
content: {
|
||||
paddingTop: 16,
|
||||
},
|
||||
contentLargeScreen: {
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
separatorStyle: { width: 16, height: 20 },
|
||||
separatorStyle: {
|
||||
width: 16,
|
||||
height: 20,
|
||||
},
|
||||
});
|
||||
|
||||
const WalletsCarousel = forwardRef((props, ref) => {
|
||||
@ -314,7 +309,7 @@ const WalletsCarousel = forwardRef((props, ref) => {
|
||||
};
|
||||
|
||||
const { width } = useWindowDimensions();
|
||||
const sliderHeight = 190;
|
||||
const sliderHeight = 195;
|
||||
const itemWidth = width * 0.82 > 375 ? 375 : width * 0.82;
|
||||
return (
|
||||
<FlatList
|
||||
@ -332,7 +327,7 @@ const WalletsCarousel = forwardRef((props, ref) => {
|
||||
showsHorizontalScrollIndicator={false}
|
||||
initialNumToRender={10}
|
||||
ListHeaderComponent={ListHeaderComponent}
|
||||
style={props.horizontal ? { height: sliderHeight + 9 } : {}}
|
||||
style={props.horizontal ? { minHeight: sliderHeight + 9 } : {}}
|
||||
onScrollToIndexFailed={onScrollToIndexFailed}
|
||||
{...props}
|
||||
/>
|
||||
|
32
components/icons/PlusIcon.js
Normal file
32
components/icons/PlusIcon.js
Normal file
@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { Avatar } from 'react-native-elements';
|
||||
import { useTheme } from '@react-navigation/native';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
ball: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
},
|
||||
});
|
||||
|
||||
const PlusIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
const stylesHook = StyleSheet.create({
|
||||
ball: {
|
||||
backgroundColor: colors.buttonBackgroundColor,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<Avatar
|
||||
rounded
|
||||
containerStyle={[styles.ball, stylesHook.ball]}
|
||||
icon={{ name: 'add', size: 22, type: 'ionicons', color: colors.foregroundColor }}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default PlusIcon;
|
39
components/icons/TransactionExpiredIcon.js
Normal file
39
components/icons/TransactionExpiredIcon.js
Normal file
@ -0,0 +1,39 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import { useTheme } from '@react-navigation/native';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
boxIncoming: {
|
||||
position: 'relative',
|
||||
},
|
||||
ballOutgoingExpired: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
icon: {
|
||||
left: 0,
|
||||
top: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const TransactionExpiredIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
const stylesHooks = StyleSheet.create({
|
||||
ballOutgoingExpired: {
|
||||
backgroundColor: colors.ballOutgoingExpired,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={styles.boxIncoming}>
|
||||
<View style={[styles.ballOutgoingExpired, stylesHooks.ballOutgoingExpired]}>
|
||||
<Icon name="clock" size={16} type="octicon" color="#9AA0AA" iconStyle={styles.icon} />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default TransactionExpiredIcon;
|
36
components/icons/TransactionIncomingIcon.js
Normal file
36
components/icons/TransactionIncomingIcon.js
Normal file
@ -0,0 +1,36 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import { useTheme } from '@react-navigation/native';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
boxIncoming: {
|
||||
position: 'relative',
|
||||
},
|
||||
ballIncoming: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
transform: [{ rotate: '-45deg' }],
|
||||
justifyContent: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
const TransactionIncomingIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
const stylesHooks = StyleSheet.create({
|
||||
ballIncoming: {
|
||||
backgroundColor: colors.ballReceive,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={styles.boxIncoming}>
|
||||
<View style={[styles.ballIncoming, stylesHooks.ballIncoming]}>
|
||||
<Icon name="arrow-down" size={16} type="font-awesome" color={colors.incomingForegroundColor} />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default TransactionIncomingIcon;
|
38
components/icons/TransactionOffchainIcon.js
Normal file
38
components/icons/TransactionOffchainIcon.js
Normal file
@ -0,0 +1,38 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import { useTheme } from '@react-navigation/native';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
boxIncoming: {
|
||||
position: 'relative',
|
||||
},
|
||||
ballOutgoingWithoutRotate: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
},
|
||||
icon: {
|
||||
left: 0,
|
||||
marginTop: 6,
|
||||
},
|
||||
});
|
||||
|
||||
const TransactionOffchainIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
const stylesHooks = StyleSheet.create({
|
||||
ballOutgoingWithoutRotate: {
|
||||
backgroundColor: colors.ballOutgoing,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={styles.boxIncoming}>
|
||||
<View style={[styles.ballOutgoingWithoutRotate, stylesHooks.ballOutgoingWithoutRotate]}>
|
||||
<Icon name="bolt" size={16} type="font-awesome" color={colors.outgoingForegroundColor} iconStyle={styles.icon} />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default TransactionOffchainIcon;
|
38
components/icons/TransactionOffchainIncomingIcon.js
Normal file
38
components/icons/TransactionOffchainIncomingIcon.js
Normal file
@ -0,0 +1,38 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import { useTheme } from '@react-navigation/native';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
boxIncoming: {
|
||||
position: 'relative',
|
||||
},
|
||||
ballIncomingWithoutRotate: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
},
|
||||
icon: {
|
||||
left: 0,
|
||||
marginTop: 6,
|
||||
},
|
||||
});
|
||||
|
||||
const TransactionOffchainIncomingIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
const stylesHooks = StyleSheet.create({
|
||||
ballIncomingWithoutRotate: {
|
||||
backgroundColor: colors.ballReceive,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={styles.boxIncoming}>
|
||||
<View style={[styles.ballIncomingWithoutRotate, stylesHooks.ballIncomingWithoutRotate]}>
|
||||
<Icon name="bolt" size={16} type="font-awesome" color={colors.incomingForegroundColor} iconStyle={styles.icon} />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default TransactionOffchainIncomingIcon;
|
41
components/icons/TransactionOnchainIcon.js
Normal file
41
components/icons/TransactionOnchainIcon.js
Normal file
@ -0,0 +1,41 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import { useTheme } from '@react-navigation/native';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
boxIncoming: {
|
||||
position: 'relative',
|
||||
},
|
||||
ballIncoming: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
transform: [{ rotate: '-45deg' }],
|
||||
justifyContent: 'center',
|
||||
},
|
||||
icon: {
|
||||
left: 0,
|
||||
top: 0,
|
||||
transform: [{ rotate: '-45deg' }],
|
||||
},
|
||||
});
|
||||
|
||||
const TransactionOnchainIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
const stylesBlueIconHooks = StyleSheet.create({
|
||||
ballIncoming: {
|
||||
backgroundColor: colors.ballReceive,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={styles.boxIncoming}>
|
||||
<View style={[styles.ballIncoming, stylesBlueIconHooks.ballIncoming]}>
|
||||
<Icon name="link" size={16} type="font-awesome" color={colors.incomingForegroundColor} iconStyle={styles.icon} />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default TransactionOnchainIcon;
|
36
components/icons/TransactionOutgoingIcon.js
Normal file
36
components/icons/TransactionOutgoingIcon.js
Normal file
@ -0,0 +1,36 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import { useTheme } from '@react-navigation/native';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
boxIncoming: {
|
||||
position: 'relative',
|
||||
},
|
||||
ballOutgoing: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
transform: [{ rotate: '225deg' }],
|
||||
justifyContent: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
const TransactionOutgoingIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
const stylesBlueIconHooks = StyleSheet.create({
|
||||
ballOutgoing: {
|
||||
backgroundColor: colors.ballOutgoing,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={styles.boxIncoming}>
|
||||
<View style={[styles.ballOutgoing, stylesBlueIconHooks.ballOutgoing]}>
|
||||
<Icon name="arrow-down" size={16} type="font-awesome" color={colors.outgoingForegroundColor} />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default TransactionOutgoingIcon;
|
38
components/icons/TransactionPendingIcon.js
Normal file
38
components/icons/TransactionPendingIcon.js
Normal file
@ -0,0 +1,38 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import { useTheme } from '@react-navigation/native';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
boxIncoming: {
|
||||
position: 'relative',
|
||||
},
|
||||
ball: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
},
|
||||
icon: {
|
||||
left: 0,
|
||||
top: 7,
|
||||
},
|
||||
});
|
||||
|
||||
const TransactionPendingIcon = props => {
|
||||
const { colors } = useTheme();
|
||||
const stylesHook = StyleSheet.create({
|
||||
ball: {
|
||||
backgroundColor: colors.buttonBackgroundColor,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={styles.boxIncoming}>
|
||||
<View style={[styles.ball, stylesHook.ball]}>
|
||||
<Icon name="kebab-horizontal" size={16} type="octicon" color={colors.foregroundColor} iconStyle={styles.icon} />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default TransactionPendingIcon;
|
@ -45,83 +45,85 @@ const navigationStyle = (
|
||||
},
|
||||
formatter: OptionsFormatter,
|
||||
): NavigationOptionsGetter => {
|
||||
return theme => ({ navigation, route }) => {
|
||||
let headerRight;
|
||||
if (closeButton) {
|
||||
const handleClose = closeButtonFunc
|
||||
? () => closeButtonFunc({ navigation, route })
|
||||
: () => {
|
||||
Keyboard.dismiss();
|
||||
navigation.goBack(null);
|
||||
};
|
||||
headerRight = () => (
|
||||
<TouchableOpacity accessibilityRole="button" style={styles.button} onPress={handleClose} testID="NavigationCloseButton">
|
||||
<Image source={theme.closeImage} />
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
return theme =>
|
||||
({ navigation, route }) => {
|
||||
let headerRight;
|
||||
if (closeButton) {
|
||||
const handleClose = closeButtonFunc
|
||||
? () => closeButtonFunc({ navigation, route })
|
||||
: () => {
|
||||
Keyboard.dismiss();
|
||||
navigation.goBack(null);
|
||||
};
|
||||
headerRight = () => (
|
||||
<TouchableOpacity accessibilityRole="button" style={styles.button} onPress={handleClose} testID="NavigationCloseButton">
|
||||
<Image source={theme.closeImage} />
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
let options: NavigationOptions = {
|
||||
headerStyle: {
|
||||
borderBottomWidth: 0,
|
||||
elevation: 0,
|
||||
shadowOpacity: 0,
|
||||
shadowOffset: { height: 0, width: 0 },
|
||||
},
|
||||
headerTitleStyle: {
|
||||
fontWeight: '600',
|
||||
color: theme.colors.foregroundColor,
|
||||
},
|
||||
headerRight: headerRight,
|
||||
headerBackTitleVisible: false,
|
||||
headerTintColor: theme.colors.foregroundColor,
|
||||
...opts,
|
||||
let options: NavigationOptions = {
|
||||
headerStyle: {
|
||||
borderBottomWidth: 0,
|
||||
elevation: 0,
|
||||
shadowOpacity: 0,
|
||||
shadowOffset: { height: 0, width: 0 },
|
||||
},
|
||||
headerTitleStyle: {
|
||||
fontWeight: '600',
|
||||
color: theme.colors.foregroundColor,
|
||||
},
|
||||
headerRight: headerRight,
|
||||
headerBackTitleVisible: false,
|
||||
headerTintColor: theme.colors.foregroundColor,
|
||||
...opts,
|
||||
};
|
||||
|
||||
if (formatter) {
|
||||
options = formatter(options, { theme, navigation, route });
|
||||
}
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
if (formatter) {
|
||||
options = formatter(options, { theme, navigation, route });
|
||||
}
|
||||
|
||||
return options;
|
||||
};
|
||||
};
|
||||
|
||||
export default navigationStyle;
|
||||
|
||||
export const navigationStyleTx = (opts: NavigationOptions, formatter: OptionsFormatter): NavigationOptionsGetter => {
|
||||
return theme => ({ navigation, route }) => {
|
||||
let options: NavigationOptions = {
|
||||
headerStyle: {
|
||||
borderBottomWidth: 0,
|
||||
elevation: 0,
|
||||
shadowOffset: { height: 0, width: 0 },
|
||||
},
|
||||
headerTitleStyle: {
|
||||
fontWeight: '600',
|
||||
color: theme.colors.foregroundColor,
|
||||
},
|
||||
// headerBackTitle: null,
|
||||
headerBackTitleVisible: false,
|
||||
headerTintColor: theme.colors.foregroundColor,
|
||||
headerLeft: () => (
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
style={styles.button}
|
||||
onPress={() => {
|
||||
Keyboard.dismiss();
|
||||
navigation.goBack(null);
|
||||
}}
|
||||
>
|
||||
<Image source={theme.closeImage} />
|
||||
</TouchableOpacity>
|
||||
),
|
||||
...opts,
|
||||
return theme =>
|
||||
({ navigation, route }) => {
|
||||
let options: NavigationOptions = {
|
||||
headerStyle: {
|
||||
borderBottomWidth: 0,
|
||||
elevation: 0,
|
||||
shadowOffset: { height: 0, width: 0 },
|
||||
},
|
||||
headerTitleStyle: {
|
||||
fontWeight: '600',
|
||||
color: theme.colors.foregroundColor,
|
||||
},
|
||||
// headerBackTitle: null,
|
||||
headerBackTitleVisible: false,
|
||||
headerTintColor: theme.colors.foregroundColor,
|
||||
headerLeft: () => (
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
style={styles.button}
|
||||
onPress={() => {
|
||||
Keyboard.dismiss();
|
||||
navigation.goBack(null);
|
||||
}}
|
||||
>
|
||||
<Image source={theme.closeImage} />
|
||||
</TouchableOpacity>
|
||||
),
|
||||
...opts,
|
||||
};
|
||||
|
||||
if (formatter) {
|
||||
options = formatter(options, { theme, navigation, route });
|
||||
}
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
if (formatter) {
|
||||
options = formatter(options, { theme, navigation, route });
|
||||
}
|
||||
|
||||
return options;
|
||||
};
|
||||
};
|
||||
|
@ -0,0 +1,91 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet } from 'react-native';
|
||||
import Animated, { interpolate, interpolateNode, multiply } from 'react-native-reanimated';
|
||||
import { useDraggableFlatListContext } from '../context/draggableFlatListContext';
|
||||
import { useNode } from '../hooks/useNode';
|
||||
import { useOnCellActiveAnimation } from '../hooks/useOnCellActiveAnimation';
|
||||
export { useOnCellActiveAnimation } from '../hooks/useOnCellActiveAnimation';
|
||||
|
||||
type ScaleProps = {
|
||||
activeScale?: number;
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
// support older versions of Reanimated v1 by using the old interpolate function
|
||||
// if interpolateNode not available.
|
||||
const interpolateFn = (interpolateNode || interpolate) as unknown as typeof interpolateNode;
|
||||
|
||||
export const ScaleDecorator = ({ activeScale = 1.1, children }: ScaleProps) => {
|
||||
const { isActive, onActiveAnim } = useOnCellActiveAnimation({
|
||||
animationConfig: { mass: 0.1, restDisplacementThreshold: 0.0001 },
|
||||
});
|
||||
|
||||
const animScale = useNode(
|
||||
interpolateFn(onActiveAnim, {
|
||||
inputRange: [0, 1],
|
||||
outputRange: [1, activeScale],
|
||||
}),
|
||||
);
|
||||
|
||||
const { horizontal } = useDraggableFlatListContext<any>();
|
||||
const scale = isActive ? animScale : 1;
|
||||
return (
|
||||
<Animated.View style={[{ transform: [{ scaleX: scale }, { scaleY: scale }] }, horizontal && styles.horizontal]}>
|
||||
{children}
|
||||
</Animated.View>
|
||||
);
|
||||
};
|
||||
|
||||
type ShadowProps = {
|
||||
children: React.ReactNode;
|
||||
elevation?: number;
|
||||
radius?: number;
|
||||
color?: string;
|
||||
opacity?: number;
|
||||
};
|
||||
|
||||
export const ShadowDecorator = ({ elevation = 10, color = 'black', opacity = 0.25, radius = 5, children }: ShadowProps) => {
|
||||
const { isActive, onActiveAnim } = useOnCellActiveAnimation();
|
||||
const { horizontal } = useDraggableFlatListContext<any>();
|
||||
|
||||
const shadowOpacity = useNode(multiply(onActiveAnim, opacity));
|
||||
|
||||
const style = {
|
||||
elevation: isActive ? elevation : 0,
|
||||
shadowRadius: isActive ? radius : 0,
|
||||
shadowColor: isActive ? color : 'transparent',
|
||||
shadowOpacity: isActive ? shadowOpacity : 0,
|
||||
};
|
||||
|
||||
return <Animated.View style={[style, horizontal && styles.horizontal]}>{children}</Animated.View>;
|
||||
};
|
||||
|
||||
type OpacityProps = {
|
||||
activeOpacity?: number;
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
export const OpacityDecorator = ({ activeOpacity = 0.25, children }: OpacityProps) => {
|
||||
const { isActive, onActiveAnim } = useOnCellActiveAnimation();
|
||||
const { horizontal } = useDraggableFlatListContext<any>();
|
||||
|
||||
const opacity = useNode(
|
||||
interpolateFn(onActiveAnim, {
|
||||
inputRange: [0, 1],
|
||||
outputRange: [1, activeOpacity],
|
||||
}),
|
||||
);
|
||||
|
||||
const style = {
|
||||
opacity: isActive ? opacity : 1,
|
||||
};
|
||||
|
||||
return <Animated.View style={[style, horizontal && styles.horizontal]}>{children}</Animated.View>;
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
horizontal: {
|
||||
flexDirection: 'row',
|
||||
flex: 1,
|
||||
},
|
||||
});
|
@ -0,0 +1,132 @@
|
||||
/* eslint-disable react-native/no-inline-styles */
|
||||
import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react';
|
||||
// @ts-ignore Ignore
|
||||
import { findNodeHandle, LayoutChangeEvent, MeasureLayoutOnSuccessCallback, StyleProp, ViewStyle } from 'react-native';
|
||||
import Animated, { cond, useValue } from 'react-native-reanimated';
|
||||
import { useDraggableFlatListContext } from '../context/draggableFlatListContext';
|
||||
import { isAndroid, isIOS, isReanimatedV2, isWeb } from '../constants';
|
||||
import { useCellTranslate } from '../hooks/useCellTranslate';
|
||||
import { typedMemo } from '../utils';
|
||||
import { useRefs } from '../context/refContext';
|
||||
import { useAnimatedValues } from '../context/animatedValueContext';
|
||||
import CellProvider from '../context/cellContext';
|
||||
|
||||
type Props<T> = {
|
||||
item: T;
|
||||
index: number;
|
||||
children: React.ReactNode;
|
||||
onLayout: (e: LayoutChangeEvent) => void;
|
||||
style?: StyleProp<ViewStyle>;
|
||||
};
|
||||
|
||||
function CellRendererComponent<T>(props: Props<T>) {
|
||||
const { item, index, onLayout, children } = props;
|
||||
|
||||
const currentIndexAnim = useValue(index);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
currentIndexAnim.setValue(index);
|
||||
}, [index, currentIndexAnim]);
|
||||
|
||||
const viewRef = useRef<Animated.View>(null);
|
||||
const { cellDataRef, propsRef, scrollOffsetRef, containerRef } = useRefs<T>();
|
||||
|
||||
const { horizontalAnim } = useAnimatedValues();
|
||||
const { activeKey, keyExtractor, horizontal } = useDraggableFlatListContext<T>();
|
||||
|
||||
const key = keyExtractor(item, index);
|
||||
const offset = useValue<number>(-1);
|
||||
const size = useValue<number>(-1);
|
||||
const translate = useCellTranslate({
|
||||
cellOffset: offset,
|
||||
cellSize: size,
|
||||
cellIndex: currentIndexAnim,
|
||||
});
|
||||
|
||||
useMemo(() => {
|
||||
// prevent flicker on web
|
||||
if (isWeb) translate.setValue(0);
|
||||
}, [index]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
const isActive = activeKey === key;
|
||||
|
||||
const style = useMemo(
|
||||
() => ({
|
||||
transform: [{ translateX: cond(horizontalAnim, translate, 0) }, { translateY: cond(horizontalAnim, 0, translate) }],
|
||||
}),
|
||||
[horizontalAnim, translate],
|
||||
);
|
||||
|
||||
const updateCellMeasurements = useCallback(() => {
|
||||
const onSuccess: MeasureLayoutOnSuccessCallback = (x, y, w, h) => {
|
||||
if (isWeb && horizontal) x += scrollOffsetRef.current;
|
||||
const cellOffset = horizontal ? x : y;
|
||||
const cellSize = horizontal ? w : h;
|
||||
cellDataRef.current.set(key, {
|
||||
measurements: { size: cellSize, offset: cellOffset },
|
||||
});
|
||||
size.setValue(cellSize);
|
||||
offset.setValue(cellOffset);
|
||||
};
|
||||
|
||||
const onFail = () => {
|
||||
if (propsRef.current?.debug) {
|
||||
console.log(`## on measure fail, index: ${index}`);
|
||||
}
|
||||
};
|
||||
|
||||
// findNodeHandle is being deprecated. This is no longer necessary if using reanimated v2
|
||||
// remove once v1 is no longer supported
|
||||
const containerNode = containerRef.current;
|
||||
const viewNode = isReanimatedV2 ? viewRef.current : viewRef.current?.getNode();
|
||||
// @ts-ignore Ignore
|
||||
const nodeHandle = isReanimatedV2 ? containerNode : findNodeHandle(containerNode);
|
||||
|
||||
if (viewNode && nodeHandle) {
|
||||
// @ts-ignore Ignore
|
||||
viewNode.measureLayout(nodeHandle, onSuccess, onFail);
|
||||
}
|
||||
}, [cellDataRef, horizontal, index, key, offset, propsRef, size, scrollOffsetRef, containerRef]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isWeb) {
|
||||
// onLayout isn't called on web when the cell index changes, so we manually re-measure
|
||||
updateCellMeasurements();
|
||||
}
|
||||
}, [index, updateCellMeasurements]);
|
||||
|
||||
const onCellLayout = useCallback(
|
||||
(e: LayoutChangeEvent) => {
|
||||
updateCellMeasurements();
|
||||
onLayout(e);
|
||||
},
|
||||
[updateCellMeasurements, onLayout],
|
||||
);
|
||||
|
||||
// changing zIndex crashes android:
|
||||
// https://github.com/facebook/react-native/issues/28751
|
||||
return (
|
||||
<Animated.View
|
||||
{...props}
|
||||
ref={viewRef}
|
||||
onLayout={onCellLayout}
|
||||
style={[
|
||||
isAndroid && { elevation: isActive ? 1 : 0 },
|
||||
{ flexDirection: horizontal ? 'row' : 'column' },
|
||||
(isWeb || isIOS) && { zIndex: isActive ? 999 : 0 },
|
||||
]}
|
||||
pointerEvents={activeKey ? 'none' : 'auto'}
|
||||
>
|
||||
<Animated.View
|
||||
{...props}
|
||||
// Including both animated styles and non-animated styles causes react-native-web
|
||||
// to ignore updates in non-animated styles. Solution is to separate animated styles from non-animated styles
|
||||
style={[props.style, style]}
|
||||
>
|
||||
<CellProvider isActive={isActive}>{children}</CellProvider>
|
||||
</Animated.View>
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
|
||||
export default typedMemo(CellRendererComponent);
|
@ -0,0 +1,326 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
// @ts-ignore: Ignore
|
||||
import React, { useCallback, useLayoutEffect, useMemo, useState } from 'react';
|
||||
// @ts-ignore: Ignore
|
||||
import { ListRenderItem, FlatListProps, NativeScrollEvent, NativeSyntheticEvent, LayoutChangeEvent } from 'react-native';
|
||||
import {
|
||||
PanGestureHandler,
|
||||
State as GestureState,
|
||||
FlatList,
|
||||
PanGestureHandlerGestureEvent,
|
||||
PanGestureHandlerStateChangeEvent,
|
||||
} from 'react-native-gesture-handler';
|
||||
import Animated, { and, block, call, cond, eq, event, greaterThan, neq, not, onChange, or, set, sub } from 'react-native-reanimated';
|
||||
import CellRendererComponent from './CellRendererComponent';
|
||||
import { DEFAULT_PROPS, isWeb } from '../constants';
|
||||
import PlaceholderItem from './PlaceholderItem';
|
||||
import RowItem from './RowItem';
|
||||
import ScrollOffsetListener from './ScrollOffsetListener';
|
||||
import { DraggableFlatListProps } from '../types';
|
||||
import { useAutoScroll } from '../hooks/useAutoScroll';
|
||||
import { useNode } from '../hooks/useNode';
|
||||
import PropsProvider from '../context/propsContext';
|
||||
import AnimatedValueProvider, { useAnimatedValues } from '../context/animatedValueContext';
|
||||
import RefProvider, { useRefs } from '../context/refContext';
|
||||
import DraggableFlatListProvider from '../context/draggableFlatListContext';
|
||||
|
||||
type RNGHFlatListProps<T> = Animated.AnimateProps<
|
||||
FlatListProps<T> & {
|
||||
ref: React.Ref<FlatList<T>>;
|
||||
simultaneousHandlers?: React.Ref<any> | React.Ref<any>[];
|
||||
}
|
||||
>;
|
||||
|
||||
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList) as unknown as <T>(props: RNGHFlatListProps<T>) => React.ReactElement;
|
||||
|
||||
function DraggableFlatListInner<T>(props: DraggableFlatListProps<T>) {
|
||||
const { cellDataRef, containerRef, flatListRef, isTouchActiveRef, keyToIndexRef, panGestureHandlerRef, propsRef, scrollOffsetRef } =
|
||||
useRefs<T>();
|
||||
const {
|
||||
activationDistance,
|
||||
activeCellOffset,
|
||||
activeCellSize,
|
||||
activeIndexAnim,
|
||||
containerSize,
|
||||
disabled,
|
||||
panGestureState,
|
||||
resetTouchedCell,
|
||||
scrollOffset,
|
||||
scrollViewSize,
|
||||
spacerIndexAnim,
|
||||
touchAbsolute,
|
||||
touchInit,
|
||||
} = useAnimatedValues();
|
||||
|
||||
const {
|
||||
dragHitSlop = DEFAULT_PROPS.dragHitSlop,
|
||||
scrollEnabled = DEFAULT_PROPS.scrollEnabled,
|
||||
activationDistance: activationDistanceProp = DEFAULT_PROPS.activationDistance,
|
||||
} = props;
|
||||
|
||||
const [activeKey, setActiveKey] = useState<string | null>(null);
|
||||
|
||||
const keyExtractor = useCallback(
|
||||
(item: T, index: number) => {
|
||||
if (propsRef.current.keyExtractor) return propsRef.current.keyExtractor(item, index);
|
||||
else throw new Error('You must provide a keyExtractor to DraggableFlatList');
|
||||
},
|
||||
[propsRef],
|
||||
);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
props.data.forEach((d, i) => {
|
||||
const key = keyExtractor(d, i);
|
||||
keyToIndexRef.current.set(key, i);
|
||||
});
|
||||
}, [props.data, keyExtractor, keyToIndexRef]);
|
||||
|
||||
const drag = useCallback(
|
||||
(activeKey: string) => {
|
||||
if (!isTouchActiveRef.current.js) return;
|
||||
const index = keyToIndexRef.current.get(activeKey);
|
||||
const cellData = cellDataRef.current.get(activeKey);
|
||||
if (cellData) {
|
||||
activeCellOffset.setValue(cellData.measurements.offset - scrollOffsetRef.current);
|
||||
activeCellSize.setValue(cellData.measurements.size);
|
||||
}
|
||||
|
||||
const { onDragBegin } = propsRef.current;
|
||||
if (index !== undefined) {
|
||||
spacerIndexAnim.setValue(index);
|
||||
activeIndexAnim.setValue(index);
|
||||
setActiveKey(activeKey);
|
||||
onDragBegin?.(index);
|
||||
}
|
||||
},
|
||||
[
|
||||
isTouchActiveRef,
|
||||
keyToIndexRef,
|
||||
cellDataRef,
|
||||
propsRef,
|
||||
activeCellOffset,
|
||||
scrollOffsetRef,
|
||||
activeCellSize,
|
||||
spacerIndexAnim,
|
||||
activeIndexAnim,
|
||||
],
|
||||
);
|
||||
|
||||
const autoScrollNode = useAutoScroll();
|
||||
|
||||
const onContainerLayout = ({ nativeEvent: { layout } }: LayoutChangeEvent) => {
|
||||
containerSize.setValue(props.horizontal ? layout.width : layout.height);
|
||||
};
|
||||
|
||||
const onListContentSizeChange = (w: number, h: number) => {
|
||||
scrollViewSize.setValue(props.horizontal ? w : h);
|
||||
props.onContentSizeChange?.(w, h);
|
||||
};
|
||||
|
||||
const onContainerTouchStart = () => {
|
||||
isTouchActiveRef.current.js = true;
|
||||
isTouchActiveRef.current.native.setValue(1);
|
||||
return false;
|
||||
};
|
||||
|
||||
const onContainerTouchEnd = () => {
|
||||
isTouchActiveRef.current.js = false;
|
||||
isTouchActiveRef.current.native.setValue(0);
|
||||
};
|
||||
|
||||
let dynamicProps = {};
|
||||
if (activationDistanceProp) {
|
||||
const activeOffset = [-activationDistanceProp, activationDistanceProp];
|
||||
dynamicProps = props.horizontal ? { activeOffsetX: activeOffset } : { activeOffsetY: activeOffset };
|
||||
}
|
||||
|
||||
const extraData = useMemo(
|
||||
() => ({
|
||||
activeKey,
|
||||
extraData: props.extraData,
|
||||
}),
|
||||
[activeKey, props.extraData],
|
||||
);
|
||||
|
||||
const renderItem: ListRenderItem<T> = useCallback(
|
||||
// @ts-ignore: Ignore
|
||||
({ item, index }) => {
|
||||
const key = keyExtractor(item, index);
|
||||
if (index !== keyToIndexRef.current.get(key)) keyToIndexRef.current.set(key, index);
|
||||
|
||||
return <RowItem item={item} itemKey={key} renderItem={props.renderItem} drag={drag} extraData={props.extraData} />;
|
||||
},
|
||||
[props.renderItem, props.extraData, drag, keyExtractor],
|
||||
);
|
||||
|
||||
const resetHoverState = useCallback(() => {
|
||||
activeIndexAnim.setValue(-1);
|
||||
spacerIndexAnim.setValue(-1);
|
||||
touchAbsolute.setValue(0);
|
||||
disabled.setValue(0);
|
||||
requestAnimationFrame(() => {
|
||||
setActiveKey(null);
|
||||
});
|
||||
}, [activeIndexAnim, spacerIndexAnim, touchAbsolute, disabled]);
|
||||
|
||||
const onRelease = ([index]: readonly number[]) => {
|
||||
// This shouldn't be necessary but seems to fix a bug where sometimes
|
||||
// native values wouldn't update
|
||||
isTouchActiveRef.current.native.setValue(0);
|
||||
props.onRelease?.(index);
|
||||
};
|
||||
|
||||
const onDragEnd = useCallback(
|
||||
([from, to]: readonly number[]) => {
|
||||
const { onDragEnd, data } = propsRef.current;
|
||||
if (onDragEnd) {
|
||||
const newData = [...data];
|
||||
if (from !== to) {
|
||||
newData.splice(from, 1);
|
||||
newData.splice(to, 0, data[from]);
|
||||
}
|
||||
onDragEnd({ from, to, data: newData });
|
||||
}
|
||||
resetHoverState();
|
||||
},
|
||||
[resetHoverState, propsRef],
|
||||
);
|
||||
|
||||
const onGestureRelease = useNode(
|
||||
cond(
|
||||
greaterThan(activeIndexAnim, -1),
|
||||
[set(disabled, 1), set(isTouchActiveRef.current.native, 0), call([activeIndexAnim], onRelease)],
|
||||
[call([activeIndexAnim], resetHoverState), resetTouchedCell],
|
||||
),
|
||||
);
|
||||
|
||||
const onPanStateChange = useMemo(
|
||||
() =>
|
||||
event([
|
||||
{
|
||||
nativeEvent: ({ state, x, y }: PanGestureHandlerStateChangeEvent['nativeEvent']) =>
|
||||
block([
|
||||
cond(and(neq(state, panGestureState), not(disabled)), [
|
||||
cond(
|
||||
or(
|
||||
eq(state, GestureState.BEGAN), // Called on press in on Android, NOT on ios!
|
||||
// GestureState.BEGAN may be skipped on fast swipes
|
||||
and(eq(state, GestureState.ACTIVE), neq(panGestureState, GestureState.BEGAN)),
|
||||
),
|
||||
[set(touchAbsolute, props.horizontal ? x : y), set(touchInit, touchAbsolute)],
|
||||
),
|
||||
cond(eq(state, GestureState.ACTIVE), [
|
||||
set(activationDistance, sub(props.horizontal ? x : y, touchInit)),
|
||||
set(touchAbsolute, props.horizontal ? x : y),
|
||||
]),
|
||||
]),
|
||||
cond(neq(panGestureState, state), [
|
||||
set(panGestureState, state),
|
||||
cond(or(eq(state, GestureState.END), eq(state, GestureState.CANCELLED), eq(state, GestureState.FAILED)), onGestureRelease),
|
||||
]),
|
||||
]),
|
||||
},
|
||||
]),
|
||||
[activationDistance, props.horizontal, panGestureState, disabled, onGestureRelease, touchAbsolute, touchInit],
|
||||
);
|
||||
|
||||
const onPanGestureEvent = useMemo(
|
||||
() =>
|
||||
event([
|
||||
{
|
||||
nativeEvent: ({ x, y }: PanGestureHandlerGestureEvent['nativeEvent']) =>
|
||||
cond(and(greaterThan(activeIndexAnim, -1), eq(panGestureState, GestureState.ACTIVE), not(disabled)), [
|
||||
set(touchAbsolute, props.horizontal ? x : y),
|
||||
]),
|
||||
},
|
||||
]),
|
||||
[activeIndexAnim, disabled, panGestureState, props.horizontal, touchAbsolute],
|
||||
);
|
||||
|
||||
const scrollHandler = useMemo(() => {
|
||||
// Web doesn't seem to like animated events
|
||||
const webOnScroll = ({
|
||||
nativeEvent: {
|
||||
contentOffset: { x, y },
|
||||
},
|
||||
}: NativeSyntheticEvent<NativeScrollEvent>) => {
|
||||
scrollOffset.setValue(props.horizontal ? x : y);
|
||||
};
|
||||
|
||||
const mobileOnScroll = event([
|
||||
{
|
||||
nativeEvent: ({ contentOffset }: NativeScrollEvent) =>
|
||||
block([set(scrollOffset, props.horizontal ? contentOffset.x : contentOffset.y), autoScrollNode]),
|
||||
},
|
||||
]);
|
||||
|
||||
return isWeb ? webOnScroll : mobileOnScroll;
|
||||
}, [autoScrollNode, props.horizontal, scrollOffset]);
|
||||
|
||||
return (
|
||||
<DraggableFlatListProvider activeKey={activeKey} onDragEnd={onDragEnd} keyExtractor={keyExtractor} horizontal={!!props.horizontal}>
|
||||
<PanGestureHandler
|
||||
ref={panGestureHandlerRef}
|
||||
hitSlop={dragHitSlop}
|
||||
onHandlerStateChange={onPanStateChange}
|
||||
onGestureEvent={onPanGestureEvent}
|
||||
simultaneousHandlers={props.simultaneousHandlers}
|
||||
{...dynamicProps}
|
||||
>
|
||||
<Animated.View
|
||||
style={props.containerStyle}
|
||||
ref={containerRef}
|
||||
onLayout={onContainerLayout}
|
||||
onTouchEnd={onContainerTouchEnd}
|
||||
onStartShouldSetResponderCapture={onContainerTouchStart}
|
||||
// @ts-ignore Ignore
|
||||
onClick={onContainerTouchEnd}
|
||||
>
|
||||
<ScrollOffsetListener
|
||||
scrollOffset={scrollOffset}
|
||||
onScrollOffsetChange={([offset]) => {
|
||||
scrollOffsetRef.current = offset;
|
||||
props.onScrollOffsetChange?.(offset);
|
||||
}}
|
||||
/>
|
||||
{!!props.renderPlaceholder && <PlaceholderItem renderPlaceholder={props.renderPlaceholder} />}
|
||||
<AnimatedFlatList
|
||||
{...props}
|
||||
CellRendererComponent={CellRendererComponent}
|
||||
ref={flatListRef}
|
||||
onContentSizeChange={onListContentSizeChange}
|
||||
scrollEnabled={!activeKey && scrollEnabled}
|
||||
renderItem={renderItem}
|
||||
extraData={extraData}
|
||||
keyExtractor={keyExtractor}
|
||||
onScroll={scrollHandler}
|
||||
scrollEventThrottle={16}
|
||||
simultaneousHandlers={props.simultaneousHandlers}
|
||||
removeClippedSubviews={false}
|
||||
/>
|
||||
<Animated.Code dependencies={[]}>
|
||||
{() => block([onChange(isTouchActiveRef.current.native, cond(not(isTouchActiveRef.current.native), onGestureRelease))])}
|
||||
</Animated.Code>
|
||||
</Animated.View>
|
||||
</PanGestureHandler>
|
||||
</DraggableFlatListProvider>
|
||||
);
|
||||
}
|
||||
|
||||
function DraggableFlatList<T>(props: DraggableFlatListProps<T>, ref: React.ForwardedRef<FlatList<T>>) {
|
||||
return (
|
||||
<PropsProvider {...props}>
|
||||
<AnimatedValueProvider>
|
||||
<RefProvider flatListRef={ref}>
|
||||
<DraggableFlatListInner {...props} />
|
||||
</RefProvider>
|
||||
</AnimatedValueProvider>
|
||||
</PropsProvider>
|
||||
);
|
||||
}
|
||||
|
||||
// Generic forwarded ref type assertion taken from:
|
||||
// https://fettblog.eu/typescript-react-generic-forward-refs/#option-1%3A-type-assertion
|
||||
export default React.forwardRef(DraggableFlatList) as <T>(
|
||||
props: DraggableFlatListProps<T> & { ref?: React.ForwardedRef<FlatList<T>> },
|
||||
) => ReturnType<typeof DraggableFlatList>;
|
@ -0,0 +1,75 @@
|
||||
// @ts-ignore: Ignore
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { StyleSheet } from 'react-native';
|
||||
import Animated, { call, useCode, onChange, greaterThan, cond, sub, block } from 'react-native-reanimated';
|
||||
import { useAnimatedValues } from '../context/animatedValueContext';
|
||||
import { useDraggableFlatListContext } from '../context/draggableFlatListContext';
|
||||
import { useProps } from '../context/propsContext';
|
||||
import { useRefs } from '../context/refContext';
|
||||
import { useNode } from '../hooks/useNode';
|
||||
import { RenderPlaceholder } from '../types';
|
||||
import { typedMemo } from '../utils';
|
||||
|
||||
type Props<T> = {
|
||||
renderPlaceholder?: RenderPlaceholder<T>;
|
||||
};
|
||||
|
||||
function PlaceholderItem<T>({ renderPlaceholder }: Props<T>) {
|
||||
const { activeCellSize, placeholderOffset, spacerIndexAnim, scrollOffset } = useAnimatedValues();
|
||||
const [placeholderSize, setPlaceholderSize] = useState(0);
|
||||
|
||||
const { keyToIndexRef, propsRef } = useRefs<T>();
|
||||
|
||||
const { activeKey } = useDraggableFlatListContext();
|
||||
const { horizontal } = useProps();
|
||||
|
||||
const onPlaceholderIndexChange = useCallback(
|
||||
(index: number) => {
|
||||
propsRef.current.onPlaceholderIndexChange?.(index);
|
||||
},
|
||||
[propsRef],
|
||||
);
|
||||
|
||||
useCode(
|
||||
() =>
|
||||
block([
|
||||
onChange(
|
||||
activeCellSize,
|
||||
call([activeCellSize], ([size]) => {
|
||||
// Using animated values to set height caused a bug where item wouldn't correctly update
|
||||
// so instead we mirror the animated value in component state.
|
||||
setPlaceholderSize(size);
|
||||
}),
|
||||
),
|
||||
onChange(
|
||||
spacerIndexAnim,
|
||||
call([spacerIndexAnim], ([i]) => {
|
||||
onPlaceholderIndexChange(i);
|
||||
if (i === -1) setPlaceholderSize(0);
|
||||
}),
|
||||
),
|
||||
]),
|
||||
[],
|
||||
);
|
||||
|
||||
const translateKey = horizontal ? 'translateX' : 'translateY';
|
||||
const sizeKey = horizontal ? 'width' : 'height';
|
||||
const opacity = useNode(cond(greaterThan(spacerIndexAnim, -1), 1, 0));
|
||||
|
||||
const activeIndex = activeKey ? keyToIndexRef.current.get(activeKey) : undefined;
|
||||
const activeItem = activeIndex === undefined ? null : propsRef.current?.data[activeIndex];
|
||||
|
||||
const animStyle = {
|
||||
opacity,
|
||||
[sizeKey]: placeholderSize,
|
||||
transform: [{ [translateKey]: sub(placeholderOffset, scrollOffset) }] as unknown as Animated.AnimatedTransform,
|
||||
};
|
||||
|
||||
return (
|
||||
<Animated.View pointerEvents={activeKey ? 'auto' : 'none'} style={[StyleSheet.absoluteFill, animStyle]}>
|
||||
{!activeItem || activeIndex === undefined ? null : renderPlaceholder?.({ item: activeItem, index: activeIndex })}
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
|
||||
export default typedMemo(PlaceholderItem);
|
@ -0,0 +1,61 @@
|
||||
/* eslint-disable react/no-unused-prop-types */
|
||||
// @ts-ignore: Ignore
|
||||
import React, { useCallback, useRef } from 'react';
|
||||
import { useDraggableFlatListContext } from '../context/draggableFlatListContext';
|
||||
import { useRefs } from '../context/refContext';
|
||||
import { RenderItem } from '../types';
|
||||
import { typedMemo } from '../utils';
|
||||
|
||||
type Props<T> = {
|
||||
extraData?: any;
|
||||
drag: (itemKey: string) => void;
|
||||
item: T;
|
||||
renderItem: RenderItem<T>;
|
||||
itemKey: string;
|
||||
debug?: boolean;
|
||||
};
|
||||
|
||||
function RowItem<T>(props: Props<T>) {
|
||||
const propsRef = useRef(props);
|
||||
propsRef.current = props;
|
||||
|
||||
const { activeKey } = useDraggableFlatListContext();
|
||||
const activeKeyRef = useRef(activeKey);
|
||||
activeKeyRef.current = activeKey;
|
||||
const { keyToIndexRef } = useRefs();
|
||||
|
||||
const drag = useCallback(() => {
|
||||
const { drag, itemKey, debug } = propsRef.current;
|
||||
if (activeKeyRef.current) {
|
||||
// already dragging an item, noop
|
||||
if (debug) console.log('## attempt to drag item while another item is already active, noop');
|
||||
}
|
||||
drag(itemKey);
|
||||
}, []);
|
||||
|
||||
const { renderItem, item, itemKey } = props;
|
||||
return (
|
||||
<MemoizedInner
|
||||
isActive={activeKey === itemKey}
|
||||
drag={drag}
|
||||
renderItem={renderItem}
|
||||
item={item}
|
||||
index={keyToIndexRef.current.get(itemKey)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default typedMemo(RowItem);
|
||||
|
||||
type InnerProps<T> = {
|
||||
isActive: boolean;
|
||||
item: T;
|
||||
index?: number;
|
||||
drag: () => void;
|
||||
renderItem: RenderItem<T>;
|
||||
};
|
||||
|
||||
function Inner<T>({ isActive, item, drag, index, renderItem }: InnerProps<T>) {
|
||||
return renderItem({ isActive, item, drag, index }) as JSX.Element;
|
||||
}
|
||||
const MemoizedInner = typedMemo(Inner);
|
@ -0,0 +1,14 @@
|
||||
import Animated, { call, onChange, useCode } from 'react-native-reanimated';
|
||||
import { typedMemo } from '../utils';
|
||||
|
||||
type Props = {
|
||||
scrollOffset: Animated.Value<number>;
|
||||
onScrollOffsetChange: (offset: readonly number[]) => void;
|
||||
};
|
||||
|
||||
const ScrollOffsetListener = ({ scrollOffset, onScrollOffsetChange }: Props) => {
|
||||
useCode(() => onChange(scrollOffset, call([scrollOffset], onScrollOffsetChange)), []);
|
||||
return null;
|
||||
};
|
||||
|
||||
export default typedMemo(ScrollOffsetListener);
|
37
components/react-native-draggable-flatlist/constants.ts
Normal file
37
components/react-native-draggable-flatlist/constants.ts
Normal file
@ -0,0 +1,37 @@
|
||||
// @ts-ignore: Ignore
|
||||
import { Platform } from 'react-native';
|
||||
import { PanGestureHandlerProperties } from 'react-native-gesture-handler';
|
||||
// @ts-ignore: Ignore
|
||||
import { useSharedValue, WithSpringConfig } from 'react-native-reanimated';
|
||||
|
||||
// Fire onScrollComplete when within this many px of target offset
|
||||
export const SCROLL_POSITION_TOLERANCE = 2;
|
||||
export const DEFAULT_ANIMATION_CONFIG: WithSpringConfig = {
|
||||
damping: 20,
|
||||
mass: 0.2,
|
||||
stiffness: 100,
|
||||
overshootClamping: false,
|
||||
restSpeedThreshold: 0.2,
|
||||
restDisplacementThreshold: 0.2,
|
||||
};
|
||||
|
||||
export const DEFAULT_PROPS = {
|
||||
autoscrollThreshold: 30,
|
||||
autoscrollSpeed: 100,
|
||||
animationConfig: DEFAULT_ANIMATION_CONFIG,
|
||||
scrollEnabled: true,
|
||||
dragHitSlop: 0 as PanGestureHandlerProperties['hitSlop'],
|
||||
activationDistance: 0,
|
||||
dragItemOverflow: false,
|
||||
};
|
||||
|
||||
export const isIOS = Platform.OS === 'ios';
|
||||
export const isAndroid = Platform.OS === 'android';
|
||||
export const isWeb = Platform.OS === 'web';
|
||||
|
||||
// Is there a better way to check for v2?
|
||||
export const isReanimatedV2 = !!useSharedValue;
|
||||
|
||||
if (!isReanimatedV2) {
|
||||
console.warn('Your version of react-native-reanimated is too old for react-native-draggable-flatlist. It may not work as expected.');
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
import React, { useContext, useMemo } from 'react';
|
||||
import { add, and, block, greaterThan, max, min, set, sub, useValue } from 'react-native-reanimated';
|
||||
import { State as GestureState } from 'react-native-gesture-handler';
|
||||
import { useNode } from '../hooks/useNode';
|
||||
import { useProps } from './propsContext';
|
||||
|
||||
if (!useValue) {
|
||||
throw new Error('Incompatible Reanimated version (useValue not found)');
|
||||
}
|
||||
|
||||
const AnimatedValueContext = React.createContext<ReturnType<typeof useSetupAnimatedValues> | undefined>(undefined);
|
||||
|
||||
export default function AnimatedValueProvider({ children }: { children: React.ReactNode }) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
const value = useSetupAnimatedValues();
|
||||
return <AnimatedValueContext.Provider value={value}>{children}</AnimatedValueContext.Provider>;
|
||||
}
|
||||
|
||||
export function useAnimatedValues() {
|
||||
const value = useContext(AnimatedValueContext);
|
||||
if (!value) {
|
||||
throw new Error('useAnimatedValues must be called from within AnimatedValueProvider!');
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function useSetupAnimatedValues<T>() {
|
||||
const props = useProps<T>();
|
||||
const containerSize = useValue<number>(0);
|
||||
|
||||
const touchInit = useValue<number>(0); // Position of initial touch
|
||||
const activationDistance = useValue<number>(0); // Distance finger travels from initial touch to when dragging begins
|
||||
const touchAbsolute = useValue<number>(0); // Finger position on screen, relative to container
|
||||
const panGestureState = useValue<GestureState>(GestureState.UNDETERMINED);
|
||||
|
||||
const isTouchActiveNative = useValue<number>(0);
|
||||
|
||||
const disabled = useValue<number>(0);
|
||||
|
||||
const horizontalAnim = useValue(props.horizontal ? 1 : 0);
|
||||
|
||||
const activeIndexAnim = useValue<number>(-1); // Index of hovering cell
|
||||
const spacerIndexAnim = useValue<number>(-1); // Index of hovered-over cell
|
||||
|
||||
const activeCellSize = useValue<number>(0); // Height or width of acctive cell
|
||||
const activeCellOffset = useValue<number>(0); // Distance between active cell and edge of container
|
||||
|
||||
const isDraggingCell = useNode(and(isTouchActiveNative, greaterThan(activeIndexAnim, -1)));
|
||||
|
||||
const scrollOffset = useValue<number>(0);
|
||||
|
||||
const scrollViewSize = useValue<number>(0);
|
||||
|
||||
const touchCellOffset = useNode(sub(touchInit, activeCellOffset));
|
||||
|
||||
const hoverAnimUnconstrained = useNode(sub(sub(touchAbsolute, activationDistance), touchCellOffset));
|
||||
|
||||
const hoverAnimConstrained = useNode(min(sub(containerSize, activeCellSize), max(0, hoverAnimUnconstrained)));
|
||||
|
||||
const hoverAnim = props.dragItemOverflow ? hoverAnimUnconstrained : hoverAnimConstrained;
|
||||
|
||||
const hoverOffset = useNode(add(hoverAnim, scrollOffset));
|
||||
|
||||
const placeholderOffset = useValue<number>(0);
|
||||
|
||||
// Note: this could use a refactor as it combines touch state + cell animation
|
||||
const resetTouchedCell = useNode(block([set(touchAbsolute, 0), set(touchInit, 0), set(activeCellOffset, 0), set(activationDistance, 0)]));
|
||||
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
activationDistance,
|
||||
activeCellOffset,
|
||||
activeCellSize,
|
||||
activeIndexAnim,
|
||||
containerSize,
|
||||
disabled,
|
||||
horizontalAnim,
|
||||
hoverAnim,
|
||||
hoverAnimConstrained,
|
||||
hoverAnimUnconstrained,
|
||||
hoverOffset,
|
||||
isDraggingCell,
|
||||
isTouchActiveNative,
|
||||
panGestureState,
|
||||
placeholderOffset,
|
||||
resetTouchedCell,
|
||||
scrollOffset,
|
||||
scrollViewSize,
|
||||
spacerIndexAnim,
|
||||
touchAbsolute,
|
||||
touchCellOffset,
|
||||
touchInit,
|
||||
}),
|
||||
[
|
||||
activationDistance,
|
||||
activeCellOffset,
|
||||
activeCellSize,
|
||||
activeIndexAnim,
|
||||
containerSize,
|
||||
disabled,
|
||||
horizontalAnim,
|
||||
hoverAnim,
|
||||
hoverAnimConstrained,
|
||||
hoverAnimUnconstrained,
|
||||
hoverOffset,
|
||||
isDraggingCell,
|
||||
isTouchActiveNative,
|
||||
panGestureState,
|
||||
placeholderOffset,
|
||||
resetTouchedCell,
|
||||
scrollOffset,
|
||||
scrollViewSize,
|
||||
spacerIndexAnim,
|
||||
touchAbsolute,
|
||||
touchCellOffset,
|
||||
touchInit,
|
||||
],
|
||||
);
|
||||
|
||||
return value;
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
import React, { useContext, useMemo } from 'react';
|
||||
|
||||
type CellContextValue = {
|
||||
isActive: boolean;
|
||||
};
|
||||
|
||||
const CellContext = React.createContext<CellContextValue | undefined>(undefined);
|
||||
|
||||
type Props = {
|
||||
isActive: boolean;
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
export default function CellProvider({ isActive, children }: Props) {
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
isActive,
|
||||
}),
|
||||
[isActive],
|
||||
);
|
||||
return <CellContext.Provider value={value}>{children}</CellContext.Provider>;
|
||||
}
|
||||
|
||||
export function useIsActive() {
|
||||
const value = useContext(CellContext);
|
||||
if (!value) {
|
||||
throw new Error('useIsActive must be called from within CellProvider!');
|
||||
}
|
||||
return value.isActive;
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
import React, { useContext, useMemo } from 'react';
|
||||
|
||||
type Props<T> = {
|
||||
activeKey: string | null;
|
||||
onDragEnd: ([from, to]: readonly number[]) => void;
|
||||
keyExtractor: (item: T, index: number) => string;
|
||||
horizontal: boolean;
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
type DraggableFlatListContextValue<T> = Omit<Props<T>, 'children'>;
|
||||
|
||||
const DraggableFlatListContext = React.createContext<DraggableFlatListContextValue<any> | undefined>(undefined);
|
||||
|
||||
export default function DraggableFlatListProvider<T>({ activeKey, onDragEnd, keyExtractor, horizontal, children }: Props<T>) {
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
activeKey,
|
||||
keyExtractor,
|
||||
onDragEnd,
|
||||
horizontal,
|
||||
}),
|
||||
[activeKey, onDragEnd, keyExtractor, horizontal],
|
||||
);
|
||||
|
||||
return <DraggableFlatListContext.Provider value={value}>{children}</DraggableFlatListContext.Provider>;
|
||||
}
|
||||
|
||||
export function useDraggableFlatListContext<T>() {
|
||||
const value = useContext(DraggableFlatListContext);
|
||||
if (!value) {
|
||||
throw new Error('useDraggableFlatListContext must be called within DraggableFlatListProvider');
|
||||
}
|
||||
return value as DraggableFlatListContextValue<T>;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { DraggableFlatListProps } from '../types';
|
||||
|
||||
const PropsContext = React.createContext<DraggableFlatListProps<any> | undefined>(undefined);
|
||||
|
||||
type Props<T> = DraggableFlatListProps<T> & { children: React.ReactNode };
|
||||
|
||||
export default function PropsProvider<T>({ children, ...props }: Props<T>) {
|
||||
return <PropsContext.Provider value={props}>{children}</PropsContext.Provider>;
|
||||
}
|
||||
|
||||
export function useProps<T>() {
|
||||
const value = useContext(PropsContext) as DraggableFlatListProps<T> | undefined;
|
||||
if (!value) {
|
||||
throw new Error('useProps must be called from within PropsProvider!');
|
||||
}
|
||||
return value;
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
/* eslint-disable @typescript-eslint/no-use-before-define */
|
||||
import React, { useContext, useMemo, useRef } from 'react';
|
||||
import { FlatList, PanGestureHandler } from 'react-native-gesture-handler';
|
||||
import Animated from 'react-native-reanimated';
|
||||
import { DEFAULT_PROPS } from '../constants';
|
||||
import { useProps } from './propsContext';
|
||||
import { useAnimatedValues } from './animatedValueContext';
|
||||
import { CellData, DraggableFlatListProps } from '../types';
|
||||
|
||||
type RefContextValue<T> = {
|
||||
propsRef: React.MutableRefObject<DraggableFlatListProps<T>>;
|
||||
animationConfigRef: React.MutableRefObject<Animated.SpringConfig>;
|
||||
cellDataRef: React.MutableRefObject<Map<string, CellData>>;
|
||||
keyToIndexRef: React.MutableRefObject<Map<string, number>>;
|
||||
containerRef: React.RefObject<Animated.View>;
|
||||
flatListRef: React.RefObject<FlatList<T>> | React.ForwardedRef<FlatList<T>>;
|
||||
panGestureHandlerRef: React.RefObject<PanGestureHandler>;
|
||||
scrollOffsetRef: React.MutableRefObject<number>;
|
||||
isTouchActiveRef: React.MutableRefObject<{
|
||||
native: Animated.Value<number>;
|
||||
js: boolean;
|
||||
}>;
|
||||
};
|
||||
const RefContext = React.createContext<RefContextValue<any> | undefined>(undefined);
|
||||
|
||||
export default function RefProvider<T>({
|
||||
children,
|
||||
flatListRef,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
flatListRef: React.ForwardedRef<FlatList<T>>;
|
||||
}) {
|
||||
const value = useSetupRefs<T>({ flatListRef });
|
||||
return <RefContext.Provider value={value}>{children}</RefContext.Provider>;
|
||||
}
|
||||
|
||||
export function useRefs<T>() {
|
||||
const value = useContext(RefContext);
|
||||
if (!value) {
|
||||
throw new Error('useRefs must be called from within a RefContext.Provider!');
|
||||
}
|
||||
return value as RefContextValue<T>;
|
||||
}
|
||||
|
||||
function useSetupRefs<T>({ flatListRef: flatListRefProp }: { flatListRef: React.ForwardedRef<FlatList<T>> }) {
|
||||
const props = useProps<T>();
|
||||
const { animationConfig = DEFAULT_PROPS.animationConfig } = props;
|
||||
|
||||
const { isTouchActiveNative } = useAnimatedValues();
|
||||
|
||||
const propsRef = useRef(props);
|
||||
propsRef.current = props;
|
||||
const animConfig = {
|
||||
...DEFAULT_PROPS.animationConfig,
|
||||
...animationConfig,
|
||||
} as Animated.SpringConfig;
|
||||
const animationConfigRef = useRef(animConfig);
|
||||
animationConfigRef.current = animConfig;
|
||||
|
||||
const cellDataRef = useRef(new Map<string, CellData>());
|
||||
const keyToIndexRef = useRef(new Map<string, number>());
|
||||
const containerRef = useRef<Animated.View>(null);
|
||||
const flatListRefInner = useRef<FlatList<T>>(null);
|
||||
const flatListRef = flatListRefProp || flatListRefInner;
|
||||
const panGestureHandlerRef = useRef<PanGestureHandler>(null);
|
||||
const scrollOffsetRef = useRef(0);
|
||||
const isTouchActiveRef = useRef({
|
||||
native: isTouchActiveNative,
|
||||
js: false,
|
||||
});
|
||||
|
||||
const refs = useMemo(
|
||||
() => ({
|
||||
animationConfigRef,
|
||||
cellDataRef,
|
||||
containerRef,
|
||||
flatListRef,
|
||||
isTouchActiveRef,
|
||||
keyToIndexRef,
|
||||
panGestureHandlerRef,
|
||||
propsRef,
|
||||
scrollOffsetRef,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
return refs;
|
||||
}
|
@ -0,0 +1,183 @@
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
import { useRef } from 'react';
|
||||
import {
|
||||
abs,
|
||||
add,
|
||||
and,
|
||||
block,
|
||||
call,
|
||||
cond,
|
||||
eq,
|
||||
greaterOrEq,
|
||||
lessOrEq,
|
||||
max,
|
||||
not,
|
||||
onChange,
|
||||
or,
|
||||
set,
|
||||
sub,
|
||||
useCode,
|
||||
useValue,
|
||||
} from 'react-native-reanimated';
|
||||
import { FlatList, State as GestureState } from 'react-native-gesture-handler';
|
||||
import { DEFAULT_PROPS, SCROLL_POSITION_TOLERANCE } from '../constants';
|
||||
import { useNode } from '../hooks/useNode';
|
||||
import { useProps } from '../context/propsContext';
|
||||
import { useAnimatedValues } from '../context/animatedValueContext';
|
||||
import { useRefs } from '../context/refContext';
|
||||
|
||||
export function useAutoScroll<T>() {
|
||||
const { flatListRef } = useRefs<T>();
|
||||
const { autoscrollThreshold = DEFAULT_PROPS.autoscrollThreshold, autoscrollSpeed = DEFAULT_PROPS.autoscrollSpeed } = useProps();
|
||||
|
||||
const { scrollOffset, scrollViewSize, containerSize, hoverAnim, isDraggingCell, activeCellSize, panGestureState } = useAnimatedValues();
|
||||
|
||||
const isScrolledUp = useNode(lessOrEq(sub(scrollOffset, SCROLL_POSITION_TOLERANCE), 0));
|
||||
const isScrolledDown = useNode(greaterOrEq(add(scrollOffset, containerSize, SCROLL_POSITION_TOLERANCE), scrollViewSize));
|
||||
|
||||
const distToTopEdge = useNode(max(0, hoverAnim));
|
||||
const distToBottomEdge = useNode(max(0, sub(containerSize, add(hoverAnim, activeCellSize))));
|
||||
|
||||
const isAtTopEdge = useNode(lessOrEq(distToTopEdge, autoscrollThreshold));
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const isAtBottomEdge = useNode(lessOrEq(distToBottomEdge, autoscrollThreshold!));
|
||||
|
||||
const isAtEdge = useNode(or(isAtBottomEdge, isAtTopEdge));
|
||||
const autoscrollParams = [distToTopEdge, distToBottomEdge, scrollOffset, isScrolledUp, isScrolledDown];
|
||||
|
||||
const targetScrollOffset = useValue<number>(0);
|
||||
const resolveAutoscroll = useRef<(params: readonly number[]) => void>();
|
||||
|
||||
const isAutoScrollInProgressNative = useValue<number>(0);
|
||||
|
||||
const isAutoScrollInProgress = useRef({
|
||||
js: false,
|
||||
native: isAutoScrollInProgressNative,
|
||||
});
|
||||
|
||||
const isDraggingCellJS = useRef(false);
|
||||
useCode(
|
||||
() =>
|
||||
block([
|
||||
onChange(
|
||||
isDraggingCell,
|
||||
call([isDraggingCell], ([v]) => {
|
||||
isDraggingCellJS.current = !!v;
|
||||
}),
|
||||
),
|
||||
]),
|
||||
[],
|
||||
);
|
||||
|
||||
// Ensure that only 1 call to autoscroll is active at a time
|
||||
const autoscrollLooping = useRef(false);
|
||||
|
||||
const onAutoscrollComplete = (params: readonly number[]) => {
|
||||
isAutoScrollInProgress.current.js = false;
|
||||
resolveAutoscroll.current?.(params);
|
||||
};
|
||||
|
||||
const scrollToAsync = (offset: number): Promise<readonly number[]> =>
|
||||
new Promise(resolve => {
|
||||
resolveAutoscroll.current = resolve;
|
||||
targetScrollOffset.setValue(offset);
|
||||
isAutoScrollInProgress.current.native.setValue(1);
|
||||
isAutoScrollInProgress.current.js = true;
|
||||
|
||||
function getFlatListNode(): FlatList<T> | null {
|
||||
if (!flatListRef || !('current' in flatListRef) || !flatListRef.current) return null;
|
||||
if ('scrollToOffset' in flatListRef.current) return flatListRef.current as FlatList<T>;
|
||||
if ('getNode' in flatListRef.current) {
|
||||
// @ts-ignore backwards compat
|
||||
return flatListRef.current.getNode();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const flatListNode = getFlatListNode();
|
||||
|
||||
flatListNode?.scrollToOffset?.({ offset });
|
||||
});
|
||||
|
||||
const getScrollTargetOffset = (
|
||||
distFromTop: number,
|
||||
distFromBottom: number,
|
||||
scrollOffset: number,
|
||||
isScrolledUp: boolean,
|
||||
isScrolledDown: boolean,
|
||||
) => {
|
||||
if (isAutoScrollInProgress.current.js) return -1;
|
||||
const scrollUp = distFromTop < autoscrollThreshold!;
|
||||
const scrollDown = distFromBottom < autoscrollThreshold!;
|
||||
if (!(scrollUp || scrollDown) || (scrollUp && isScrolledUp) || (scrollDown && isScrolledDown)) return -1;
|
||||
const distFromEdge = scrollUp ? distFromTop : distFromBottom;
|
||||
const speedPct = 1 - distFromEdge / autoscrollThreshold!;
|
||||
const offset = speedPct * autoscrollSpeed;
|
||||
const targetOffset = scrollUp ? Math.max(0, scrollOffset - offset) : scrollOffset + offset;
|
||||
return targetOffset;
|
||||
};
|
||||
|
||||
const autoscroll = async (params: readonly number[]) => {
|
||||
if (autoscrollLooping.current) {
|
||||
return;
|
||||
}
|
||||
autoscrollLooping.current = true;
|
||||
try {
|
||||
let shouldScroll = true;
|
||||
let curParams = params;
|
||||
while (shouldScroll) {
|
||||
const [distFromTop, distFromBottom, scrollOffset, isScrolledUp, isScrolledDown] = curParams;
|
||||
const targetOffset = getScrollTargetOffset(distFromTop, distFromBottom, scrollOffset, !!isScrolledUp, !!isScrolledDown);
|
||||
const scrollingUpAtTop = !!(isScrolledUp && targetOffset <= scrollOffset);
|
||||
const scrollingDownAtBottom = !!(isScrolledDown && targetOffset >= scrollOffset);
|
||||
shouldScroll = targetOffset >= 0 && isDraggingCellJS.current && !scrollingUpAtTop && !scrollingDownAtBottom;
|
||||
|
||||
if (shouldScroll) {
|
||||
try {
|
||||
curParams = await scrollToAsync(targetOffset);
|
||||
} catch (err) {}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
autoscrollLooping.current = false;
|
||||
}
|
||||
};
|
||||
|
||||
const checkAutoscroll = useNode(
|
||||
cond(
|
||||
and(
|
||||
isAtEdge,
|
||||
not(and(isAtTopEdge, isScrolledUp)),
|
||||
not(and(isAtBottomEdge, isScrolledDown)),
|
||||
eq(panGestureState, GestureState.ACTIVE),
|
||||
not(isAutoScrollInProgress.current.native),
|
||||
),
|
||||
call(autoscrollParams, autoscroll),
|
||||
),
|
||||
);
|
||||
|
||||
useCode(() => checkAutoscroll, []);
|
||||
|
||||
const onScrollNode = useNode(
|
||||
cond(
|
||||
and(
|
||||
isAutoScrollInProgress.current.native,
|
||||
or(
|
||||
// We've scrolled to where we want to be
|
||||
lessOrEq(abs(sub(targetScrollOffset, scrollOffset)), SCROLL_POSITION_TOLERANCE),
|
||||
// We're at the start, but still want to scroll farther up
|
||||
and(isScrolledUp, lessOrEq(targetScrollOffset, scrollOffset)),
|
||||
// We're at the end, but still want to scroll further down
|
||||
and(isScrolledDown, greaterOrEq(targetScrollOffset, scrollOffset)),
|
||||
),
|
||||
),
|
||||
[
|
||||
// Finish scrolling
|
||||
set(isAutoScrollInProgress.current.native, 0),
|
||||
call(autoscrollParams, onAutoscrollComplete),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
return onScrollNode;
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
import Animated, { add, block, call, clockRunning, cond, eq, onChange, stopClock, useCode, useValue } from 'react-native-reanimated';
|
||||
import { useAnimatedValues } from '../context/animatedValueContext';
|
||||
import { useRefs } from '../context/refContext';
|
||||
import { setupCell, springFill } from '../procs';
|
||||
import { useSpring } from './useSpring';
|
||||
import { useNode } from '../hooks/useNode';
|
||||
import { useDraggableFlatListContext } from '../context/draggableFlatListContext';
|
||||
|
||||
type Params = {
|
||||
cellIndex: Animated.Value<number>;
|
||||
cellSize: Animated.Value<number>;
|
||||
cellOffset: Animated.Value<number>;
|
||||
};
|
||||
|
||||
export function useCellTranslate({ cellIndex, cellSize, cellOffset }: Params) {
|
||||
const {
|
||||
activeIndexAnim,
|
||||
activeCellSize,
|
||||
hoverAnim,
|
||||
scrollOffset,
|
||||
spacerIndexAnim,
|
||||
placeholderOffset,
|
||||
isDraggingCell,
|
||||
resetTouchedCell,
|
||||
disabled,
|
||||
} = useAnimatedValues();
|
||||
const { animationConfigRef } = useRefs();
|
||||
const { onDragEnd } = useDraggableFlatListContext();
|
||||
|
||||
const cellSpring = useSpring({ config: animationConfigRef.current });
|
||||
const { clock, state, config } = cellSpring;
|
||||
|
||||
const isAfterActive = useValue(0);
|
||||
const isClockRunning = useNode(clockRunning(clock));
|
||||
|
||||
const runSpring = useNode(springFill(clock, state, config));
|
||||
|
||||
// Even though this is the same value as hoverOffset passed via context
|
||||
// the android context value lags behind the actual value on autoscroll
|
||||
const cellHoverOffset = useNode(add(hoverAnim, scrollOffset));
|
||||
|
||||
const onFinished = useNode(
|
||||
cond(isClockRunning, [
|
||||
stopClock(clock),
|
||||
cond(eq(cellIndex, activeIndexAnim), [resetTouchedCell, call([activeIndexAnim, spacerIndexAnim], onDragEnd)]),
|
||||
]),
|
||||
);
|
||||
|
||||
const prevTrans = useValue<number>(0);
|
||||
const prevSpacerIndex = useValue<number>(-1);
|
||||
const prevIsDraggingCell = useValue<number>(0);
|
||||
|
||||
const cellTranslate = useNode(
|
||||
setupCell(
|
||||
cellIndex,
|
||||
cellSize,
|
||||
cellOffset,
|
||||
isAfterActive,
|
||||
prevTrans,
|
||||
prevSpacerIndex,
|
||||
activeIndexAnim,
|
||||
activeCellSize,
|
||||
cellHoverOffset,
|
||||
spacerIndexAnim,
|
||||
// @ts-ignore Ignore
|
||||
config.toValue,
|
||||
state.position,
|
||||
state.time,
|
||||
state.finished,
|
||||
runSpring,
|
||||
onFinished,
|
||||
isDraggingCell,
|
||||
placeholderOffset,
|
||||
prevIsDraggingCell,
|
||||
clock,
|
||||
disabled,
|
||||
),
|
||||
);
|
||||
|
||||
// This is a workaround required to continually evaluate values
|
||||
useCode(() => block([onChange(cellTranslate, []), onChange(prevTrans, []), onChange(cellSize, []), onChange(cellOffset, [])]), []);
|
||||
|
||||
return state.position;
|
||||
}
|
10
components/react-native-draggable-flatlist/hooks/useNode.tsx
Normal file
10
components/react-native-draggable-flatlist/hooks/useNode.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import { useRef } from 'react';
|
||||
import Animated from 'react-native-reanimated';
|
||||
|
||||
export function useNode<T>(node: Animated.Node<T>) {
|
||||
const ref = useRef<Animated.Node<T> | null>(null);
|
||||
if (ref.current === null) {
|
||||
ref.current = node;
|
||||
}
|
||||
return ref.current;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
// @ts-ignore: Ignore
|
||||
import Animated, { block, clockRunning, cond, onChange, set, startClock, stopClock, useCode } from 'react-native-reanimated';
|
||||
import { useAnimatedValues } from '../context/animatedValueContext';
|
||||
import { useIsActive } from '../context/cellContext';
|
||||
import { springFill } from '../procs';
|
||||
import { useSpring } from './useSpring';
|
||||
|
||||
type Params = {
|
||||
animationConfig: Partial<Animated.SpringConfig>;
|
||||
};
|
||||
|
||||
export function useOnCellActiveAnimation({ animationConfig }: Params = { animationConfig: {} }) {
|
||||
const { clock, state, config } = useSpring({ config: animationConfig });
|
||||
|
||||
const { isDraggingCell } = useAnimatedValues();
|
||||
const isActive = useIsActive();
|
||||
|
||||
useCode(
|
||||
() =>
|
||||
block([
|
||||
onChange(isDraggingCell, [
|
||||
// @ts-ignore Ignore
|
||||
set(config.toValue, cond(isDraggingCell, 1, 0)),
|
||||
startClock(clock),
|
||||
]),
|
||||
cond(clockRunning(clock), [
|
||||
springFill(clock, state, config),
|
||||
cond(state.finished, [stopClock(clock), set(state.finished, 0), set(state.time, 0), set(state.velocity, 0)]),
|
||||
]),
|
||||
]),
|
||||
[],
|
||||
);
|
||||
|
||||
return {
|
||||
isActive,
|
||||
onActiveAnim: state.position,
|
||||
};
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
import { useMemo } from 'react';
|
||||
import Animated, { Clock, useValue } from 'react-native-reanimated';
|
||||
import { DEFAULT_ANIMATION_CONFIG } from '../constants';
|
||||
|
||||
type Params = {
|
||||
config: Partial<Animated.SpringConfig>;
|
||||
};
|
||||
|
||||
export function useSpring({ config: configParam }: Params = { config: DEFAULT_ANIMATION_CONFIG }) {
|
||||
const toValue = useValue<number>(0);
|
||||
const clock = useMemo(() => new Clock(), []);
|
||||
|
||||
const finished = useValue<number>(0);
|
||||
const velocity = useValue<number>(0);
|
||||
const position = useValue<number>(0);
|
||||
const time = useValue<number>(0);
|
||||
|
||||
const state = useMemo(
|
||||
() => ({
|
||||
finished,
|
||||
velocity,
|
||||
position,
|
||||
time,
|
||||
}),
|
||||
[finished, velocity, position, time],
|
||||
);
|
||||
|
||||
const config = useMemo(
|
||||
() => ({
|
||||
...DEFAULT_ANIMATION_CONFIG,
|
||||
...configParam,
|
||||
toValue,
|
||||
}),
|
||||
[configParam, toValue],
|
||||
) as Animated.SpringConfig;
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
clock,
|
||||
state,
|
||||
config,
|
||||
}),
|
||||
[clock, state, config],
|
||||
);
|
||||
}
|
4
components/react-native-draggable-flatlist/index.tsx
Normal file
4
components/react-native-draggable-flatlist/index.tsx
Normal file
@ -0,0 +1,4 @@
|
||||
import DraggableFlatList from './components/DraggableFlatList';
|
||||
export * from './components/CellDecorators';
|
||||
export * from './types';
|
||||
export default DraggableFlatList;
|
222
components/react-native-draggable-flatlist/procs.ts
Normal file
222
components/react-native-draggable-flatlist/procs.ts
Normal file
@ -0,0 +1,222 @@
|
||||
import Animated, { clockRunning, not, startClock, stopClock } from 'react-native-reanimated';
|
||||
import { isWeb } from './constants';
|
||||
|
||||
const { set, cond, add, sub, block, eq, neq, and, divide, greaterThan, greaterOrEq, Value, spring, lessThan, lessOrEq, multiply } =
|
||||
Animated;
|
||||
|
||||
if (!Animated.proc) {
|
||||
throw new Error('Incompatible Reanimated version (proc not found)');
|
||||
}
|
||||
|
||||
// clock procs don't seem to work in web, not sure if there's a perf benefit to web procs anyway?
|
||||
const proc = isWeb ? <T>(cb: T) => cb : Animated.proc;
|
||||
|
||||
export const getIsAfterActive = proc((currentIndex: Animated.Node<number>, activeIndex: Animated.Node<number>) =>
|
||||
greaterThan(currentIndex, activeIndex),
|
||||
);
|
||||
|
||||
export const hardReset = proc(
|
||||
(position: Animated.Value<number>, finished: Animated.Value<number>, time: Animated.Value<number>, toValue: Animated.Value<number>) =>
|
||||
block([set(position, 0), set(finished, 0), set(time, 0), set(toValue, 0)]),
|
||||
);
|
||||
|
||||
/**
|
||||
* The in react-native-reanimated.d.ts definition of `proc` only has generics
|
||||
* for up to 10 arguments. We cast it to accept any params to avoid errors when
|
||||
* type-checking.
|
||||
*/
|
||||
type RetypedProc = (cb: (...params: any) => Animated.Node<number>) => typeof cb;
|
||||
|
||||
export const setupCell = proc(
|
||||
(
|
||||
currentIndex: Animated.Value<number>,
|
||||
size: Animated.Node<number>,
|
||||
offset: Animated.Node<number>,
|
||||
isAfterActive: Animated.Value<number>,
|
||||
prevToValue: Animated.Value<number>,
|
||||
prevSpacerIndex: Animated.Value<number>,
|
||||
activeIndex: Animated.Node<number>,
|
||||
activeCellSize: Animated.Node<number>,
|
||||
hoverOffset: Animated.Node<number>,
|
||||
spacerIndex: Animated.Value<number>,
|
||||
toValue: Animated.Value<number>,
|
||||
position: Animated.Value<number>,
|
||||
time: Animated.Value<number>,
|
||||
finished: Animated.Value<number>,
|
||||
runSpring: Animated.Node<number>,
|
||||
onFinished: Animated.Node<number>,
|
||||
isDraggingCell: Animated.Node<number>,
|
||||
placeholderOffset: Animated.Value<number>,
|
||||
prevIsDraggingCell: Animated.Value<number>,
|
||||
clock: Animated.Clock,
|
||||
disabled: Animated.Node<number>,
|
||||
) =>
|
||||
block([
|
||||
cond(
|
||||
greaterThan(activeIndex, -1),
|
||||
[
|
||||
// Only update spacer if touch is not disabled.
|
||||
// Fixes android bugs where state would update with invalid touch values on touch end.
|
||||
cond(not(disabled), [
|
||||
// Determine whether this cell is after the active cell in the list
|
||||
set(isAfterActive, getIsAfterActive(currentIndex, activeIndex)),
|
||||
|
||||
// Determining spacer index is hard to visualize, see diagram: https://i.imgur.com/jRPf5t3.jpg
|
||||
cond(
|
||||
isAfterActive,
|
||||
[
|
||||
cond(
|
||||
and(
|
||||
greaterOrEq(add(hoverOffset, activeCellSize), offset),
|
||||
lessThan(add(hoverOffset, activeCellSize), add(offset, divide(size, 2))),
|
||||
),
|
||||
set(spacerIndex, sub(currentIndex, 1)),
|
||||
),
|
||||
cond(
|
||||
and(
|
||||
greaterOrEq(add(hoverOffset, activeCellSize), add(offset, divide(size, 2))),
|
||||
lessThan(add(hoverOffset, activeCellSize), add(offset, size)),
|
||||
),
|
||||
set(spacerIndex, currentIndex),
|
||||
),
|
||||
],
|
||||
cond(lessThan(currentIndex, activeIndex), [
|
||||
cond(
|
||||
and(lessThan(hoverOffset, add(offset, size)), greaterOrEq(hoverOffset, add(offset, divide(size, 2)))),
|
||||
set(spacerIndex, add(currentIndex, 1)),
|
||||
),
|
||||
cond(
|
||||
and(greaterOrEq(hoverOffset, offset), lessThan(hoverOffset, add(offset, divide(size, 2)))),
|
||||
set(spacerIndex, currentIndex),
|
||||
),
|
||||
]),
|
||||
),
|
||||
// Set placeholder offset
|
||||
cond(eq(spacerIndex, currentIndex), [
|
||||
set(placeholderOffset, cond(isAfterActive, add(sub(offset, activeCellSize), size), offset)),
|
||||
]),
|
||||
]),
|
||||
|
||||
cond(
|
||||
eq(currentIndex, activeIndex),
|
||||
[
|
||||
// If this cell is the active cell
|
||||
cond(
|
||||
isDraggingCell,
|
||||
[
|
||||
// Set its position to the drag position
|
||||
set(position, sub(hoverOffset, offset)),
|
||||
],
|
||||
[
|
||||
// Active item, not pressed in
|
||||
|
||||
// Set value hovering element will snap to once released
|
||||
cond(prevIsDraggingCell, [
|
||||
set(toValue, sub(placeholderOffset, offset)),
|
||||
// The clock starts automatically when toValue changes, however, we need to handle the
|
||||
// case where the item should snap back to its original location and toValue doesn't change
|
||||
cond(eq(prevToValue, toValue), [
|
||||
cond(clockRunning(clock), stopClock(clock)),
|
||||
set(time, 0),
|
||||
set(finished, 0),
|
||||
startClock(clock),
|
||||
]),
|
||||
]),
|
||||
],
|
||||
),
|
||||
],
|
||||
[
|
||||
// Not the active item
|
||||
// Translate cell down if it is before active index and active cell has passed it.
|
||||
// Translate cell up if it is after the active index and active cell has passed it.
|
||||
set(
|
||||
toValue,
|
||||
cond(
|
||||
cond(isAfterActive, lessOrEq(currentIndex, spacerIndex), greaterOrEq(currentIndex, spacerIndex)),
|
||||
cond(isAfterActive, multiply(activeCellSize, -1), activeCellSize),
|
||||
0,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
// If this cell should animate somewhere new, reset its state and start its clock
|
||||
cond(neq(toValue, prevToValue), [cond(clockRunning(clock), stopClock(clock)), set(time, 0), set(finished, 0), startClock(clock)]),
|
||||
|
||||
cond(neq(prevSpacerIndex, spacerIndex), [
|
||||
cond(eq(spacerIndex, -1), [
|
||||
// Hard reset to prevent stale state bugs
|
||||
cond(clockRunning(clock), stopClock(clock)),
|
||||
hardReset(position, finished, time, toValue),
|
||||
]),
|
||||
]),
|
||||
cond(finished, [onFinished, set(time, 0), set(finished, 0)]),
|
||||
set(prevSpacerIndex, spacerIndex),
|
||||
set(prevToValue, toValue),
|
||||
set(prevIsDraggingCell, isDraggingCell),
|
||||
cond(clockRunning(clock), runSpring),
|
||||
],
|
||||
[
|
||||
// // Reset the spacer index when drag ends
|
||||
cond(neq(spacerIndex, -1), set(spacerIndex, -1)),
|
||||
cond(neq(position, 0), set(position, 0)),
|
||||
],
|
||||
),
|
||||
position,
|
||||
]),
|
||||
);
|
||||
|
||||
const betterSpring = (proc as RetypedProc)(
|
||||
(
|
||||
finished: Animated.Value<number>,
|
||||
velocity: Animated.Value<number>,
|
||||
position: Animated.Value<number>,
|
||||
time: Animated.Value<number>,
|
||||
prevPosition: Animated.Value<number>,
|
||||
toValue: Animated.Value<number>,
|
||||
damping: Animated.Value<number>,
|
||||
mass: Animated.Value<number>,
|
||||
stiffness: Animated.Value<number>,
|
||||
overshootClamping: Animated.SpringConfig['overshootClamping'],
|
||||
restSpeedThreshold: Animated.Value<number>,
|
||||
restDisplacementThreshold: Animated.Value<number>,
|
||||
clock: Animated.Clock,
|
||||
) =>
|
||||
spring(
|
||||
clock,
|
||||
{
|
||||
finished,
|
||||
velocity,
|
||||
position,
|
||||
time,
|
||||
// @ts-ignore -- https://github.com/software-mansion/react-native-reanimated/blob/master/src/animations/spring.js#L177
|
||||
prevPosition,
|
||||
},
|
||||
{
|
||||
toValue,
|
||||
damping,
|
||||
mass,
|
||||
stiffness,
|
||||
overshootClamping,
|
||||
restDisplacementThreshold,
|
||||
restSpeedThreshold,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
export function springFill(clock: Animated.Clock, state: Animated.SpringState, config: Animated.SpringConfig) {
|
||||
return betterSpring(
|
||||
state.finished,
|
||||
state.velocity,
|
||||
state.position,
|
||||
state.time,
|
||||
new Value(0),
|
||||
config.toValue,
|
||||
config.damping,
|
||||
config.mass,
|
||||
config.stiffness,
|
||||
config.overshootClamping,
|
||||
config.restSpeedThreshold,
|
||||
config.restDisplacementThreshold,
|
||||
clock,
|
||||
);
|
||||
}
|
64
components/react-native-draggable-flatlist/types.ts
Normal file
64
components/react-native-draggable-flatlist/types.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import React from 'react';
|
||||
import { FlatListProps, StyleProp, ViewStyle } from 'react-native';
|
||||
import { FlatList } from 'react-native-gesture-handler';
|
||||
import Animated from 'react-native-reanimated';
|
||||
import { DEFAULT_PROPS } from './constants';
|
||||
|
||||
export type DragEndParams<T> = {
|
||||
data: T[];
|
||||
from: number;
|
||||
to: number;
|
||||
};
|
||||
type Modify<T, R> = Omit<T, keyof R> & R;
|
||||
|
||||
type DefaultProps = Readonly<typeof DEFAULT_PROPS>;
|
||||
|
||||
export type DraggableFlatListProps<T> = Modify<
|
||||
FlatListProps<T>,
|
||||
{
|
||||
data: T[];
|
||||
activationDistance?: number;
|
||||
animationConfig?: Partial<Animated.SpringConfig>;
|
||||
autoscrollSpeed?: number;
|
||||
autoscrollThreshold?: number;
|
||||
containerStyle?: StyleProp<ViewStyle>;
|
||||
debug?: boolean;
|
||||
dragItemOverflow?: boolean;
|
||||
keyExtractor: (item: T, index: number) => string;
|
||||
onDragBegin?: (index: number) => void;
|
||||
onDragEnd?: (params: DragEndParams<T>) => void;
|
||||
onPlaceholderIndexChange?: (placeholderIndex: number) => void;
|
||||
onRelease?: (index: number) => void;
|
||||
onScrollOffsetChange?: (scrollOffset: number) => void;
|
||||
renderItem: RenderItem<T>;
|
||||
renderPlaceholder?: RenderPlaceholder<T>;
|
||||
simultaneousHandlers?: React.Ref<any> | React.Ref<any>[];
|
||||
} & Partial<DefaultProps>
|
||||
>;
|
||||
|
||||
export type RenderPlaceholder<T> = (params: { item: T; index: number }) => JSX.Element;
|
||||
|
||||
export type RenderItemParams<T> = {
|
||||
item: T;
|
||||
index?: number; // This is technically a "last known index" since cells don't necessarily rerender when their index changes
|
||||
drag: () => void;
|
||||
isActive: boolean;
|
||||
};
|
||||
|
||||
export type RenderItem<T> = (params: RenderItemParams<T>) => React.ReactNode;
|
||||
|
||||
export type AnimatedFlatListType = <T>(
|
||||
props: Animated.AnimateProps<
|
||||
FlatListProps<T> & {
|
||||
ref: React.Ref<FlatList<T>>;
|
||||
simultaneousHandlers?: React.Ref<any> | React.Ref<any>[];
|
||||
}
|
||||
>,
|
||||
) => React.ReactElement;
|
||||
|
||||
export type CellData = {
|
||||
measurements: {
|
||||
size: number;
|
||||
offset: number;
|
||||
};
|
||||
};
|
5
components/react-native-draggable-flatlist/utils.ts
Normal file
5
components/react-native-draggable-flatlist/utils.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import React from 'react';
|
||||
|
||||
// Fixes bug with useMemo + generic types:
|
||||
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/37087#issuecomment-542793243
|
||||
export const typedMemo: <T>(c: T) => T = React.memo;
|
@ -1372,7 +1372,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = BlueWallet/BlueWallet.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 700;
|
||||
CURRENT_PROJECT_VERSION = 702;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
ENABLE_BITCODE = NO;
|
||||
@ -1393,7 +1393,7 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)",
|
||||
);
|
||||
MARKETING_VERSION = 6.2.17;
|
||||
MARKETING_VERSION = 6.2.19;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@ -1421,7 +1421,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 700;
|
||||
CURRENT_PROJECT_VERSION = 702;
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
ENABLE_BITCODE = NO;
|
||||
"ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES;
|
||||
@ -1436,7 +1436,7 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)",
|
||||
);
|
||||
MARKETING_VERSION = 6.2.17;
|
||||
MARKETING_VERSION = 6.2.19;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@ -1466,7 +1466,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "TodayExtension/BlueWallet - Bitcoin Price.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 700;
|
||||
CURRENT_PROJECT_VERSION = 702;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
@ -1477,7 +1477,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 6.2.17;
|
||||
MARKETING_VERSION = 6.2.19;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.TodayExtension;
|
||||
@ -1505,7 +1505,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 700;
|
||||
CURRENT_PROJECT_VERSION = 702;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
@ -1516,7 +1516,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 6.2.17;
|
||||
MARKETING_VERSION = 6.2.19;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.TodayExtension;
|
||||
PRODUCT_NAME = "BlueWallet - Bitcoin Price";
|
||||
@ -1542,13 +1542,13 @@
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 700;
|
||||
CURRENT_PROJECT_VERSION = 702;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = Stickers/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
MARKETING_VERSION = 6.2.17;
|
||||
MARKETING_VERSION = 6.2.19;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.Stickers;
|
||||
@ -1574,13 +1574,13 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 700;
|
||||
CURRENT_PROJECT_VERSION = 702;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = Stickers/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
MARKETING_VERSION = 6.2.17;
|
||||
MARKETING_VERSION = 6.2.19;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.Stickers;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -1607,7 +1607,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 700;
|
||||
CURRENT_PROJECT_VERSION = 702;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
@ -1618,7 +1618,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 6.2.17;
|
||||
MARKETING_VERSION = 6.2.19;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.MarketWidget;
|
||||
@ -1652,7 +1652,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 700;
|
||||
CURRENT_PROJECT_VERSION = 702;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
@ -1663,7 +1663,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 6.2.17;
|
||||
MARKETING_VERSION = 6.2.19;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.MarketWidget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -1709,7 +1709,7 @@
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 ";
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
@ -1766,7 +1766,7 @@
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 ";
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
@ -1798,7 +1798,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "BlueWalletWatch Extension/BlueWalletWatch Extension.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 700;
|
||||
CURRENT_PROJECT_VERSION = 702;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
@ -1808,7 +1808,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 6.2.17;
|
||||
MARKETING_VERSION = 6.2.19;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.watch.extension;
|
||||
@ -1838,7 +1838,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 700;
|
||||
CURRENT_PROJECT_VERSION = 702;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
@ -1848,7 +1848,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 6.2.17;
|
||||
MARKETING_VERSION = 6.2.19;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.watch.extension;
|
||||
PRODUCT_NAME = "${TARGET_NAME}";
|
||||
@ -1877,13 +1877,13 @@
|
||||
CODE_SIGN_ENTITLEMENTS = BlueWalletWatch/BlueWalletWatch.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 700;
|
||||
CURRENT_PROJECT_VERSION = 702;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
IBSC_MODULE = BlueWalletWatch_Extension;
|
||||
INFOPLIST_FILE = BlueWalletWatch/Info.plist;
|
||||
MARKETING_VERSION = 6.2.17;
|
||||
MARKETING_VERSION = 6.2.19;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.watch;
|
||||
@ -1915,13 +1915,13 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 700;
|
||||
CURRENT_PROJECT_VERSION = 702;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
IBSC_MODULE = BlueWalletWatch_Extension;
|
||||
INFOPLIST_FILE = BlueWalletWatch/Info.plist;
|
||||
MARKETING_VERSION = 6.2.17;
|
||||
MARKETING_VERSION = 6.2.19;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.watch;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
@ -116,7 +116,6 @@
|
||||
<string>bluewallet</string>
|
||||
<string>lapp</string>
|
||||
<string>blue</string>
|
||||
<string>aopp</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
|
@ -22,6 +22,10 @@ RCT_EXPORT_MODULE();
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (void)removeListeners:(double)count {
|
||||
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
sharedInstance = [super init];
|
||||
return sharedInstance;
|
||||
|
@ -16,9 +16,10 @@ target 'BlueWallet' do
|
||||
#
|
||||
# Note that if you have use_frameworks! enabled, Flipper will not work and
|
||||
# you should disable these next few lines.
|
||||
use_flipper!()
|
||||
use_flipper!({ "Flipper-DoubleConversion" => "1.1.7" })
|
||||
post_install do |installer|
|
||||
react_native_post_install(installer)
|
||||
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
pod 'Bugsnag'
|
||||
plugin 'cocoapods-bugsnag'
|
||||
installer.pods_project.targets.each do |target|
|
||||
|
754
ios/Podfile.lock
754
ios/Podfile.lock
@ -1,270 +1,290 @@
|
||||
PODS:
|
||||
- boost-for-react-native (1.63.0)
|
||||
- BugsnagReactNative (7.14.2):
|
||||
- boost (1.76.0)
|
||||
- BugsnagReactNative (7.16.1):
|
||||
- React-Core
|
||||
- BVLinearGradient (2.5.6):
|
||||
- React
|
||||
- CocoaAsyncSocket (7.6.5)
|
||||
- DoubleConversion (1.1.6)
|
||||
- FBLazyVector (0.64.2)
|
||||
- FBReactNativeSpec (0.64.2):
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- RCTRequired (= 0.64.2)
|
||||
- RCTTypeSafety (= 0.64.2)
|
||||
- React-Core (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- ReactCommon/turbomodule/core (= 0.64.2)
|
||||
- Flipper (0.75.1):
|
||||
- Flipper-Folly (~> 2.5)
|
||||
- Flipper-RSocket (~> 1.3)
|
||||
- FBLazyVector (0.67.2)
|
||||
- FBReactNativeSpec (0.67.2):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.67.2)
|
||||
- RCTTypeSafety (= 0.67.2)
|
||||
- React-Core (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- Flipper (0.99.0):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- Flipper-RSocket (~> 1.4)
|
||||
- Flipper-Boost-iOSX (1.76.0.1.11)
|
||||
- Flipper-DoubleConversion (1.1.7)
|
||||
- Flipper-Folly (2.5.3):
|
||||
- boost-for-react-native
|
||||
- Flipper-Fmt (7.1.7)
|
||||
- Flipper-Folly (2.6.7):
|
||||
- Flipper-Boost-iOSX
|
||||
- Flipper-DoubleConversion
|
||||
- Flipper-Fmt (= 7.1.7)
|
||||
- Flipper-Glog
|
||||
- libevent (~> 2.1.12)
|
||||
- OpenSSL-Universal (= 1.1.180)
|
||||
- Flipper-Glog (0.3.6)
|
||||
- Flipper-PeerTalk (0.0.4)
|
||||
- Flipper-RSocket (1.3.1):
|
||||
- Flipper-Folly (~> 2.5)
|
||||
- FlipperKit (0.75.1):
|
||||
- FlipperKit/Core (= 0.75.1)
|
||||
- FlipperKit/Core (0.75.1):
|
||||
- Flipper (~> 0.75.1)
|
||||
- Flipper-RSocket (1.4.3):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- FlipperKit (0.99.0):
|
||||
- FlipperKit/Core (= 0.99.0)
|
||||
- FlipperKit/Core (0.99.0):
|
||||
- Flipper (~> 0.99.0)
|
||||
- FlipperKit/CppBridge
|
||||
- FlipperKit/FBCxxFollyDynamicConvert
|
||||
- FlipperKit/FBDefines
|
||||
- FlipperKit/FKPortForwarding
|
||||
- FlipperKit/CppBridge (0.75.1):
|
||||
- Flipper (~> 0.75.1)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (0.75.1):
|
||||
- Flipper-Folly (~> 2.5)
|
||||
- FlipperKit/FBDefines (0.75.1)
|
||||
- FlipperKit/FKPortForwarding (0.75.1):
|
||||
- FlipperKit/CppBridge (0.99.0):
|
||||
- Flipper (~> 0.99.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (0.99.0):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- FlipperKit/FBDefines (0.99.0)
|
||||
- FlipperKit/FKPortForwarding (0.99.0):
|
||||
- CocoaAsyncSocket (~> 7.6)
|
||||
- Flipper-PeerTalk (~> 0.0.4)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (0.75.1)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (0.75.1):
|
||||
- FlipperKit/FlipperKitHighlightOverlay (0.99.0)
|
||||
- FlipperKit/FlipperKitLayoutHelpers (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- FlipperKit/FlipperKitLayoutIOSDescriptors (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutHelpers
|
||||
- YogaKit (~> 1.18)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (0.75.1)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (0.75.1):
|
||||
- FlipperKit/FlipperKitLayoutPlugin (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitReactPlugin (0.75.1):
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutHelpers
|
||||
- FlipperKit/FlipperKitLayoutIOSDescriptors
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- YogaKit (~> 1.18)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (0.99.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (0.75.1):
|
||||
- FlipperKit/FlipperKitReactPlugin (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/SKIOSNetworkPlugin (0.75.1):
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/SKIOSNetworkPlugin (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitNetworkPlugin
|
||||
- fmt (6.2.1)
|
||||
- GCDWebServer (3.5.4):
|
||||
- GCDWebServer/Core (= 3.5.4)
|
||||
- GCDWebServer/Core (3.5.4)
|
||||
- glog (0.3.5)
|
||||
- libevent (2.1.12)
|
||||
- lottie-ios (3.1.9)
|
||||
- lottie-react-native (4.0.2):
|
||||
- lottie-ios (~> 3.1.8)
|
||||
- lottie-ios (3.2.3)
|
||||
- lottie-react-native (5.0.1):
|
||||
- lottie-ios (~> 3.2.3)
|
||||
- React-Core
|
||||
- OpenSSL-Universal (1.1.180)
|
||||
- PasscodeAuth (1.0.0):
|
||||
- React
|
||||
- RCT-Folly (2020.01.13.00):
|
||||
- boost-for-react-native
|
||||
- RCT-Folly (2021.06.28.00-v2):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fmt (~> 6.2.1)
|
||||
- glog
|
||||
- RCT-Folly/Default (= 2021.06.28.00-v2)
|
||||
- RCT-Folly/Default (2021.06.28.00-v2):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- fmt (~> 6.2.1)
|
||||
- glog
|
||||
- RCTRequired (0.67.2)
|
||||
- RCTTypeSafety (0.67.2):
|
||||
- FBLazyVector (= 0.67.2)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.67.2)
|
||||
- React-Core (= 0.67.2)
|
||||
- React (0.67.2):
|
||||
- React-Core (= 0.67.2)
|
||||
- React-Core/DevSupport (= 0.67.2)
|
||||
- React-Core/RCTWebSocket (= 0.67.2)
|
||||
- React-RCTActionSheet (= 0.67.2)
|
||||
- React-RCTAnimation (= 0.67.2)
|
||||
- React-RCTBlob (= 0.67.2)
|
||||
- React-RCTImage (= 0.67.2)
|
||||
- React-RCTLinking (= 0.67.2)
|
||||
- React-RCTNetwork (= 0.67.2)
|
||||
- React-RCTSettings (= 0.67.2)
|
||||
- React-RCTText (= 0.67.2)
|
||||
- React-RCTVibration (= 0.67.2)
|
||||
- React-callinvoker (0.67.2)
|
||||
- React-Core (0.67.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.67.2)
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (0.67.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- Yoga
|
||||
- React-Core/Default (0.67.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (0.67.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.67.2)
|
||||
- React-Core/RCTWebSocket (= 0.67.2)
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-jsinspector (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (0.67.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (0.67.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (0.67.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (0.67.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (0.67.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (0.67.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (0.67.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (0.67.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (0.67.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (0.67.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.67.2)
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsiexecutor (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- Yoga
|
||||
- React-CoreModules (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.67.2)
|
||||
- React-Core/CoreModulesHeaders (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-RCTImage (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-cxxreact (0.67.2):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly/Default (= 2020.01.13.00)
|
||||
- RCT-Folly/Default (2020.01.13.00):
|
||||
- boost-for-react-native
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-jsinspector (= 0.67.2)
|
||||
- React-logger (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-runtimeexecutor (= 0.67.2)
|
||||
- React-jsi (0.67.2):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCTRequired (0.64.2)
|
||||
- RCTTypeSafety (0.64.2):
|
||||
- FBLazyVector (= 0.64.2)
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- RCTRequired (= 0.64.2)
|
||||
- React-Core (= 0.64.2)
|
||||
- React (0.64.2):
|
||||
- React-Core (= 0.64.2)
|
||||
- React-Core/DevSupport (= 0.64.2)
|
||||
- React-Core/RCTWebSocket (= 0.64.2)
|
||||
- React-RCTActionSheet (= 0.64.2)
|
||||
- React-RCTAnimation (= 0.64.2)
|
||||
- React-RCTBlob (= 0.64.2)
|
||||
- React-RCTImage (= 0.64.2)
|
||||
- React-RCTLinking (= 0.64.2)
|
||||
- React-RCTNetwork (= 0.64.2)
|
||||
- React-RCTSettings (= 0.64.2)
|
||||
- React-RCTText (= 0.64.2)
|
||||
- React-RCTVibration (= 0.64.2)
|
||||
- React-callinvoker (0.64.2)
|
||||
- React-Core (0.64.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-Core/Default (= 0.64.2)
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-jsiexecutor (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (0.64.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-jsiexecutor (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- Yoga
|
||||
- React-Core/Default (0.64.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-jsiexecutor (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (0.64.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-Core/Default (= 0.64.2)
|
||||
- React-Core/RCTWebSocket (= 0.64.2)
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-jsiexecutor (= 0.64.2)
|
||||
- React-jsinspector (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (0.64.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-jsiexecutor (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (0.64.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-jsiexecutor (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (0.64.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-jsiexecutor (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (0.64.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-jsiexecutor (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (0.64.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-jsiexecutor (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (0.64.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-jsiexecutor (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (0.64.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-jsiexecutor (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (0.64.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-jsiexecutor (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (0.64.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-jsiexecutor (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (0.64.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-Core/Default (= 0.64.2)
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-jsiexecutor (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- Yoga
|
||||
- React-CoreModules (0.64.2):
|
||||
- FBReactNativeSpec (= 0.64.2)
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- RCTTypeSafety (= 0.64.2)
|
||||
- React-Core/CoreModulesHeaders (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-RCTImage (= 0.64.2)
|
||||
- ReactCommon/turbomodule/core (= 0.64.2)
|
||||
- React-cxxreact (0.64.2):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsi/Default (= 0.67.2)
|
||||
- React-jsi/Default (0.67.2):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-callinvoker (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-jsinspector (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- React-runtimeexecutor (= 0.64.2)
|
||||
- React-jsi (0.64.2):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsiexecutor (0.67.2):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-jsi/Default (= 0.64.2)
|
||||
- React-jsi/Default (0.64.2):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- React-jsinspector (0.67.2)
|
||||
- React-logger (0.67.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-jsiexecutor (0.64.2):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- React-jsinspector (0.64.2)
|
||||
- react-native-blue-crypto (1.0.0):
|
||||
- React
|
||||
- react-native-camera (4.2.1):
|
||||
@ -281,7 +301,7 @@ PODS:
|
||||
- React
|
||||
- react-native-idle-timer (2.1.6):
|
||||
- React-Core
|
||||
- react-native-image-picker (4.7.0):
|
||||
- react-native-image-picker (4.7.3):
|
||||
- React-Core
|
||||
- react-native-ios-context-menu (1.3.0):
|
||||
- React-Core
|
||||
@ -292,84 +312,85 @@ PODS:
|
||||
- react-native-tcp-socket (5.5.0):
|
||||
- CocoaAsyncSocket
|
||||
- React-Core
|
||||
- react-native-tor (0.1.7):
|
||||
- react-native-tor (0.1.8):
|
||||
- React
|
||||
- react-native-webview (11.16.0):
|
||||
- react-native-webview (11.17.2):
|
||||
- React-Core
|
||||
- react-native-widget-center (0.0.7):
|
||||
- React
|
||||
- React-perflogger (0.64.2)
|
||||
- React-RCTActionSheet (0.64.2):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.64.2)
|
||||
- React-RCTAnimation (0.64.2):
|
||||
- FBReactNativeSpec (= 0.64.2)
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- RCTTypeSafety (= 0.64.2)
|
||||
- React-Core/RCTAnimationHeaders (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- ReactCommon/turbomodule/core (= 0.64.2)
|
||||
- React-RCTBlob (0.64.2):
|
||||
- FBReactNativeSpec (= 0.64.2)
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-Core/RCTBlobHeaders (= 0.64.2)
|
||||
- React-Core/RCTWebSocket (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-RCTNetwork (= 0.64.2)
|
||||
- ReactCommon/turbomodule/core (= 0.64.2)
|
||||
- React-RCTImage (0.64.2):
|
||||
- FBReactNativeSpec (= 0.64.2)
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- RCTTypeSafety (= 0.64.2)
|
||||
- React-Core/RCTImageHeaders (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-RCTNetwork (= 0.64.2)
|
||||
- ReactCommon/turbomodule/core (= 0.64.2)
|
||||
- React-RCTLinking (0.64.2):
|
||||
- FBReactNativeSpec (= 0.64.2)
|
||||
- React-Core/RCTLinkingHeaders (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- ReactCommon/turbomodule/core (= 0.64.2)
|
||||
- React-RCTNetwork (0.64.2):
|
||||
- FBReactNativeSpec (= 0.64.2)
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- RCTTypeSafety (= 0.64.2)
|
||||
- React-Core/RCTNetworkHeaders (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- ReactCommon/turbomodule/core (= 0.64.2)
|
||||
- React-RCTSettings (0.64.2):
|
||||
- FBReactNativeSpec (= 0.64.2)
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- RCTTypeSafety (= 0.64.2)
|
||||
- React-Core/RCTSettingsHeaders (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- ReactCommon/turbomodule/core (= 0.64.2)
|
||||
- React-RCTText (0.64.2):
|
||||
- React-Core/RCTTextHeaders (= 0.64.2)
|
||||
- React-RCTVibration (0.64.2):
|
||||
- FBReactNativeSpec (= 0.64.2)
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-Core/RCTVibrationHeaders (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- ReactCommon/turbomodule/core (= 0.64.2)
|
||||
- React-runtimeexecutor (0.64.2):
|
||||
- React-jsi (= 0.64.2)
|
||||
- ReactCommon/turbomodule/core (0.64.2):
|
||||
- React-perflogger (0.67.2)
|
||||
- React-RCTActionSheet (0.67.2):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.67.2)
|
||||
- React-RCTAnimation (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.67.2)
|
||||
- React-Core/RCTAnimationHeaders (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-RCTBlob (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/RCTBlobHeaders (= 0.67.2)
|
||||
- React-Core/RCTWebSocket (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-RCTNetwork (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-RCTImage (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.67.2)
|
||||
- React-Core/RCTImageHeaders (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-RCTNetwork (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-RCTLinking (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- React-Core/RCTLinkingHeaders (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-RCTNetwork (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.67.2)
|
||||
- React-Core/RCTNetworkHeaders (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-RCTSettings (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.67.2)
|
||||
- React-Core/RCTSettingsHeaders (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-RCTText (0.67.2):
|
||||
- React-Core/RCTTextHeaders (= 0.67.2)
|
||||
- React-RCTVibration (0.67.2):
|
||||
- FBReactNativeSpec (= 0.67.2)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/RCTVibrationHeaders (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (= 0.67.2)
|
||||
- React-runtimeexecutor (0.67.2):
|
||||
- React-jsi (= 0.67.2)
|
||||
- ReactCommon/turbomodule/core (0.67.2):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2020.01.13.00)
|
||||
- React-callinvoker (= 0.64.2)
|
||||
- React-Core (= 0.64.2)
|
||||
- React-cxxreact (= 0.64.2)
|
||||
- React-jsi (= 0.64.2)
|
||||
- React-perflogger (= 0.64.2)
|
||||
- RealmJS (10.11.0):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.67.2)
|
||||
- React-Core (= 0.67.2)
|
||||
- React-cxxreact (= 0.67.2)
|
||||
- React-jsi (= 0.67.2)
|
||||
- React-logger (= 0.67.2)
|
||||
- React-perflogger (= 0.67.2)
|
||||
- RealmJS (10.12.0):
|
||||
- GCDWebServer
|
||||
- React
|
||||
- RemobileReactNativeQrcodeLocalImage (1.0.4):
|
||||
- React
|
||||
- rn-ldk (0.6.4):
|
||||
- React-Core
|
||||
- RNCAsyncStorage (1.15.15):
|
||||
- RNCAsyncStorage (1.16.1):
|
||||
- React-Core
|
||||
- RNCClipboard (1.9.0):
|
||||
- React-Core
|
||||
@ -377,17 +398,17 @@ PODS:
|
||||
- React-Core
|
||||
- RNDefaultPreference (1.4.3):
|
||||
- React
|
||||
- RNDeviceInfo (8.4.8):
|
||||
- RNDeviceInfo (8.4.9):
|
||||
- React-Core
|
||||
- RNFS (2.18.0):
|
||||
- React
|
||||
- RNGestureHandler (1.10.3):
|
||||
- RNGestureHandler (2.2.0):
|
||||
- React-Core
|
||||
- RNHandoff (0.0.3):
|
||||
- React
|
||||
- RNKeychain (8.0.0):
|
||||
- React-Core
|
||||
- RNLocalize (2.1.7):
|
||||
- RNLocalize (2.1.9):
|
||||
- React-Core
|
||||
- RNPrivacySnapshot (1.0.0):
|
||||
- React
|
||||
@ -426,12 +447,12 @@ PODS:
|
||||
- React-RCTVibration
|
||||
- ReactCommon/turbomodule/core
|
||||
- Yoga
|
||||
- RNScreens (3.10.1):
|
||||
- RNScreens (3.11.0):
|
||||
- React-Core
|
||||
- React-RCTImage
|
||||
- RNSecureKeyStore (1.0.0):
|
||||
- React
|
||||
- RNShare (7.3.2):
|
||||
- RNShare (7.3.5):
|
||||
- React-Core
|
||||
- RNSVG (12.1.1):
|
||||
- React
|
||||
@ -445,34 +466,38 @@ PODS:
|
||||
- Yoga (~> 1.14)
|
||||
|
||||
DEPENDENCIES:
|
||||
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
|
||||
- Bugsnag
|
||||
- "BugsnagReactNative (from `../node_modules/@bugsnag/react-native`)"
|
||||
- BVLinearGradient (from `../node_modules/react-native-linear-gradient`)
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
|
||||
- Flipper (~> 0.75.1)
|
||||
- Flipper (= 0.99.0)
|
||||
- Flipper-Boost-iOSX (= 1.76.0.1.11)
|
||||
- Flipper-DoubleConversion (= 1.1.7)
|
||||
- Flipper-Folly (~> 2.5.3)
|
||||
- Flipper-Fmt (= 7.1.7)
|
||||
- Flipper-Folly (= 2.6.7)
|
||||
- Flipper-Glog (= 0.3.6)
|
||||
- Flipper-PeerTalk (~> 0.0.4)
|
||||
- Flipper-RSocket (~> 1.3)
|
||||
- FlipperKit (~> 0.75.1)
|
||||
- FlipperKit/Core (~> 0.75.1)
|
||||
- FlipperKit/CppBridge (~> 0.75.1)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (~> 0.75.1)
|
||||
- FlipperKit/FBDefines (~> 0.75.1)
|
||||
- FlipperKit/FKPortForwarding (~> 0.75.1)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (~> 0.75.1)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (~> 0.75.1)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (~> 0.75.1)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (~> 0.75.1)
|
||||
- FlipperKit/FlipperKitReactPlugin (~> 0.75.1)
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.75.1)
|
||||
- FlipperKit/SKIOSNetworkPlugin (~> 0.75.1)
|
||||
- Flipper-PeerTalk (= 0.0.4)
|
||||
- Flipper-RSocket (= 1.4.3)
|
||||
- FlipperKit (= 0.99.0)
|
||||
- FlipperKit/Core (= 0.99.0)
|
||||
- FlipperKit/CppBridge (= 0.99.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (= 0.99.0)
|
||||
- FlipperKit/FBDefines (= 0.99.0)
|
||||
- FlipperKit/FKPortForwarding (= 0.99.0)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (= 0.99.0)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (= 0.99.0)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (= 0.99.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (= 0.99.0)
|
||||
- FlipperKit/FlipperKitReactPlugin (= 0.99.0)
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (= 0.99.0)
|
||||
- FlipperKit/SKIOSNetworkPlugin (= 0.99.0)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- lottie-ios (from `../node_modules/lottie-ios`)
|
||||
- lottie-react-native (from `../node_modules/lottie-react-native`)
|
||||
- OpenSSL-Universal (= 1.1.180)
|
||||
- PasscodeAuth (from `../node_modules/react-native-passcode-auth`)
|
||||
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
|
||||
@ -487,6 +512,7 @@ DEPENDENCIES:
|
||||
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
|
||||
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
||||
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
|
||||
- react-native-blue-crypto (from `../node_modules/react-native-blue-crypto`)
|
||||
- react-native-camera (from `../node_modules/react-native-camera`)
|
||||
- react-native-document-picker (from `../node_modules/react-native-document-picker`)
|
||||
@ -541,21 +567,25 @@ DEPENDENCIES:
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- boost-for-react-native
|
||||
- CocoaAsyncSocket
|
||||
- Flipper
|
||||
- Flipper-Boost-iOSX
|
||||
- Flipper-DoubleConversion
|
||||
- Flipper-Fmt
|
||||
- Flipper-Folly
|
||||
- Flipper-Glog
|
||||
- Flipper-PeerTalk
|
||||
- Flipper-RSocket
|
||||
- FlipperKit
|
||||
- fmt
|
||||
- GCDWebServer
|
||||
- libevent
|
||||
- OpenSSL-Universal
|
||||
- YogaKit
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
boost:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec"
|
||||
BugsnagReactNative:
|
||||
:path: "../node_modules/@bugsnag/react-native"
|
||||
BVLinearGradient:
|
||||
@ -596,6 +626,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsiexecutor"
|
||||
React-jsinspector:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsinspector"
|
||||
React-logger:
|
||||
:path: "../node_modules/react-native/ReactCommon/logger"
|
||||
react-native-blue-crypto:
|
||||
:path: "../node_modules/react-native-blue-crypto"
|
||||
react-native-camera:
|
||||
@ -706,91 +738,95 @@ CHECKOUT OPTIONS:
|
||||
:git: https://github.com/swiftsocket/SwiftSocket.git
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
BugsnagReactNative: 74c4786cdf6eca1e9c41509f60f6600761189e11
|
||||
boost: a7c83b31436843459a1961bfd74b96033dc77234
|
||||
BugsnagReactNative: bd1c905fb868fae8448a913b87356dbf2b02dc80
|
||||
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
|
||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||
DoubleConversion: cf9b38bf0b2d048436d9a82ad2abe1404f11e7de
|
||||
FBLazyVector: e686045572151edef46010a6f819ade377dfeb4b
|
||||
FBReactNativeSpec: d1904f6d1468c2411b99af1a8b3db52f828475b7
|
||||
Flipper: d3da1aa199aad94455ae725e9f3aa43f3ec17021
|
||||
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
|
||||
FBLazyVector: 244195e30d63d7f564c55da4410b9a24e8fbceaa
|
||||
FBReactNativeSpec: c94002c1d93da3658f4d5119c6994d19961e3d52
|
||||
Flipper: 30e8eeeed6abdc98edaf32af0cda2f198be4b733
|
||||
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
|
||||
Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41
|
||||
Flipper-Folly: 755929a4f851b2fb2c347d533a23f191b008554c
|
||||
Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b
|
||||
Flipper-Folly: 83af37379faa69497529e414bd43fbfc7cae259a
|
||||
Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6
|
||||
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
|
||||
Flipper-RSocket: 127954abe8b162fcaf68d2134d34dc2bd7076154
|
||||
FlipperKit: 8a20b5c5fcf9436cac58551dc049867247f64b00
|
||||
Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
|
||||
FlipperKit: d8d346844eca5d9120c17d441a2f38596e8ed2b9
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
GCDWebServer: 2c156a56c8226e2d5c0c3f208a3621ccffbe3ce4
|
||||
glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62
|
||||
glog: 85ecdd10ee8d8ec362ef519a6a45ff9aa27b2e85
|
||||
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
|
||||
lottie-ios: 3a3758ef5a008e762faec9c9d50a39842f26d124
|
||||
lottie-react-native: 4dff8fe8d10ddef9e7880e770080f4a56121397e
|
||||
lottie-ios: c058aeafa76daa4cf64d773554bccc8385d0150e
|
||||
lottie-react-native: a029a86e1689c86a07169c520ae770e84348cd20
|
||||
OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b
|
||||
PasscodeAuth: 3e88093ff46c31a952d8b36c488240de980517be
|
||||
RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c
|
||||
RCTRequired: 6d3e854f0e7260a648badd0d44fc364bc9da9728
|
||||
RCTTypeSafety: c1f31d19349c6b53085766359caac425926fafaa
|
||||
React: bda6b6d7ae912de97d7a61aa5c160db24aa2ad69
|
||||
React-callinvoker: 9840ea7e8e88ed73d438edb725574820b29b5baa
|
||||
React-Core: b5e385da7ce5f16a220fc60fd0749eae2c6120f0
|
||||
React-CoreModules: 17071a4e2c5239b01585f4aa8070141168ab298f
|
||||
React-cxxreact: 9be7b6340ed9f7c53e53deca7779f07cd66525ba
|
||||
React-jsi: 67747b9722f6dab2ffe15b011bcf6b3f2c3f1427
|
||||
React-jsiexecutor: 80c46bd381fd06e418e0d4f53672dc1d1945c4c3
|
||||
React-jsinspector: cc614ec18a9ca96fd275100c16d74d62ee11f0ae
|
||||
RCT-Folly: 803a9cfd78114b2ec0f140cfa6fa2a6bafb2d685
|
||||
RCTRequired: cd47794163052d2b8318c891a7a14fcfaccc75ab
|
||||
RCTTypeSafety: 393bb40b3e357b224cde53d3fec26813c52428b1
|
||||
React: dec6476bc27155b250eeadfc11ea779265f53ebf
|
||||
React-callinvoker: e5047929e80aea942e6fdd96482504ef0189ca63
|
||||
React-Core: e382655566b2b9a6e3b4f641d777b7bfdbe52358
|
||||
React-CoreModules: cf262e82fa101c0aee022b6f90d1a5b612038b64
|
||||
React-cxxreact: 69d53de3b30c7c161ba087ca1ecdffed9ccb1039
|
||||
React-jsi: ce9a2d804adf75809ce2fe2374ba3fbbf5d59b03
|
||||
React-jsiexecutor: 52beb652bbc61201bd70cbe4f0b8edb607e8da4f
|
||||
React-jsinspector: 595f76eba2176ebd8817a1fffd47b84fbdab9383
|
||||
React-logger: 23de8ea0f44fa00ee77e96060273225607fd4d78
|
||||
react-native-blue-crypto: 23f1558ad3d38d7a2edb7e2f6ed1bc520ed93e56
|
||||
react-native-camera: 3eae183c1d111103963f3dd913b65d01aef8110f
|
||||
react-native-document-picker: ec07866a30707f23660c0f3ae591d669d3e89096
|
||||
react-native-fingerprint-scanner: ac6656f18c8e45a7459302b84da41a44ad96dbbe
|
||||
react-native-idle-timer: f7f651542b39dce9b9473e4578cb64a255075f17
|
||||
react-native-image-picker: 4b090b73077c3a71b91fddc739a594feebd00184
|
||||
react-native-image-picker: 4e6008ad8c2321622affa2c85432a5ebd02d480c
|
||||
react-native-ios-context-menu: 1ccf4d6aa1c0e7dc596613eb9a36f8c0c23ca56f
|
||||
react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846
|
||||
react-native-safe-area-context: 584dc04881deb49474363f3be89e4ca0e854c057
|
||||
react-native-tcp-socket: 199889cd48b07a0238e0feb53549607de5207116
|
||||
react-native-tor: 6a64351e96ccd6a49941989703f63ec81fc1ae7c
|
||||
react-native-webview: 28a8636d97ee641f2ee8f20492d7a6c269c1d703
|
||||
react-native-tor: 3b14e9160b2eb7fa3f310921b2dee71a5171e5b7
|
||||
react-native-webview: 380c1a03ec94b7ed764dac8db1e7c9952d08c93a
|
||||
react-native-widget-center: 5e63193fce272aa3c2aa4f1a33e129b06a962f47
|
||||
React-perflogger: 25373e382fed75ce768a443822f07098a15ab737
|
||||
React-RCTActionSheet: af7796ba49ffe4ca92e7277a5d992d37203f7da5
|
||||
React-RCTAnimation: 6a2e76ab50c6f25b428d81b76a5a45351c4d77aa
|
||||
React-RCTBlob: 02a2887023e0eed99391b6445b2e23a2a6f9226d
|
||||
React-RCTImage: ce5bf8e7438f2286d9b646a05d6ab11f38b0323d
|
||||
React-RCTLinking: ccd20742de14e020cb5f99d5c7e0bf0383aefbd9
|
||||
React-RCTNetwork: dfb9d089ab0753e5e5f55fc4b1210858f7245647
|
||||
React-RCTSettings: b14aef2d83699e48b410fb7c3ba5b66cd3291ae2
|
||||
React-RCTText: 41a2e952dd9adc5caf6fb68ed46b275194d5da5f
|
||||
React-RCTVibration: 24600e3b1aaa77126989bc58b6747509a1ba14f3
|
||||
React-runtimeexecutor: a9904c6d0218fb9f8b19d6dd88607225927668f9
|
||||
ReactCommon: 149906e01aa51142707a10665185db879898e966
|
||||
RealmJS: de65cc7c3ea041750d66beaa28b30585222c3d94
|
||||
React-perflogger: 3c9bb7372493e49036f07a82c44c8cf65cbe88db
|
||||
React-RCTActionSheet: 052606483045a408693aa7e864410b4a052f541a
|
||||
React-RCTAnimation: 08d4cac13222bb1348c687a0158dfd3b577cdb63
|
||||
React-RCTBlob: 928ad1df65219c3d9e2ac80983b943a75b5c3629
|
||||
React-RCTImage: 524d7313b142a39ee0e20fa312b67277917fe076
|
||||
React-RCTLinking: 44036ea6f13a2e46238be07a67566247fee35244
|
||||
React-RCTNetwork: 9b6faacf1e0789253e319ca53b1f8d92c2ac5455
|
||||
React-RCTSettings: ecd8094f831130a49581d5112a8607220e5d12a5
|
||||
React-RCTText: 14ba976fb48ed283cfdb1a754a5d4276471e0152
|
||||
React-RCTVibration: 99c7f67fba7a5ade46e98e870c6ff2444484f995
|
||||
React-runtimeexecutor: 2450b43df7ffe8e805a0b3dcb2abd4282f1f1836
|
||||
ReactCommon: d98c6c96b567f9b3a15f9fd4cc302c1eda8e3cf2
|
||||
RealmJS: b6097dab8af3bcf1cd5fa0ac39a4e4c54980c719
|
||||
RemobileReactNativeQrcodeLocalImage: 57aadc12896b148fb5e04bc7c6805f3565f5c3fa
|
||||
rn-ldk: 94bc90bf928598dd2684a58e6949e40bb3d45c7b
|
||||
RNCAsyncStorage: 0bef6a21517c0254bd6bd59a3672963abfa0d18e
|
||||
RNCAsyncStorage: b49b4e38a1548d03b74b30e558a1d18465b94be7
|
||||
RNCClipboard: 99fc8ad669a376b756fbc8098ae2fd05c0ed0668
|
||||
RNCPushNotificationIOS: 87b8d16d3ede4532745e05b03c42cff33a36cc45
|
||||
RNDefaultPreference: 2f8d6d54230edbd78708ada8d63bb275e5a8415b
|
||||
RNDeviceInfo: 0400a6d0c94186d1120c3cbd97b23abc022187a9
|
||||
RNDeviceInfo: 4944cf8787b9c5bffaf301fda68cc1a2ec003341
|
||||
RNFS: 3ab21fa6c56d65566d1fb26c2228e2b6132e5e32
|
||||
RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211
|
||||
RNGestureHandler: bf572f552ea324acd5b5464b8d30755b2d8c1de6
|
||||
RNHandoff: d3b0754cca3a6bcd9b25f544f733f7f033ccf5fa
|
||||
RNKeychain: 4f63aada75ebafd26f4bc2c670199461eab85d94
|
||||
RNLocalize: f567ea0e35116a641cdffe6683b0d212d568f32a
|
||||
RNLocalize: 291e5e21b53cd30b5205c10ed95d31b0dc9b8d63
|
||||
RNPrivacySnapshot: 71919dde3c6a29dd332115409c2aec564afee8f4
|
||||
RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93
|
||||
RNRate: 94f57c773e155ca0d0aeeba9c10a32bce9030daf
|
||||
RNReactNativeHapticFeedback: b83bfb4b537bdd78eb4f6ffe63c6884f7b049ead
|
||||
RNReanimated: 024eff8202342abf4b24e11575a16afc441dabfe
|
||||
RNScreens: 522705f2e5c9d27efb17f24aceb2bf8335bc7b8e
|
||||
RNReanimated: e28dfaa950064b674fde0a9b736e62b9dff500a7
|
||||
RNScreens: fd535547baa4ef8aeaee1a8b1e3ffd17b8df44a4
|
||||
RNSecureKeyStore: f1ad870e53806453039f650720d2845c678d89c8
|
||||
RNShare: d76b8c9c6e6ffb38fc18f40b4338c9d867592ed3
|
||||
RNShare: 730a2773b1e0007425f2f111dcf75208a919c902
|
||||
RNSVG: 551acb6562324b1d52a4e0758f7ca0ec234e278f
|
||||
RNVectorIcons: 4143ba35feebab8fdbe6bc43d1e776b393d47ac8
|
||||
RNWatch: 99637948ec9b5c9ec5a41920642594ad5ba07e80
|
||||
SwiftSocket: c8d482e867ae4d3eb4c769e9382e123c1f1f833b
|
||||
Yoga: 575c581c63e0d35c9a83f4b46d01d63abc1100ac
|
||||
Yoga: 9b6696970c3289e8dea34b3eda93f23e61fb8121
|
||||
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
|
||||
|
||||
PODFILE CHECKSUM: 39afb2c1727531c14ee301938165dcf7a6f6ca0f
|
||||
PODFILE CHECKSUM: 53c058f42bf11a3d01891a40676ea8f9c6a9ecf9
|
||||
|
||||
COCOAPODS: 1.10.1
|
||||
|
@ -1 +1 @@
|
||||
BlueWallet Cartera de Bitcoin
|
||||
BlueWallet - Cartera de Bitcoin
|
@ -1 +1 @@
|
||||
BlueWallet portefeuille
|
||||
BlueWallet - portefeuille Bitcoin
|
@ -40,14 +40,14 @@ A partire da 1 Satoshi. Deciso da te, l'utente
|
||||
Replace-By-Fee
|
||||
(RBF) Velocizza le tue transazioni aumentando le commissioni (BIP125)
|
||||
|
||||
Watch-only wallets
|
||||
Watch-only wallets allow you to keep an eye on your cold storage without touching the hardware.
|
||||
Portafoglio watch-only
|
||||
Il portafoglio watch-only ti permette di visualizzare il tuo cold wallet senza dover inserire la seed phrase o usare l'hardware wallet
|
||||
|
||||
Lightning Network
|
||||
Wallet per Lightning Network con zero configurazioni necessarie. Per transazioni incredibilmente economiche e veloci con la miglior esperienza utente.
|
||||
|
||||
Acquista Bitcoin
|
||||
Enter in the open financial revolution with the ability to buy Bitcoin directly in your wallet.
|
||||
Partecipa alla rivoluzione finanziaria con la possibilità di comprare Bitcoin direttamente dal tuo wallet.
|
||||
|
||||
Local Trader
|
||||
A p2p Bitcoin Trading platform, that allows you to buy and sell bitcoin directly to other users without 3rd parties.
|
||||
Una piattaforma Bitcoin p2p, che ti permette di comprare e vendere bitcoin direttamente ad altri utenti senza il bisogno di 3º parti.
|
||||
|
@ -1 +1 @@
|
||||
BlueWallet Bitcoin portomonnee
|
||||
BlueWallet - Bitcoin portomonnee
|
11
loc/ar.json
11
loc/ar.json
@ -120,7 +120,7 @@
|
||||
"placeholder": "فاتورة",
|
||||
"open_channel": "فتح قناة",
|
||||
"funding_amount_placeholder": "مبلغ التمويل، على سبيل المثال 0.001",
|
||||
"opening_channnel_for_from":"جاري فتح قناة للمحفظة {forWalletLabel} بتمويل من {fromWalletLabel}",
|
||||
"opening_channnel_for_from":"جارِ فتح قناة للمحفظة {forWalletLabel} بتمويل من {fromWalletLabel}",
|
||||
"are_you_sure_open_channel": "هل أنت متأكد أنك تريد فتح هذه القناة؟",
|
||||
"are_you_sure_exit_without_new_channel": "هل أنت متأكد أنك تريد الخروج دون فتح قناة؟",
|
||||
"public": "علني",
|
||||
@ -525,6 +525,7 @@
|
||||
"no_ln_wallet_error": "قبل دفع فاتورة برق (Lightning) ، يجب عليك أولاً إضافة محفظة برق (Lightning).",
|
||||
"looks_like_bip38": "يبدوا ان هذا مفتاح خاص محمي بكلمة مرور (BIP38).",
|
||||
"reorder_title": "إعادة ترتيب المحافظ",
|
||||
"reorder_instructions": "اضغط باستمرار على اي محفظة لتحريكها عبر القائمة",
|
||||
"please_continue_scanning": "الرجاء متابعة الفحص.",
|
||||
"scan_error": "خطأ في الفحص",
|
||||
"select_no_bitcoin": "لا توجد محافظ Bitcoin متاحة حاليًا.",
|
||||
@ -625,6 +626,7 @@
|
||||
"cc": {
|
||||
"change": "تغيير",
|
||||
"coins_selected": "العملات المحددة ({number})",
|
||||
"selected_summ": "{value} مختاره",
|
||||
"empty": "لا تحتوي هذه المحفظة على أي عملات في الوقت الحالي.",
|
||||
"freeze": "تجميد",
|
||||
"freezeLabel": "تجميد",
|
||||
@ -651,17 +653,10 @@
|
||||
"sign_placeholder_address": "العنوان",
|
||||
"sign_placeholder_message": "الرسالة",
|
||||
"sign_placeholder_signature": "التوقيع",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"sign_aopp_confirm": "هل تريد إرسال رسالة موقعة إلى {hostname}؟",
|
||||
"addresses_title": "العنوان",
|
||||
"type_change": "تغيير",
|
||||
"type_receive": "استلام",
|
||||
"type_used": "مستخدم",
|
||||
"transactions": "الحوالات"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "اختر عنوانًا",
|
||||
"send_success": "تم إرسال التوقيع بنجاح",
|
||||
"send_error": "خطأ في إرسال التوقيع"
|
||||
}
|
||||
}
|
||||
|
@ -525,6 +525,7 @@
|
||||
"no_ln_wallet_error": "Před zaplacením Lightning faktury musíte nejprve přidat Lightning peněženku.",
|
||||
"looks_like_bip38": "Tohle vypadá jako soukromý klíč chráněný heslem (BIP38)",
|
||||
"reorder_title": "Seřadit peěženky",
|
||||
"reorder_instructions": "Klepněte a podržte peněženku a přetáhněte ji po seznamu.",
|
||||
"please_continue_scanning": "Pokračujte ve skenování",
|
||||
"scan_error": "Chyba skenování",
|
||||
"select_no_bitcoin": "V současné době nejsou k dispozici žádné bitcoinové peněženky.",
|
||||
@ -625,6 +626,7 @@
|
||||
"cc": {
|
||||
"change": "změnit",
|
||||
"coins_selected": "Vybrané mince ({number})",
|
||||
"selected_summ": "{value} vybráno",
|
||||
"empty": "Tato peněženka nemá v tuto chvíli žádné mince",
|
||||
"freeze": "zmrazit",
|
||||
"freezeLabel": "Zmrazit",
|
||||
@ -651,17 +653,10 @@
|
||||
"sign_placeholder_address": "Adresa",
|
||||
"sign_placeholder_message": "Zpráva",
|
||||
"sign_placeholder_signature": "Podpis",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"sign_aopp_confirm": "Chcete odeslat podepsanou zprávu na adresu {hostname}?",
|
||||
"addresses_title": "Adresy",
|
||||
"type_change": "Změnit",
|
||||
"type_receive": "Příjmout",
|
||||
"type_used": "Použité",
|
||||
"transactions": "Transakce"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "Vybrat adresu",
|
||||
"send_success": "Podpis byl úspěšně odeslán",
|
||||
"send_error": "Chyba při odesílání podpisu"
|
||||
}
|
||||
}
|
||||
|
@ -284,8 +284,5 @@
|
||||
"addresses_title": "Cyfeiriadau",
|
||||
"type_change": "Newid",
|
||||
"type_receive": "Derbyn"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "Dewis Cyfeiriad"
|
||||
}
|
||||
}
|
||||
|
@ -525,6 +525,7 @@
|
||||
"no_ln_wallet_error": "Vor Bezahlung einer Lightning Rechnung zuerst ein Lightning wallet eröffnen.",
|
||||
"looks_like_bip38": "Passwortgeschützter Privatschlüssel (BIP38) erkannt.",
|
||||
"reorder_title": "Wallets neu ordnen",
|
||||
"reorder_instructions": "Tippen und halten Sie eine Wallet, um sie umzuplatzieren.",
|
||||
"please_continue_scanning": "Bitte Scanvorgang fortsetzten",
|
||||
"scan_error": "Scanfehler",
|
||||
"select_no_bitcoin": "Es sind momentan keine Bitcoin Wallets verfügbar.",
|
||||
@ -625,6 +626,7 @@
|
||||
"cc": {
|
||||
"change": "Ändern",
|
||||
"coins_selected": "Anz. gewählte Münzen ({number})",
|
||||
"selected_summ": "{value} ausgewählt",
|
||||
"empty": "Dieses Wallet hat aktuell keine Münzen",
|
||||
"freeze": "einfrieren",
|
||||
"freezeLabel": "Einfrieren",
|
||||
@ -651,17 +653,26 @@
|
||||
"sign_placeholder_address": "Adresse",
|
||||
"sign_placeholder_message": "Meldung",
|
||||
"sign_placeholder_signature": "Signatur",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"sign_aopp_confirm": "Senden der signierten Nachricht nach {hostname}?",
|
||||
"addresses_title": "Adressen",
|
||||
"type_change": "Wechsel",
|
||||
"type_receive": "Empfang",
|
||||
"type_used": "Verwendet",
|
||||
"transactions": "Transaktionen"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "Adresse wählen",
|
||||
"send_success": "Signatur erfolgreich gesendet",
|
||||
"send_error": "Fehler beim Senden der Signatur"
|
||||
"lnurl_auth": {
|
||||
"register_question_part_1": "Möchten Sie ein Konto bei",
|
||||
"register_question_part_2": "mit Ihrem LN-Wallet registrieren?",
|
||||
"register_answer": "Konto bei {hostname} erfolgreich registriert!",
|
||||
"login_question_part_1": "Möchten Sie sich mit Ihrem LN-Wallet auf",
|
||||
"login_question_part_2": "anmelden?",
|
||||
"login_answer": "Erfolgreich angemeldet bei {hostname}!",
|
||||
"link_question_part_1": "Möchten Sie Ihr Konto auf",
|
||||
"link_question_part_2": "mit Ihrem LN-Wallet verknüpfen?",
|
||||
"link_answer": "Ihr LN-Wallet wurde erfolgreich mit Ihrem Konto bei {hostname} verknüpft!",
|
||||
"auth_question_part_1": "Möchten Sie sich mit Ihrem LN-Wallet bei",
|
||||
"auth_question_part_2": "authentifizieren?",
|
||||
"auth_answer": "Erfolgreich authentifiziert bei {hostname}!",
|
||||
"could_not_auth": "Authentifizierung bei {hostname} fehlgeschlagen.",
|
||||
"authenticate": "Authentifizieren"
|
||||
}
|
||||
}
|
||||
|
23
loc/en.json
23
loc/en.json
@ -525,6 +525,7 @@
|
||||
"no_ln_wallet_error": "Before paying a Lightning invoice, you must first add a Lightning wallet.",
|
||||
"looks_like_bip38": "This looks like a password-protected private key (BIP38).",
|
||||
"reorder_title": "Re-order Wallets",
|
||||
"reorder_instructions": "Tap and hold a wallet to drag it across the list.",
|
||||
"please_continue_scanning": "Please continue scanning.",
|
||||
"scan_error": "Scan Error",
|
||||
"select_no_bitcoin": "There are currently no Bitcoin wallets available.",
|
||||
@ -625,6 +626,7 @@
|
||||
"cc": {
|
||||
"change": "Change",
|
||||
"coins_selected": "Coins Selected ({number})",
|
||||
"selected_summ": "{value} selected",
|
||||
"empty": "This wallet doesn’t have any coins at the moment.",
|
||||
"freeze": "Freeze",
|
||||
"freezeLabel": "Freeze",
|
||||
@ -651,17 +653,26 @@
|
||||
"sign_placeholder_address": "Address",
|
||||
"sign_placeholder_message": "Message",
|
||||
"sign_placeholder_signature": "Signature",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"sign_aopp_confirm": "Do you want to send a signed message to {hostname}?",
|
||||
"addresses_title": "Addresses",
|
||||
"type_change": "Change",
|
||||
"type_receive": "Receive",
|
||||
"type_used": "Used",
|
||||
"transactions": "Transactions"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "Select Address",
|
||||
"send_success": "Signature sent successfully",
|
||||
"send_error": "Signature sending error"
|
||||
"lnurl_auth": {
|
||||
"register_question_part_1": "Do you want to register an account at ",
|
||||
"register_question_part_2": "using your LN wallet?",
|
||||
"register_answer": "Sucessfully registered an account at {hostname}!",
|
||||
"login_question_part_1": "Do you want to login at ",
|
||||
"login_question_part_2": "using your LN wallet?",
|
||||
"login_answer": "Sucessfully logged in at {hostname}!",
|
||||
"link_question_part_1": "Link your account at ",
|
||||
"link_question_part_2": "to your LN wallet?",
|
||||
"link_answer": "Your LN wallet was sucessfully linked to your account at {hostname}!",
|
||||
"auth_question_part_1": "Do you want to authenticate at ",
|
||||
"auth_question_part_2": "using your LN wallet?",
|
||||
"auth_answer": "Sucessfully authenticated at {hostname}!",
|
||||
"could_not_auth": "Could not authenticate to {hostname}.",
|
||||
"authenticate": "Authenticate"
|
||||
}
|
||||
}
|
||||
|
@ -648,17 +648,10 @@
|
||||
"sign_placeholder_address": "Dirección",
|
||||
"sign_placeholder_message": "Mensaje",
|
||||
"sign_placeholder_signature": "Firma",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"sign_aopp_confirm": "¿Quieres enviar un mensaje firmado a {hostname}?",
|
||||
"addresses_title": "Direcciones",
|
||||
"type_change": "Cambio",
|
||||
"type_receive": "Recibir",
|
||||
"type_used": "Usado",
|
||||
"transactions": "Transacciones"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "Selecciona la dirección",
|
||||
"send_success": "Firma enviada correctamente",
|
||||
"send_error": "Error al enviar la firma"
|
||||
}
|
||||
}
|
||||
|
@ -525,6 +525,7 @@
|
||||
"no_ln_wallet_error": "Antes de pagar una factura Lightning, primero debes agregar una billetera Lightning.",
|
||||
"looks_like_bip38": "Esto parece una clave privada protegida por contraseña (BIP38).",
|
||||
"reorder_title": "Reorganizar Billeteras",
|
||||
"reorder_instructions": "Toca y mantén presionada una billetera para arrastrarla por la lista.",
|
||||
"please_continue_scanning": "Por favor continúa escaneando.",
|
||||
"scan_error": "Error de Escaneo",
|
||||
"select_no_bitcoin": "Actualmente no hay billeteras Bitcoin disponibles.",
|
||||
@ -625,6 +626,7 @@
|
||||
"cc": {
|
||||
"change": "Cambio",
|
||||
"coins_selected": "Monedas Seleccionadas ({number})",
|
||||
"selected_summ": "{value} seleccionado",
|
||||
"empty": "Esta billetera no tiene monedas en este momento.",
|
||||
"freeze": "Congelar",
|
||||
"freezeLabel": "Congelar",
|
||||
@ -651,17 +653,10 @@
|
||||
"sign_placeholder_address": "Dirección",
|
||||
"sign_placeholder_message": "Mensaje",
|
||||
"sign_placeholder_signature": "Firma",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"sign_aopp_confirm": "¿Quieres enviar un mensaje firmado a {hostname}?",
|
||||
"addresses_title": "Direcciones",
|
||||
"type_change": "Cambio",
|
||||
"type_receive": "Recibir",
|
||||
"type_used": "Usado",
|
||||
"transactions": "Transacciones"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "Seleccionar dirección",
|
||||
"send_success": "Firma enviada con éxito",
|
||||
"send_error": "Error de envío de firma"
|
||||
}
|
||||
}
|
||||
|
25
loc/fa.json
25
loc/fa.json
@ -185,7 +185,7 @@
|
||||
"header": "دریافت"
|
||||
},
|
||||
"send": {
|
||||
"provided_address_is_invoice": "بهنظر میآید این آدرس یک صورتحساب لایتنینگی است. جهت پرداخت این صورتحساب لطفاً به کیف پول لایتنینگ خود بروید.",
|
||||
"provided_address_is_invoice": "بهنظر میآید این آدرس یک صورتحساب لایتنینگ است. جهت پرداخت این صورتحساب لطفاً به کیف پول لایتنینگ خود بروید.",
|
||||
"broadcastButton": "انتشار",
|
||||
"broadcastError": "خطا",
|
||||
"broadcastNone": "هگزادسیمال تراکنش را وارد کنید",
|
||||
@ -525,6 +525,7 @@
|
||||
"no_ln_wallet_error": "قبل از پرداخت یک صورتحساب لایتنینگ، ابتدا باید یک کیف پول لایتنینگ اضافه کنید.",
|
||||
"looks_like_bip38": "این به کلید خصوصی محافظتشده با گذرواژه (BIP38) شباهت دارد.",
|
||||
"reorder_title": "بازچینی کیف پولها",
|
||||
"reorder_instructions": "روی یک کیف پول بزنید و نگه دارید تا آن را در لیست جابهجا کنید.",
|
||||
"please_continue_scanning": "لطفاً به اسکنکردن ادامه دهید.",
|
||||
"scan_error": "خطا در اسکن",
|
||||
"select_no_bitcoin": "هیچ کیف پول بیتکوینی درحالحاضر دردسترس نیست.",
|
||||
@ -625,6 +626,7 @@
|
||||
"cc": {
|
||||
"change": "باقیمانده (change)",
|
||||
"coins_selected": "کوینهای انتخابشده ({number})",
|
||||
"selected_summ": "انتخابشده: {value}",
|
||||
"empty": "این کیف پول درحالحاضر هیچ کوینی ندارد.",
|
||||
"freeze": "مسدود",
|
||||
"freezeLabel": "مسدودکردن",
|
||||
@ -651,17 +653,26 @@
|
||||
"sign_placeholder_address": "آدرس",
|
||||
"sign_placeholder_message": "پیام",
|
||||
"sign_placeholder_signature": "امضا",
|
||||
"sign_aopp_title": "پروتکل اثبات مالکیت آدرس (AOPP)",
|
||||
"sign_aopp_confirm": "آیا مایل به ارسال پیام امضاشده به {hostname} هستید؟",
|
||||
"addresses_title": "آدرسها",
|
||||
"type_change": "باقیمانده",
|
||||
"type_receive": "دریافت",
|
||||
"type_used": "استفادهشده",
|
||||
"transactions": "تراکنشها"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "انتخاب آدرس",
|
||||
"send_success": "امضا با موفقیت ارسال شد.",
|
||||
"send_error": "خطا در ارسال امضا"
|
||||
"lnurl_auth": {
|
||||
"register_question_part_1": "آیا میخواهید حسابی در",
|
||||
"register_question_part_2": "با استفاده از کیف پول لایتنینگ خود بسازید؟",
|
||||
"register_answer": "حساب در {hostname} با موفقیت ساخته شد!",
|
||||
"login_question_part_1": "آیا میخواهید در",
|
||||
"login_question_part_2": "با استفاده از کیف پول لایتنینگ خود وارد شوید؟",
|
||||
"login_answer": "با موفقیت در {hostname} وارد شدید!",
|
||||
"link_question_part_1": "حسابتان در",
|
||||
"link_question_part_2": "به کیف پول لایتنینگ شما متصل شود؟",
|
||||
"link_answer": "کیف پول لایتنینگ شما با موفقیت به حسابتان در {hostname} متصل شد!",
|
||||
"auth_question_part_1": "آیا میخواهید در",
|
||||
"auth_question_part_2": "با استفاده از کیف پول لایتنینگ خود احراز کنید؟",
|
||||
"auth_answer": "احراز در {hostname} با موفقیت انجام شد!",
|
||||
"could_not_auth": "احراز در {hostname} انجام نشد.",
|
||||
"authenticate": "احراز"
|
||||
}
|
||||
}
|
||||
|
152
loc/fi_fi.json
152
loc/fi_fi.json
@ -3,8 +3,10 @@
|
||||
"bad_password": "Väärä salasana, yritä uudelleen.",
|
||||
"cancel": "Peruuta",
|
||||
"continue": "Jatka",
|
||||
"clipboard": "Leikepöytä",
|
||||
"enter_password": "Anna salasana",
|
||||
"never": "ei koskaan",
|
||||
"disabled": "Poissa käytöstä",
|
||||
"of": "{number} / {total}",
|
||||
"ok": "OK",
|
||||
"storage_is_encrypted": "Tallennustilasi on salattu. Sen purkamiseksi vaaditaan salasana",
|
||||
@ -16,10 +18,18 @@
|
||||
"seed": "Siemen",
|
||||
"success": "Onnistui",
|
||||
"wallet_key": "Lompakkoavain",
|
||||
"invalid_animated_qr_code_fragment": "Virheellinen animoitu QRCode-fragmentti, yritä uudelleen",
|
||||
"invalid_animated_qr_code_fragment" : "Virheellinen animoitu QRCode-fragmentti, yritä uudelleen",
|
||||
"file_saved": "Tiedosto {filePath} on talletettu sinun {destination}.",
|
||||
"file_save_title": "Tallenna tiedosto",
|
||||
"file_save_location": "Valitse tallennus sijainti {filePath}",
|
||||
"downloads_folder": "Lataukset-kansio",
|
||||
"external_storage": "Ulkoinen tallennuslaite",
|
||||
"discard_changes": "Hylkää muutokset?",
|
||||
"discard_changes_detail": "Sinulla on tallentamattomia muutoksia. Haluatko varmasti hylätä ne ja poistut näytöltä? "
|
||||
},
|
||||
"alert": {
|
||||
"default": "Hälytys"
|
||||
},
|
||||
"azteco": {
|
||||
"codeIs": "Kuponkikoodisi on",
|
||||
"errorBeforeRefeem": "Ennen lunastamista sinun on ensin lisättävä Bitcoin-lompakko",
|
||||
@ -92,20 +102,45 @@
|
||||
"p2p": "Osta Bitcoinia p2p-pörssistä "
|
||||
},
|
||||
"lnd": {
|
||||
"active":"Aktiivinen",
|
||||
"inactive":"Passiivinen",
|
||||
"channels": "Kanavat",
|
||||
"no_channels": "Ei kanavia",
|
||||
"claim_balance": "Lunasta saldo {balance}",
|
||||
"close_channel": "Sulje kanava",
|
||||
"new_channel" : "Uusi kanava",
|
||||
"errorInvoiceExpired": "Lasku vanheni",
|
||||
"exchange": "Vaihto",
|
||||
"force_close_channel": "Pakota kanavan sulku?",
|
||||
"expired": "Erääntynyt",
|
||||
"node_alias": "Solmun lempinimi",
|
||||
"expiredLow": "erääntynyt",
|
||||
"expiresIn": "Vanhenee {time} minuutissa",
|
||||
"payButton": "Maksa",
|
||||
"placeholder": "Lasku",
|
||||
"open_channel": "Avaa kanava",
|
||||
"funding_amount_placeholder": "Rahoitettava määrä, esimerkiksi 0.001",
|
||||
"opening_channnel_for_from":"Ota rahoitus {fromWalletLabel}:sta kanavan avaamiseksi lompakkoon {forWalletLabel}",
|
||||
"are_you_sure_open_channel": "Oletko varma että haluat avata tämän kanavan?",
|
||||
"are_you_sure_exit_without_new_channel": "Oletko varma että haluat poistua avaamatta kanavaa?",
|
||||
"public": "Julkinen",
|
||||
"public_description": "Verkkoon näkyvä: Se voi olla reitittävä solmu ja kerätä maksuja",
|
||||
"private": "Yksityinen",
|
||||
"private_description": "Verkossa näkymätön: Se suojaa maksujesi yksityisyyttä.",
|
||||
"local_reserve": "Paikallinen varanto",
|
||||
"potentialFee": "Mahdollinen siirtokulu: {fee}",
|
||||
"remote_host": "Etäpalvelin",
|
||||
"refill": "Täytä",
|
||||
"refill_card": "Täytä pankkikortilla",
|
||||
"reconnect_peer": "Palauta yhteys naapuriin",
|
||||
"refill_create": "Jatka luomalla Bitcoin-lompakko, jolla voit täyttää sen.",
|
||||
"refill_external": "Täytä ulkoisella lompakolla",
|
||||
"refill_lnd_balance": "Täytä Lightning-lompakon saldoa",
|
||||
"sameWalletAsInvoiceError": "Et voi maksaa laskua samalla lompakolla, jolla se on luotu.",
|
||||
"title": "hallinnoi varoja"
|
||||
"title": "hallinnoi varoja",
|
||||
"can_send": "Lähetettävissä",
|
||||
"can_receive": "Vastaanotettavissa",
|
||||
"view_logs": "Näytä lokitiedot"
|
||||
},
|
||||
"lndViewInvoice": {
|
||||
"additional_info": "Lisäinformaatio",
|
||||
@ -113,6 +148,7 @@
|
||||
"lightning_invoice": "Lightning-lasku",
|
||||
"has_been_paid": "Tämä lasku on maksettu",
|
||||
"open_direct_channel": "Avaa suora kanava tällä solmulla:",
|
||||
"please_pay_between_and": "Maksa vähintään {min} ja enintään {max}",
|
||||
"please_pay": "Ole hyvä ja maksa",
|
||||
"preimage": "Alkukuva",
|
||||
"sats": "sattia",
|
||||
@ -134,8 +170,12 @@
|
||||
"ask": "Oletko tallentanut lompakon varmuuskopion? Tämä varmuuskopio vaaditaan varojen käyttämiseen, jos kadotat tämän laitteen. Ilman varmuuskopiota varat menetetään lopullisesti.",
|
||||
"ask_no": "Ei, en ole",
|
||||
"ask_yes": "Kyllä, olen",
|
||||
"ok": "OK, kirjoitin sen ylös",
|
||||
"ok_lnd": "OK, Olen tallettanut sen",
|
||||
"text": "Varaa hetki aikaa ja kirjoita palautuslause (mnemonic) talteen paperille.\nSe on varmuuskopiosi ja voit käyttää sitä lompakon palauttamiseen.",
|
||||
"text_lnd": "Tallenna tämä lompakon varmuuskopio. Sen avulla voit palauttaa lompakon, jos lompakko katoaa.",
|
||||
"text_lnd2": "Tätä lompakkoa ylläpitää BlueWallet."
|
||||
"text_lnd2": "Tätä lompakkoa ylläpitää BlueWallet.",
|
||||
"title": "Lompakkosi on luotu"
|
||||
},
|
||||
"receive": {
|
||||
"details_create": "Luo",
|
||||
@ -145,6 +185,7 @@
|
||||
"header": "Vastaanota"
|
||||
},
|
||||
"send": {
|
||||
"provided_address_is_invoice": "Tämä osoite vaikuttaa olevan Lightning-lasku. Maksun suorittamiseksi, siirry Lightning-lompakkoosi.",
|
||||
"broadcastButton": "LÄHETÄ",
|
||||
"broadcastError": "virhe",
|
||||
"broadcastNone": "Syötä siirtotapahtuman tiiviste",
|
||||
@ -158,7 +199,7 @@
|
||||
"create_details": "Tarkemmat tiedot",
|
||||
"create_fee": "Siirtokulu",
|
||||
"create_memo": "Muistio",
|
||||
"create_satoshi_per_byte": "Satoshia per tavu",
|
||||
"create_satoshi_per_vbyte": "satoshia per vbyte",
|
||||
"create_this_is_hex": "Tämä on siirtotapahtuman hex, allekirjoitettu ja valmis lähetettävksi verkkoon.",
|
||||
"create_to": "Vastaanottaja",
|
||||
"create_tx_size": "Siirtotapahtuman koko",
|
||||
@ -170,17 +211,22 @@
|
||||
"details_adv_fee_bump": "Salli Siirtokulun Nosto",
|
||||
"details_adv_full": "Käytä koko saldo",
|
||||
"details_adv_full_sure": "Haluatko varmasti käyttää lompakon koko saldon tähän siirtotapahtumaan?",
|
||||
"details_adv_full_sure_frozen": "Haluatko varmasti käyttää koko lompakkosi saldon tähän tapahtumaan? Huomioithan että jäädytetyt kolikot jäävät tapahtuman ulkopuolelle.",
|
||||
"details_adv_import": "Tuo Siirtotapahtuma",
|
||||
"details_adv_import_qr": "Tuo tapahtuma (QR)",
|
||||
"details_amount_field_is_not_valid": "Määrä ei kelpaa",
|
||||
"details_amount_field_is_less_than_minimum_amount_sat": "Määritetty määrä on liian pieni. Anna summa, joka on yli 500 sattia. ",
|
||||
"details_create": "Luo Lasku",
|
||||
"details_error_decode": "Bitcoin-osoitetta ei voida dekoodata ",
|
||||
"details_fee_field_is_not_valid": "Siirtokulukenttä ei ole pätevä",
|
||||
"details_frozen": "{amount} BTC on jäädytetty",
|
||||
"details_next": "Seuraava",
|
||||
"details_no_signed_tx": "Valittu tiedosto ei sisällä tuotavaa siirtotapahtumaa.",
|
||||
"details_note_placeholder": "muistiinpano itselle",
|
||||
"details_scan": "Skannaa",
|
||||
"details_scan_hint": "Scannaa tai tuo tupla-napauttamalla",
|
||||
"details_total_exceeds_balance": "Lähetettävä summa ylittää katteen",
|
||||
"details_total_exceeds_balance_frozen": "Lähetettävä määrä ylittää käytettävissä olevan saldon. Huomioithan että jäädytetyt kolikot jäävät tapahtuman ulkopuolelle.",
|
||||
"details_unrecognized_file_format": "Tunnistamaton tiedostomuoto ",
|
||||
"details_wallet_before_tx": "Ennen siirtotapahtuman luomista, sinun on ensin lisättävä Bitcoin-lompakko.",
|
||||
"dynamic_init": "Alustaa",
|
||||
@ -194,8 +240,8 @@
|
||||
"fee_custom": "Mukautettu",
|
||||
"fee_fast": "Nopea",
|
||||
"fee_medium": "Keskitaso",
|
||||
"fee_replace_min": "Maksettavan kokonaiskulun (satoshia tavua kohti) tulisi olla korkeampi kuin {min} sat/tavu",
|
||||
"fee_satbyte": "sat/tavu",
|
||||
"fee_replace_minvb": "Kulujen maksimimäärä (satoshia / vByte) jonka olet valmis maksamaan, tulee olla enemmän kuin {min} satoshia / vByte.",
|
||||
"fee_satvbyte": "sat/vByte",
|
||||
"fee_slow": "Hidas",
|
||||
"header": "Lähetä",
|
||||
"input_clear": "Tyhjää",
|
||||
@ -208,15 +254,19 @@
|
||||
"open_settings": "Avaa Asetukset",
|
||||
"permission_storage_later": "Kysy Minulta Myöhemmin",
|
||||
"permission_storage_message": "BlueWallet tarvitsee lupasi käyttääkseen tallennustilaasi tämän tiedoston tallentamiseksi.",
|
||||
"permission_storage_denied_message": "BlueWallet ei voi tallentaa tätä tiedostoa. Avaa laitteen asetukset ja ota Tallennusoikeus käyttöön.",
|
||||
"permission_storage_denied_message": "BlueWallet ei voinut tallettaa tätä tiedostoa. Aseta laitteesi sallimaan tallentaminen kyttkemällä Storage Permission päälle.",
|
||||
"permission_storage_title": "Tallennustilan käyttöoikeus",
|
||||
"psbt_clipboard": "Kopioi Leikepöydälle",
|
||||
"psbt_this_is_psbt": "Tämä on osittain allekirjoitettu bitcoin-siirtotapahtuma (PSBT). Ole hyvä ja allekirjoita se hardware-lompakolla.",
|
||||
"psbt_tx_export": "Vie tiedostoon",
|
||||
"no_tx_signing_in_progress": "Siirtotapahtuman allekirjoittamista ei ole käynnissä",
|
||||
"outdated_rate": "Vaihtokurssi päivitettiin viimeksi: {date}",
|
||||
"psbt_tx_open": "Avaa Allekirjoitettu Siirtotapahtuma",
|
||||
"psbt_tx_scan": "Skannaa Allekirjoitettu Siirtotapahtuma",
|
||||
"qr_error_no_qrcode": "Kuvasta ei löytynyt QR-koodia. Varmista että kuva sisältää ainoastaan QR-koodin eikä muita tietoja kuten tekstia tai nappeja.",
|
||||
"qr_error_no_wallet": "Valittu tiedosto ei sisällä tuotavaa lompakkoa.",
|
||||
"reset_amount": "Nollaa määrä",
|
||||
"reset_amount_confirm": "Haluaisitko nollata määrän?",
|
||||
"success_done": "Valmis",
|
||||
"txSaved": "Siirtotapahtumatiedosto ({filePath}) on tallennettu Lataukset-kansioon.",
|
||||
"problem_with_psbt": "Ongelma PSBT:n kanssa"
|
||||
@ -230,6 +280,7 @@
|
||||
"about_release_notes": "Julkaisutiedot",
|
||||
"about_review": "Jätä meille arvostelu",
|
||||
"about_selftest": "Suorita itsetestaus",
|
||||
"about_selftest_electrum_disabled": "Electrum Self-Test toimintoa ei ole mahdollista käyttää offline-tilassa. Siirry pois offline-tilasta ja yritä uudelleen",
|
||||
"about_selftest_ok": "Kaikki sisäiset testit on läpäisty onnistuneesti. Lompakko toimii hyvin. ",
|
||||
"about_sm_github": "GitHub",
|
||||
"about_sm_discord": "Discord-serveri",
|
||||
@ -243,16 +294,26 @@
|
||||
"biom_remove_decrypt": "Kaikki lompakot poistetaan ja tallennustilasi puretaan. Haluatko varmasti jatkaa?",
|
||||
"currency": "Valuutta",
|
||||
"currency_source": "Hinnat saadaan",
|
||||
"currency_fetch_error": "Valitu valuutan vaihtokurssin hakemisessa tapahtui virhe.",
|
||||
"default_desc": "Kun on pois käytöstä, BlueWallet avaa valitun lompakon heti käynnistettäessä.",
|
||||
"default_info": "Oletustiedot",
|
||||
"default_title": "Käynnistettäessä",
|
||||
"default_wallets": "Näytä Kaikki Lompakot",
|
||||
"electrum_connected": "Yhdistetty",
|
||||
"electrum_connected_not": "Ei yhteyttä",
|
||||
"electrum_connnected_not_description": "Lompakon tuonti edellyttää Electrum-palvelinyhteyttä. Kytke yhteys päälle Asetuksien Verkko -osiosta.",
|
||||
"electrum_error_connect": "Ei voida yhdistää tarjottuun Electrum-palvelimeen",
|
||||
"lndhub_uri": "esim, {example}",
|
||||
"electrum_host": "esim, {example}",
|
||||
"electrum_offline_mode": "Offline-tila",
|
||||
"electrum_offline_description": "Jos tämä on valittuna, niin bitcoin-lompakkojen saldoja ja tapahtumia ei yritetä hakea.",
|
||||
"electrum_port": "Portti, yleensä {example}",
|
||||
"use_ssl": "Käytä SSL",
|
||||
"electrum_saved": "Muutoksesi on tallennettu onnistuneesti. Uudelleenkäynnistys voi olla tarpeen, jotta muutokset tulevat voimaan.",
|
||||
"set_electrum_server_as_default": "Asetetaanko {server} oletus Electrum-palvelimeksi?",
|
||||
"set_lndhub_as_default": "Asetetaanko {url} oletus LNDHub-palvelimeksi?",
|
||||
"electrum_settings_server": "Electrum-palvelin",
|
||||
"electrum_settings_explain": "Jos haluat käyttää oletusta, jätä tämä tyhjäksi.",
|
||||
"electrum_status": "Tila",
|
||||
"electrum_clear_alert_title": "Tyhjennä historia?",
|
||||
"electrum_clear_alert_message": "Haluatko tyhjentää Electrum-palvelinten historian?",
|
||||
@ -264,6 +325,8 @@
|
||||
"electrum_history": "Palvelimen historia",
|
||||
"electrum_reset_to_default": "Haluatko varmasti palauttaa Electrumin asetukset oletusarvoihin? ",
|
||||
"electrum_clear": "Tyhjennä",
|
||||
"tor_supported": "Tor on tuettu",
|
||||
"tor_unsupported": "Tor yhteyksiä ei tueta",
|
||||
"encrypt_decrypt": "Pura tallennustilan salaus",
|
||||
"encrypt_decrypt_q": "Haluatko varmasti purkaa tallennustilan salauksen? Tämä mahdollistaa lompakkoihisi pääsyn ilman salasanaa.",
|
||||
"encrypt_del_uninstall": "Poista, jos BlueWallet poistetaan",
|
||||
@ -271,7 +334,7 @@
|
||||
"encrypt_title": "Tietoturva",
|
||||
"encrypt_tstorage": "tallennustila",
|
||||
"encrypt_use": "Käytä {type}",
|
||||
"encrypt_use_expl": "{type} käytetään henkilöllisyytesi vahvistamiseen ennen siirtotapahtuman tekemistä, lompakon lukituksen avaamista, vientiä tai poistamista. {type} ei käytetä salatun tallennustilan lukituksen avaamiseen.",
|
||||
"encrypt_use_expl": "Ennen tapahtumia, avaamista vientiä tai lompakon poistoa identiteettis varmistetaan {type}:lla. {type} ei kuitenkaan voi käyttää salatun tallennustilan avaamiseen.",
|
||||
"general": "Yleinen",
|
||||
"general_adv_mode": "Lisäasetukset",
|
||||
"general_adv_mode_e": "Kun tämä asetus on käytössä, näet lisäasetukset, kuten erilaiset lompakkotyypit, kyvyn määrittää LNDHub-instanssi, johon haluat muodostaa yhteyden ja mukautetun entropian lompakon luomisen aikana.",
|
||||
@ -280,16 +343,19 @@
|
||||
"groundcontrol_explanation": "GroundControl on ilmainen avoimen lähdekoodin push-ilmoituspalvelin bitcoin-lompakoille. Voit asentaa oman GroundControl-palvelimen ja laittaa sen URL-osoitteen tähän, jotta et luota BlueWallet-infrastruktuuriin. Jätä tyhjäksi käyttääksesi oletusasetusta",
|
||||
"header": "asetukset",
|
||||
"language": "Kieli",
|
||||
"last_updated": "Päivitetty viimeksi",
|
||||
"language_isRTL": "BlueWallet on käynnistettävä uudelleen, jotta kielisuuntaus tulee voimaan.",
|
||||
"lightning_error_lndhub_uri": "LndHub-URI ei kelpaa",
|
||||
"lightning_error_lndhub_uri": "Virheellinen LNDHub URI",
|
||||
"lightning_saved": "Muutoksesi on tallennettu onnistuneesti",
|
||||
"lightning_settings": "Lightning-Asetukset",
|
||||
"tor_settings": "Tor-asetukset",
|
||||
"lightning_settings_explain": "Oman LND-solmun käyttö edellyttää että, siihen on asennettu LNDHub-ohjelmisto ja sen URL on määritelty tähän. Kentän ollessa tyhjä on käytössä BleaWallet:in oma LNDHub (lndhub.io). Huomaathan että asetusten tallettamisen jälkeen luodut lompakot yhdistäytyvät määriteltyyn solmuun.",
|
||||
"network": "Verkko",
|
||||
"network_broadcast": "Lähetä siirtotapahtuma",
|
||||
"network_electrum": "Electrum-palvelin",
|
||||
"not_a_valid_uri": "URI ei kelpaa",
|
||||
"not_a_valid_uri": "Virheellinen URI",
|
||||
"notifications": "Ilmoitukset",
|
||||
"open_link_in_explorer": "Avaa linkki selaimessa",
|
||||
"open_link_in_explorer" : "Avaa linkki selaimessa",
|
||||
"password": "Salasana",
|
||||
"password_explain": "Luo salasana, jota käytät tallennustilan salauksen purkamiseen",
|
||||
"passwords_do_not_match": "Salasanat eivät täsmää",
|
||||
@ -301,12 +367,15 @@
|
||||
"privacy_quickactions": "Lompakon Pikanäppäimet",
|
||||
"privacy_quickactions_explanation": "Kosketa ja pidä Aloitusnäytön BlueWallet-sovelluskuvaketta nähdäksesi nopeasti lompakon saldon.",
|
||||
"privacy_clipboard_explanation": "Toimita pikakuvakkeet, jos leikepöydältä löytyy osoite tai lasku.",
|
||||
"privacy_do_not_track": "Poista analytiikka käytöstä",
|
||||
"privacy_do_not_track_explanation": "Suorituskyky- ja luotettavuustietoja ei lähtetä analysoitavaksi.",
|
||||
"push_notifications": "Push-ilmoitukset",
|
||||
"rate": "Vaihtokurssi",
|
||||
"retype_password": "Salasana uudelleen",
|
||||
"selfTest": "Itsetestaus ",
|
||||
"save": "Tallenna",
|
||||
"saved": "Tallennettu",
|
||||
"success_transaction_broadcasted": "Onnistui! Siirtotapahtumasi on lähetetty!",
|
||||
"success_transaction_broadcasted" : "Tapahtumasi on lähetetty onnistuneesti.",
|
||||
"total_balance": "Kokonaissaldo",
|
||||
"total_balance_explanation": "Näytä kaikkien lompakoiden kokonaissaldo aloitusnäytön widgeteissä.",
|
||||
"widgets": "Widgetit",
|
||||
@ -322,9 +391,8 @@
|
||||
"cancel_no": "Tämä siirtotapahtuma ei ole vaihdettavissa",
|
||||
"cancel_title": "Peruuta tämä siirtotapahtuma (RBF)",
|
||||
"confirmations_lowercase": "{confirmations} vahvistukset",
|
||||
"note": "Huomautus",
|
||||
"copy_link": "Kopioi linkki",
|
||||
"expand_note": "Laajenna huomautus",
|
||||
"block_explorer_link": "Lohkoselain-linkki",
|
||||
"cpfp_create": "Luo",
|
||||
"cpfp_exp": "Luomme toisen siirtotapahtuman, joka kuluttaa vahvistamattoman siirtotapahtuman. Kokonaiskulu on suurempi kuin alkuperäinen siirtokulu, joten sen pitäisi olla louhittu nopeammin. Tätä kutsutaan CPFP - Child Pays For Parent - Lapsi Maksaa Vanhemmalle.",
|
||||
"cpfp_no_bump": "Tämä siirtotapahtuma ei ole nostettavissa",
|
||||
@ -333,6 +401,10 @@
|
||||
"details_balance_show": "Näytä Saldo",
|
||||
"details_block": "Lohkon järjestysnumero",
|
||||
"details_copy": "Kopioi",
|
||||
"details_copy_amount": "Kopioi määrä",
|
||||
"details_copy_block_explorer_link": "Kopioi linkki lohkoketjuselaimeen",
|
||||
"details_copy_note": "Kopioi muistiinpanot",
|
||||
"details_copy_txid": "Kopioi tapahtumatunnus",
|
||||
"details_from": "Syöte",
|
||||
"details_inputs": "Syötteet",
|
||||
"details_outputs": "Ulostulot",
|
||||
@ -345,7 +417,13 @@
|
||||
"enable_offline_signing": "Tätä lompakkoa ei käytetä offline-allekirjoituksen yhteydessä. Haluatko ottaa sen käyttöön nyt? ",
|
||||
"list_conf": "conf: {number}",
|
||||
"pending": "Odottaa",
|
||||
"pending_with_amount": "Odottaa {amt1} ({amd2})",
|
||||
"received_with_amount": "+{amt1} ({amd2})",
|
||||
"eta_10m": "Saapuu n.10 minuutissa",
|
||||
"eta_3h": "Saapuu n.3 tunnissa",
|
||||
"eta_1d": "Saapuu noin vuorokaudessa",
|
||||
"list_title": "siirtotapahtumat",
|
||||
"open_url_error": "URL-osoiteen avaaminen oletusselaimella ei onnistunut. Vaihda käyttämäsi selaimen oletusasetus ja yritä uudelleen.",
|
||||
"rbf_explain": "Korvaamme tämän siirtotapahtuman toisella jossa on korkeammat siirtokulut, joten se pitäisi olla louhittu nopeammin. Tätä kutsutaan RBF - Replace By Fee - Korvattavissa korkeammilla kuluilla.",
|
||||
"rbf_title": "Nosta siirtokuluja (RBF)",
|
||||
"status_bump": "Nosta siirtokuluja",
|
||||
@ -365,12 +443,14 @@
|
||||
"add_lightning": "Lightning",
|
||||
"add_lightning_explain": "Käytetään välittömiin siirtotapahtumiin",
|
||||
"add_lndhub": "Yhdistä LNDHub:iisi",
|
||||
"add_lndhub_error": "Annettu solmun osoite ei ole kelvollinen LNDHub-solmu.",
|
||||
"add_lndhub_error": "Annettu solmun osoite ei ole kelvollinen LNDHub solmu",
|
||||
"add_lndhub_placeholder": "solmusi osoite",
|
||||
"add_or": "tai",
|
||||
"add_placeholder": "minun lompakkoni",
|
||||
"add_title": "lisää lompakko",
|
||||
"add_wallet_name": "nimi",
|
||||
"add_wallet_type": "tyyppi",
|
||||
"balance": "Saldo",
|
||||
"clipboard_bitcoin": "Sinulla on leikepöydällä Bitcoin-osoite. Haluatko käyttää sitä siirtotapahtumaan?",
|
||||
"clipboard_lightning": "Leikepöydälläsi on Lightning Invoice. Haluatko käyttää sitä siirtotapahtumaan?",
|
||||
"details_address": "Osoite",
|
||||
@ -378,7 +458,7 @@
|
||||
"details_are_you_sure": "Oletko varma?",
|
||||
"details_connected_to": "Yhdistetty",
|
||||
"details_del_wb_err": "Annettu saldo ei vastaa tämän lompakon saldoa. Yritä uudelleen",
|
||||
"details_del_wb_q": "Tällä lompakolla on saldoa. Ennen kuin jatkat, huomaa, että et voi palauttaa varoja ilman tämän lompakon siemenlauseketta. Syötä lompakkosi saldo {balance} satoshia välttääksesi vahingossa tämän lompakon poistamisen.",
|
||||
"details_del_wb_q": "Lompakossa on varoja. Ennenkuin jatkat, ymmärrä että tarvitset lompakon palautukseen tulevaisuudeessa palautuslauseen. Varmistaaksemme ettet tuhoa lompakkoa vahingossa, tulee sinun syöttää saldosi {balance} satosheina.",
|
||||
"details_delete": "Poista",
|
||||
"details_delete_wallet": "Poista lompakko",
|
||||
"details_derivation_path": "johdantopolku",
|
||||
@ -393,6 +473,7 @@
|
||||
"details_no_cancel": "Ei, peruuta",
|
||||
"details_save": "Tallenna",
|
||||
"details_show_xpub": "Näytä lompakon XPUB",
|
||||
"details_show_addresses": "Näytä osoitteet",
|
||||
"details_title": "Lompakko",
|
||||
"details_type": "Tyyppi",
|
||||
"details_use_with_hardware_wallet": "Käytä hardware-lompakon kanssa",
|
||||
@ -401,15 +482,28 @@
|
||||
"enter_bip38_password": "Syötä salasana salauksen purkamiseksi",
|
||||
"export_title": "lompakon vienti",
|
||||
"import_do_import": "Tuo",
|
||||
"import_passphrase": "tunnuslause",
|
||||
"import_passphrase_title": "tunnuslause",
|
||||
"import_passphrase_message": "Anna tunnuslause, mikäli olet käyttänyt sellaista",
|
||||
"import_error": "Tuonti epäonnistui. Varmista, että annettu tieto on oikein",
|
||||
"import_explanation": "Kirjoita siemensanasi, julkinen avain, WIF tai mikä tahansa sinulla on. BlueWallet tekee parhaansa arvatakseen oikean formaatin ja tuodakseen lompakkosi. ",
|
||||
"import_file": "Tuo tiedosto",
|
||||
"import_imported": "Tuotu",
|
||||
"import_placeholder_fail": "Lompakon tuonti",
|
||||
"import_placeholder_inprogress": "Tuodaan lompakkoa...",
|
||||
"import_scan_qr": "Skannaa tai tuo tiedosto",
|
||||
"import_success": "Lompakkosi tuonti onnistui.",
|
||||
"import_search_accounts": "Hae tilejä",
|
||||
"import_title": "tuo",
|
||||
"import_discovery_title": "Etsiminen",
|
||||
"import_discovery_subtitle": "Valitse löydetty lompakko",
|
||||
"import_discovery_derivation": "Vaihtoehtoinen derivation path",
|
||||
"import_discovery_no_wallets": "Lompakkoja ei löytynyt",
|
||||
"import_derivation_found": "löytyi",
|
||||
"import_derivation_found_not": "ei löytynyt",
|
||||
"import_derivation_loading": "ladataan...",
|
||||
"import_derivation_subtitle": "Syötä vaihtoehtoinen derivation path, niin yritämme etsiä lompakkosi",
|
||||
"import_derivation_title": "Derivation path",
|
||||
"import_derivation_unknown": "tuntematon",
|
||||
"import_wrong_path": "Väärä derivation path",
|
||||
"list_create_a_button": "Lisää nyt",
|
||||
"list_create_a_wallet": "Lisää lompakko",
|
||||
"list_create_a_wallet_text": "Se on ilmainen ja voit luoda\nniin monta kuin haluat",
|
||||
@ -418,7 +512,6 @@
|
||||
"list_empty_txs2": "Aloita lompakostasi. ",
|
||||
"list_empty_txs2_lightning": "Aloita lompakon käyttäminen napsauttamalla \"hallinnoi varoja\" ja lisää saldoasi.\n",
|
||||
"list_header": "Lompakko edustaa avainparia, yhtä yksityistä ja yhtä, jonka voit jakaa vastaanottaaksesi varoja.",
|
||||
"list_import_error": "Tämän lompakon tuomisessa tapahtui virhe.",
|
||||
"list_import_problem": "Tämän lompakon tuomisessa oli ongelma",
|
||||
"list_latest_transaction": "viimeisin siirto",
|
||||
"list_ln_browser": "LApp-selain",
|
||||
@ -432,6 +525,7 @@
|
||||
"no_ln_wallet_error": "Ennen kuin maksat Lightning-laskun, sinun on ensin lisättävä Lightning-lompakko.",
|
||||
"looks_like_bip38": "Tämä näyttää salasanalla suojatulta yksityiseltä avaimelta (BIP38)",
|
||||
"reorder_title": "Järjestele Lompakot",
|
||||
"reorder_instructions": "Siirrä listalla, ensin napauttamalla ja pitämällä, sitten vetäen.",
|
||||
"please_continue_scanning": "Jatka skannausta",
|
||||
"scan_error": "Skannausvirhe ",
|
||||
"select_no_bitcoin": "Bitcoin-lompakkoa ei tällä hetkellä ole saatavana.",
|
||||
@ -486,7 +580,7 @@
|
||||
"wallet_type": "Lompakon tyyppi",
|
||||
"view_key": "näkymä",
|
||||
"invalid_mnemonics": "Tämä muistilauseke ei näytä olevan pätevä",
|
||||
"invalid_cosigner": "Ei kelvollisia allekirjoitustietoja",
|
||||
"invalid_cosigner": "Virheellinen kanssa-allekirjoittajan tieto",
|
||||
"not_a_multisignature_xpub": "Tämä ei ole xpub multisignature-lompakosta!",
|
||||
"invalid_cosigner_format": "Virheellinen allekirjoittaja: tämä ei ole muodon {format} allekirjoittaja",
|
||||
"create_new_key": "Luo Uusi",
|
||||
@ -513,9 +607,9 @@
|
||||
"ms_help_title1": "Useita laitteita suositellaan",
|
||||
"ms_help_1": "Vault toimii muiden BlueWallet-sovellusten ja PSBT-yhteensopivien lompakoiden kanssa, kuten Electrum, Spectre, Coldcard, Cobo vault jne.",
|
||||
"ms_help_title2": "Avainten Muokkaus",
|
||||
"ms_help_2": "Voit luoda kaikki Vault-avaimet tälle laitteelle ja poistaa tai muokata niitä myöhemmin. Pitämällä kaikki avaimet samalla laitteella on vastaavanlainen suojaus kuin tavallisella Bitcoin-lompakolla.",
|
||||
"ms_help_2": "Voit luoda holvi-avaimia tässä laitteessa. Ja sitten myöhemmin poistaa ja muokate niitä. Kaikkien avaimien pitäminen samassa laitteessa on yhtä turvallista kuin tavallisessa Bitcoin-lompakossakin.",
|
||||
"ms_help_title3": "Vault-varmuuskopiot",
|
||||
"ms_help_3": "Lompakon vaihtoehdoista löydät Vault-varmuuskopion ja vain-lukuoikeus varmuuskopion. Tämä varmuuskopio on kuin kartta lompakkoosi. Se on välttämätöntä lompakon palauttamiseksi, jos menetät yhden siemenistäsi.",
|
||||
"ms_help_3": "Holvi- ja katselu varmuuskopiot löydät lompakon asetuksista. Tämä varmuuskopio on kartta lompakollesi. Se on välttämätön lompakon palauttamiseksi, mikäli ole hukannut yhdenkään siemensanan tai lauseen.",
|
||||
"ms_help_title4": "Tuodaan Vault:ia",
|
||||
"ms_help_4": "Voit tuoda multisig:in käyttämällä varmuuskopiotiedostoasi ja Tuo-ominaisuutta. Jos sinulla on vain laajennettuja avaimia ja siemensanoja, voit käyttää yksittäistä Tuo-näppäintä, kun luot Vault -avaimia.",
|
||||
"ms_help_title5": "Lisäasetukset",
|
||||
@ -526,11 +620,13 @@
|
||||
"owns": "{label} omistaa {address}",
|
||||
"enter_address": "Syötä osoite",
|
||||
"check_address": "Tarkista osoite",
|
||||
"no_wallet_owns_address": "Mikään käytettävissä olevista lompakoista ei omista annettua osoitetta."
|
||||
"no_wallet_owns_address": "Mikään käytettävissä olevista lompakoista ei omista annettua osoitetta.",
|
||||
"view_qrcode": "Näytä QR-koodi"
|
||||
},
|
||||
"cc": {
|
||||
"change": "vaihto",
|
||||
"coins_selected": "Kolikot valittu ({number})",
|
||||
"selected_summ": "{value} valittuna",
|
||||
"empty": "Tässä lompakossa ei ole tällä hetkellä kolikoita",
|
||||
"freeze": "jäädytä",
|
||||
"freezeLabel": "Jäädytä",
|
||||
@ -543,18 +639,24 @@
|
||||
"units": {
|
||||
"BTC": "BTC",
|
||||
"MAX": "MAX",
|
||||
"sat_byte": "sat/bitti",
|
||||
"sat_vbyte": "sat/tavu",
|
||||
"sats": "sattia"
|
||||
},
|
||||
"addresses": {
|
||||
"sign_title": "Allekirjoita/Varmenna viesti",
|
||||
"sign_help": "Täällä voit luoda tai varmentaa kryptografisen allekirjoituksen Bitcoin-osoitteen perusteella ",
|
||||
"sign_sign": "Allekirjoita",
|
||||
"sign_sign_submit": "Allekirjoita ja toimita",
|
||||
"sign_verify": "Varmenna",
|
||||
"sign_signature_correct": "Varmennus onnistui!",
|
||||
"sign_signature_incorrect": "Varmennus epäonnistui!",
|
||||
"sign_placeholder_address": "Osoite",
|
||||
"sign_placeholder_message": "Viesti",
|
||||
"sign_placeholder_signature": "Allekirjoitus"
|
||||
"sign_placeholder_signature": "Allekirjoitus",
|
||||
"addresses_title": "Osoitteet",
|
||||
"type_change": "muuta",
|
||||
"type_receive": "vastaanota",
|
||||
"type_used": "Käytetty",
|
||||
"transactions": "tapahtumat"
|
||||
}
|
||||
}
|
||||
|
@ -641,17 +641,10 @@
|
||||
"sign_placeholder_address": "Adresse",
|
||||
"sign_placeholder_message": "Message",
|
||||
"sign_placeholder_signature": "Signature",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"sign_aopp_confirm": "Voulez vous envoyer un message signé a {hostname}?",
|
||||
"addresses_title": "Adresses",
|
||||
"type_change": "Monnaie",
|
||||
"type_receive": "Réception",
|
||||
"type_used": "Utilisé",
|
||||
"transactions": "Transactions"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "Sélectionner l'adresse",
|
||||
"send_success": "Signature envoyée avec succès",
|
||||
"send_error": "Erreur lors de l'envoi de la signature"
|
||||
}
|
||||
}
|
||||
|
@ -637,16 +637,10 @@
|
||||
"sign_placeholder_address": "כתובת",
|
||||
"sign_placeholder_message": "הודעה",
|
||||
"sign_placeholder_signature": "חתימה",
|
||||
"sign_aopp_confirm": "האם ברצונך לשלוח הודעה חתומה אל {hostname}?",
|
||||
"addresses_title": "כתובות",
|
||||
"type_change": "עודף",
|
||||
"type_receive": "קבלה",
|
||||
"type_used": "שומש",
|
||||
"transactions": "פעולות"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "בחירת כתובת",
|
||||
"send_success": "חתימה נשלחה בהצלחה",
|
||||
"send_error": "שגיאת שליחת חתימה"
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
"seed": "jelszó sorozat",
|
||||
"success": "Sikeres",
|
||||
"wallet_key": "Tárca kulcs",
|
||||
"invalid_animated_qr_code_fragment": "Érvénytelen animált QR kód részlet, próbáld újra!",
|
||||
"invalid_animated_qr_code_fragment" : "Érvénytelen animált QR kód részlet, próbáld újra!",
|
||||
"file_saved": "{filePath} elmentve a kijelölt helyen: {destination}.",
|
||||
"file_save_title": "Fájl Mentése",
|
||||
"file_save_location": "Jelölje ki hova mentsen {filePath}",
|
||||
@ -102,13 +102,13 @@
|
||||
"p2p": "p2p átváltás"
|
||||
},
|
||||
"lnd": {
|
||||
"active": "Aktív",
|
||||
"inactive": "Inaktív",
|
||||
"active":"Aktív",
|
||||
"inactive":"Inaktív",
|
||||
"channels": "Csatornák",
|
||||
"no_channels": "Nincsenek csatornák",
|
||||
"claim_balance": "Egyenleg lefoglalása {balance}",
|
||||
"close_channel": "Csatorna zárása",
|
||||
"new_channel": "Új csatorna",
|
||||
"new_channel" : "Új csatorna",
|
||||
"errorInvoiceExpired": "A számla lejárt",
|
||||
"exchange": "Átváltás",
|
||||
"force_close_channel": "Csatorna erőltetett zárása?",
|
||||
@ -119,10 +119,14 @@
|
||||
"payButton": "Fizess",
|
||||
"placeholder": "Számla",
|
||||
"open_channel": "Csatorna nyitása",
|
||||
"opening_channnel_for_from": "Csatornanyitás a {forWalletLabel} tárca számára, {fromWalletLabel} által finanszírozva.",
|
||||
"funding_amount_placeholder": "Feltöltési mennyiség, például 0.001",
|
||||
"opening_channnel_for_from":"Csatornanyitás a {forWalletLabel} tárca számára, {fromWalletLabel} által finanszírozva.",
|
||||
"are_you_sure_open_channel": "Biztosan meg akarja nyitni ezt a csatornát?",
|
||||
"are_you_sure_exit_without_new_channel": "Biztosan ki akar lépni anélkül, hogy csatornát nyit?",
|
||||
"public": "Nyilvános",
|
||||
"public_description": "Látható a hálózaton: Lehet útválasztó node és díjakat tud felszámolni.",
|
||||
"private": "Privát",
|
||||
"private_description": "Láthatatlan a hálózaton: Megóvja az ön privát adatait amikor átutalásokat teljesít.",
|
||||
"local_reserve": "Helyi tartalék",
|
||||
"potentialFee": "Várható díj: {fee}",
|
||||
"remote_host": "Távoli host",
|
||||
@ -181,6 +185,7 @@
|
||||
"header": "Fogadás"
|
||||
},
|
||||
"send": {
|
||||
"provided_address_is_invoice": "Ez a cím Villám számlának tűnik. Kérem, mennyen be a Villám tárcájába és ott próbálkozzon ezen számla fizetésével.",
|
||||
"broadcastButton": "Küldés",
|
||||
"broadcastError": "hiba",
|
||||
"broadcastNone": "Bejövő tranzakciós hash",
|
||||
@ -206,6 +211,7 @@
|
||||
"details_adv_fee_bump": "Kiváltás díjjal engedélyezve",
|
||||
"details_adv_full": "Használd a teljes egyenleget",
|
||||
"details_adv_full_sure": "Biztosan használni akarod a tárca teljes egyenlegét ehhez a tranzakcióhoz?",
|
||||
"details_adv_full_sure_frozen": "Biztosan fel akarja használna a teljes egyenleget ehhez a tranzakcióhoz? Lefagyasztott érmék nem lesznek felhasználva.",
|
||||
"details_adv_import": "Tranzakció importálása",
|
||||
"details_adv_import_qr": "Tranzakció Importálása (QR)",
|
||||
"details_amount_field_is_not_valid": "Érvénytelen összeg",
|
||||
@ -213,12 +219,14 @@
|
||||
"details_create": "Készíts számlát",
|
||||
"details_error_decode": "Nem lehet dekódolni a bitcoin címet",
|
||||
"details_fee_field_is_not_valid": "Èrvénytelen tranzakciós díj",
|
||||
"details_frozen": "{amount} BTC fagyasztva áll",
|
||||
"details_next": "Következő",
|
||||
"details_no_signed_tx": "A kiválasztott fájl nem tartalmaz importálható tranzakciót.",
|
||||
"details_note_placeholder": "saját megjegyzés",
|
||||
"details_scan": "Szkennelés",
|
||||
"details_scan_hint": "Dupla érintéssel szkennelhet, vagy betölthet uticélt",
|
||||
"details_total_exceeds_balance": "A megadott összeg nagyobb, mint a tárca elérhető egyenlege",
|
||||
"details_total_exceeds_balance_frozen": "A küldeni kívánt össze meghaladja az elérhető egyenlegét. Lefagyasztott érmék nem voltak használva.",
|
||||
"details_unrecognized_file_format": "Nemismert fálj formátum",
|
||||
"details_wallet_before_tx": "Tranzakció előtt, először adj meg egy Bitcoin tárcát.",
|
||||
"dynamic_init": "Előkészítés",
|
||||
@ -232,6 +240,8 @@
|
||||
"fee_custom": "beállított",
|
||||
"fee_fast": "Gyors",
|
||||
"fee_medium": "Közepes",
|
||||
"fee_replace_minvb": "A fizetendő teljes díj mértékének (satoshi per vbyte) magasabbnak kell lennie, mint {min} sat/vbyte.",
|
||||
"fee_satvbyte": "sat/vByte-ban",
|
||||
"fee_slow": "Lassú",
|
||||
"header": "Küldés",
|
||||
"input_clear": "Törlés",
|
||||
@ -244,11 +254,13 @@
|
||||
"open_settings": "Beállítások megnyitása",
|
||||
"permission_storage_later": "Később",
|
||||
"permission_storage_message": "A fájl elmentéséhez engedélyezned kell a BlueWallet hozzáférését a háttértárhoz.",
|
||||
"permission_storage_denied_message": "BlueWallet nem képes elmenteni ezt a fájlt. Kérem nyissa meg a beállításokat és engedélyezze a tárhely hozzáférést az eszközén.",
|
||||
"permission_storage_title": "Háttértár hozzáférés engedélyezés",
|
||||
"psbt_clipboard": "Másolás vágólapra",
|
||||
"psbt_this_is_psbt": "Ez egy részlegesen aláírt Bitcoin tranzakció (PSBT). Befejezheted a hardver tárcád aláírásával. ",
|
||||
"psbt_tx_export": "Exportálás fájlba",
|
||||
"no_tx_signing_in_progress": "Tranzakció aláírás nincs folyamatban",
|
||||
"outdated_rate": "A ráta utoljára frissítve: {date}",
|
||||
"psbt_tx_open": "Aláírt tranzakció megnyitása",
|
||||
"psbt_tx_scan": "Aláírt tranzakció szkennelése",
|
||||
"qr_error_no_qrcode": "Nem találtunk QR kódot a kiválasztott képen. Győződjön meg arról, hogy a kép csak QR kódot tartalmaz, és nem tartalmaz további tartalmat, például szöveget vagy gombokat.",
|
||||
@ -282,6 +294,7 @@
|
||||
"biom_remove_decrypt": "Minden pénztárcáját eltávolítjuk, és a tárolójáról visszafejtjük a titkosítást. Biztosan folytatja?",
|
||||
"currency": "Valuta",
|
||||
"currency_source": "Árak forrása",
|
||||
"currency_fetch_error": "Hibatörtént a ráta lekérdezésekor a kijelölt fiat pénznél.",
|
||||
"default_desc": "Ha le van tiltva, a BlueWallet azonnal megnyitja a kiválasztott tárcát indításkor. ",
|
||||
"default_info": "Alapértelmezett információ",
|
||||
"default_title": "Indításkor ",
|
||||
@ -290,6 +303,8 @@
|
||||
"electrum_connected_not": "Nincs kapcsolat",
|
||||
"electrum_connnected_not_description": "A pénztárca importálásához aktív Electrum kapcsolat szükséges. A kapcsolat létrejöttét a Beállításokon belül a Hálózat menüpontban ellenőrizheti.",
|
||||
"electrum_error_connect": "Nem tud csatlakozni a kiválasztott Electrum szerverhez",
|
||||
"lndhub_uri": "P.l., {example}",
|
||||
"electrum_host": "P.l., {example}",
|
||||
"electrum_offline_mode": "Offline Mód",
|
||||
"electrum_offline_description": "Ha engedélyezve van, a Bitcoin pénztárcájai nem kísérelnek meg egyenlegek vagy tranzakciók lekérdezésével.",
|
||||
"electrum_port": "Port, álltalában {example}",
|
||||
@ -340,7 +355,7 @@
|
||||
"network_electrum": "Electrum szerver",
|
||||
"not_a_valid_uri": "Nem megfelelő URI",
|
||||
"notifications": "Megjegyzések",
|
||||
"open_link_in_explorer": "Link megnyitása explorerben",
|
||||
"open_link_in_explorer" : "Link megnyitása explorerben",
|
||||
"password": "Jelszó",
|
||||
"password_explain": "Add meg a jelszót, amivel majd dekódolhatod a tárhelyet",
|
||||
"passwords_do_not_match": "A megadott jelszavak különböznek!",
|
||||
@ -360,7 +375,7 @@
|
||||
"selfTest": "Önteszt",
|
||||
"save": "Ment",
|
||||
"saved": "Elmentve",
|
||||
"success_transaction_broadcasted": "Sikeres! A tranzakciója továbbítva!",
|
||||
"success_transaction_broadcasted" : "Sikeres! A tranzakciója továbbítva!",
|
||||
"total_balance": "Teljes egyenleg",
|
||||
"total_balance_explanation": "Jelenítse meg az összes pénztárca egyenlegét a kezdőképernyő moduljain.",
|
||||
"widgets": "Widgetek",
|
||||
@ -386,7 +401,10 @@
|
||||
"details_balance_show": "Egyenleg mutatása",
|
||||
"details_block": "Blokkszámláló",
|
||||
"details_copy": "Másolás",
|
||||
"details_copy_amount": "Mennyiség Másolása",
|
||||
"details_copy_block_explorer_link": "Blokk Böngésző Link Másolása",
|
||||
"details_copy_note": "Megjegyzés Másolása",
|
||||
"details_copy_txid": "Tranzakciós ID Másolása",
|
||||
"details_from": "Bejövő utalás",
|
||||
"details_inputs": "Bejövő utalások",
|
||||
"details_outputs": "Kimenő utalások",
|
||||
@ -405,6 +423,7 @@
|
||||
"eta_3h": "ETA: ~3 órán belül",
|
||||
"eta_1d": "ETA: ~1 napon belül",
|
||||
"list_title": "tranzakciók",
|
||||
"open_url_error": "Nem lehetett megnyitni a URL-t az alapértelmezett böngészővel. Kérem változtassa meg a böngészőjét és próbálkozzon meg újra.",
|
||||
"rbf_explain": "Kiváltjuk ezt a tranzakciót egy magasabb tranzakciós díjjal járó tranzakcióval, így hamarabb teljesül. Ezt a megoldást Tranzakciós Díj Pótlásnak hívjuk, angolul RBF - Replace by Fee.",
|
||||
"rbf_title": "Kiváltási díj (RBF)",
|
||||
"status_bump": "Kiváltási díj",
|
||||
@ -439,6 +458,7 @@
|
||||
"details_are_you_sure": "Biztos vagy benne?",
|
||||
"details_connected_to": "Kapcsolódva: ",
|
||||
"details_del_wb_err": "A megadott egyenleg összege nem egyezik a tárca egyenlegével. Próbáld újra. ",
|
||||
"details_del_wb_q": "Ennek a tárcának van egyenlege. Mielőtt tovább lép, tudnia kell, hogy nem fogja tudni vissza szerezni ezen összeget ha nem rendelkezik ezen tárca biztonsági szavaival. A véletlen eltávolítások elkerülése érdekéven kérem adja meg a tárcán található {balance} egyenleget satoshiban.",
|
||||
"details_delete": "Törlés",
|
||||
"details_delete_wallet": "Tárca törlése",
|
||||
"details_derivation_path": "derivációs út",
|
||||
@ -474,11 +494,13 @@
|
||||
"import_search_accounts": "Fiókok keresése",
|
||||
"import_title": "importálás",
|
||||
"import_discovery_title": "Felfedezés",
|
||||
"import_discovery_subtitle": "Már felfedezett tárca választása",
|
||||
"import_discovery_derivation": "Egyedi derivációs útvonal használata",
|
||||
"import_discovery_no_wallets": "Nem található tárca.",
|
||||
"import_derivation_found": "megtalálva",
|
||||
"import_derivation_found_not": "nem található",
|
||||
"import_derivation_loading": "töltés...",
|
||||
"import_derivation_subtitle": "Egyedi derivációs útvonal beírása és mi megpróbáljuk felfedezni a tárcáját",
|
||||
"import_derivation_title": "Derivációs útvonal",
|
||||
"import_derivation_unknown": "ismeretlen",
|
||||
"import_wrong_path": "hibás derivációs útvonal",
|
||||
@ -503,6 +525,7 @@
|
||||
"no_ln_wallet_error": "Mielőtt tudnál fizetni a villámhálózaton, először egy Lightning tárcát kell létrehoznod vagy betöltened.",
|
||||
"looks_like_bip38": "Ez egy jelszó védett privát kulcsnak (BIP38) tűnik",
|
||||
"reorder_title": "Tárcák rendezése",
|
||||
"reorder_instructions": "Érintse meg és tartsa lenyomva, hogy át húzzhassa a listán.",
|
||||
"please_continue_scanning": "Kérem szkenneljen folyamatosan.",
|
||||
"scan_error": "Szkennelési Hiba",
|
||||
"select_no_bitcoin": "Jelenleg nincs elérhető Bitcoin tárca.",
|
||||
@ -584,6 +607,7 @@
|
||||
"ms_help_title1": "Több eszköz használata javasolt.",
|
||||
"ms_help_1": "A Vault működőképes más BlueWallet applikációkkal és PSBT kompatibilis tárcákkal mint például az Electrum, Specter, Coldcard, KeystoneWallet, stb.",
|
||||
"ms_help_title2": "Kulcsok szerkesztése",
|
||||
"ms_help_2": "Az összes Vault-kulcsot létrehozhatja ezen az eszközön, majd később eltávolíthatja vagy szerkesztheti azokat. Ha minden kulcs ugyanazon az eszközön van, az egyenértékű egy hagyományos Bitcoin pénztárca biztonságával.",
|
||||
"ms_help_title3": "Széf Biztonsági Másolat",
|
||||
"ms_help_3": "A pénztárca beállításainál megtalálhatja a Vault biztonsági másolatát és a csak megtekintésre kész biztonsági másolatot. Ez a biztonsági mentés olyan, mint egy térkép a pénztárcájához. A biztonsági mentés elengedhetetlen a pénztárca helyreállításához.",
|
||||
"ms_help_title4": "Széf Importálása",
|
||||
@ -602,6 +626,7 @@
|
||||
"cc": {
|
||||
"change": "váltás",
|
||||
"coins_selected": "Érmék kiválasztva ({number})",
|
||||
"selected_summ": "{value} kijelölve",
|
||||
"empty": "Ez a tárca jelenleg üres.",
|
||||
"freeze": "zárolás",
|
||||
"freezeLabel": "zárolás",
|
||||
@ -628,16 +653,10 @@
|
||||
"sign_placeholder_address": "Cím",
|
||||
"sign_placeholder_message": "Üzenet",
|
||||
"sign_placeholder_signature": "Szignatúra",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"addresses_title": "Címek",
|
||||
"type_change": "Váltópénz",
|
||||
"type_receive": "Fogadás",
|
||||
"type_used": "Használt",
|
||||
"transactions": "Tranzakciók"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "Cím kiválasztása",
|
||||
"send_success": "Szignatúra sikeresen elküldve",
|
||||
"send_error": "Hiba a szignatúra küldésekor"
|
||||
}
|
||||
}
|
||||
|
23
loc/it.json
23
loc/it.json
@ -105,11 +105,14 @@
|
||||
"inactive": "Inattivo",
|
||||
"channels": "Canali",
|
||||
"no_channels": "Nessun canale",
|
||||
"claim_balance": "Richiedi il saldo {balance}",
|
||||
"close_channel": "Chiudi il canale",
|
||||
"new_channel": "Nuovo canale",
|
||||
"errorInvoiceExpired": "Fattura scaduta",
|
||||
"exchange": "Exchange",
|
||||
"force_close_channel": "Forza la chiusura del canale?",
|
||||
"expired": "Scaduto",
|
||||
"node_alias": "Alias del nodo",
|
||||
"expiredLow": "Scaduto",
|
||||
"expiresIn": "Scade tra {time} minuti",
|
||||
"payButton": "Paga",
|
||||
@ -119,9 +122,11 @@
|
||||
"opening_channnel_for_from": "Apri canale per il wallet {forWalletLabel}, caricando fondi da {fromWalletLabel}",
|
||||
"are_you_sure_open_channel": "Sei sicuro di voler aprie questo canale?",
|
||||
"are_you_sure_exit_without_new_channel": "Sei sicuro di voler uscire senza aprire un canale?",
|
||||
"public": "Pubblico",
|
||||
"public_description": "Visibile sulla rete: può essere un nodo di routing e guadagnare le commissioni.",
|
||||
"private": "Privato",
|
||||
"private_description": "Invisibile sulla rete: preserverà la privacy dei tuoi pagamenti.",
|
||||
"local_reserve": "Risorse locali",
|
||||
"potentialFee": "Commissioni potenziali: {fee}",
|
||||
"remote_host": "Host remoto",
|
||||
"refill": "Ricarica",
|
||||
@ -133,7 +138,8 @@
|
||||
"sameWalletAsInvoiceError": "Non puoi pagare una fattura con lo stesso portafoglio utilizzato per crearla.",
|
||||
"title": "Gestisci fondi",
|
||||
"can_send": "Puoi inviare",
|
||||
"can_receive": "Puoi ricevere"
|
||||
"can_receive": "Puoi ricevere",
|
||||
"view_logs": "Visualizza i log"
|
||||
},
|
||||
"lndViewInvoice": {
|
||||
"additional_info": "Ulteriori Informazioni",
|
||||
@ -204,6 +210,7 @@
|
||||
"details_adv_fee_bump": "Permetti l'aumento della commissione",
|
||||
"details_adv_full": "Utilizza tutti i fondi",
|
||||
"details_adv_full_sure": "Desideri veramente usare tutti i fondi in questo portafoglio per questa transazione?",
|
||||
"details_adv_full_sure_frozen": "Sei sicuro di voler usare tutto il saldo del tuo wallet per questa transazione? Notare che il saldo congelato è escluso.",
|
||||
"details_adv_import": "Importa Transazione",
|
||||
"details_adv_import_qr": "Importa Transazione (QR)",
|
||||
"details_amount_field_is_not_valid": "Importo non valido",
|
||||
@ -211,12 +218,14 @@
|
||||
"details_create": "Crea",
|
||||
"details_error_decode": "Impossibile decodificare l'indirizzo Bitcoin",
|
||||
"details_fee_field_is_not_valid": "Commissione non valida",
|
||||
"details_frozen": "{amount} BTC sono congelati",
|
||||
"details_next": "Avanti",
|
||||
"details_no_signed_tx": "Il file selezionato non contiene una transazione che può essere importata.",
|
||||
"details_note_placeholder": "Nota",
|
||||
"details_scan": "Scansiona",
|
||||
"details_scan_hint": "Tocca due volte per scannerizzare o importare una destinazione",
|
||||
"details_total_exceeds_balance": "L'importo da inviare eccede i fondi disponibili.",
|
||||
"details_total_exceeds_balance_frozen": "Il saldo che si vuole inviare è superiore al saldo disponibile. Notare che il saldo congelato è escluso.",
|
||||
"details_unrecognized_file_format": "Formato sconosciuto",
|
||||
"details_wallet_before_tx": "Prima di creare una transazione devi prima creare un portafoglio Bitcoin.",
|
||||
"dynamic_init": "Avviamento",
|
||||
@ -250,6 +259,7 @@
|
||||
"psbt_this_is_psbt": "Questa è una Transazione Bitcoin Parzialmente Firmata (PSBT). Per favore termina di firmarla con il tuo portafoglio hardware.",
|
||||
"psbt_tx_export": "Esporta in un file",
|
||||
"no_tx_signing_in_progress": "Non c'è nessuna firma di transazione in corso.",
|
||||
"outdated_rate": "La tariffa è stata aggiornata il: {data}",
|
||||
"psbt_tx_open": "Apri una transazione firmata",
|
||||
"psbt_tx_scan": "Scansiona una transazione firmata",
|
||||
"qr_error_no_qrcode": "Non siamo stati in grado di trovare un QR Code nell'immagine selezionata. Assicurati che l'immagine contenga solo un QR Code e nessun altro contenuto in aggiunta, quale testo o pulsanti.",
|
||||
@ -283,6 +293,7 @@
|
||||
"biom_remove_decrypt": "Tutti i tuoi portafogli saranno rimossi e la memoria sarà decriptata. Sei sicuro di voler procedere?",
|
||||
"currency": "Valuta",
|
||||
"currency_source": "I prezzi sono ottenuti da",
|
||||
"currency_fetch_error": "Errore durante la ricezione della tariffa per la valuta selezionata",
|
||||
"default_desc": "Se disabilitato, BlueWallet aprirà immediatamente il portafoglio selezionato al lancio.",
|
||||
"default_info": "Informazioni predefinite",
|
||||
"default_title": "All'avvio",
|
||||
@ -358,6 +369,7 @@
|
||||
"privacy_do_not_track": "Disattiva Analytics",
|
||||
"privacy_do_not_track_explanation": "Le informazioni circa la performance e l'affidabilità non saranno inviati per l'analisi.",
|
||||
"push_notifications": "Notifiche Push",
|
||||
"rate": "Tariffa",
|
||||
"retype_password": "Reinserisci password",
|
||||
"selfTest": "Auto-Test",
|
||||
"save": "Salva",
|
||||
@ -378,6 +390,7 @@
|
||||
"cancel_no": "Questa transazione non può essere sostituita.",
|
||||
"cancel_title": "Cancella questa transazione (RBF)",
|
||||
"confirmations_lowercase": "{confirmations} conferme",
|
||||
"copy_link": "Copia link",
|
||||
"expand_note": "Espandi Nota",
|
||||
"cpfp_create": "Crea",
|
||||
"cpfp_exp": "Creeremo una nuova transazione che spende la tua transazione non ancora confermata. Le commissioni totali saranno più elevate rispetto alla transazione originale, quindi dovrebbe venir confermata pi?u rapidamente. Questa tecnica si chiama CPFP—Child Pays for Parent.",
|
||||
@ -388,7 +401,9 @@
|
||||
"details_block": "Altezza del blocco",
|
||||
"details_copy": "Copia",
|
||||
"details_copy_amount": "Copia importo",
|
||||
"details_copy_block_explorer_link": "Copia link del Block Explorer",
|
||||
"details_copy_note": "Copia Nota",
|
||||
"details_copy_txid": "Copia ID di transazione",
|
||||
"details_from": "Da",
|
||||
"details_inputs": "Input",
|
||||
"details_outputs": "Output",
|
||||
@ -406,6 +421,7 @@
|
||||
"eta_3h": "ETA: In ~3 ore",
|
||||
"eta_1d": "ETA: In ~1 giorno",
|
||||
"list_title": "Transazioni",
|
||||
"open_url_error": "Impossibile aprire URL con il browser di default. È necessario cambiare il browser di default nelle impostazioni e riprovare.",
|
||||
"rbf_explain": "Sostituiremo questa transazione con una con una commissione più elevata in modo che venga confermata più rapidamente. Questa tecnica è chiamata RBF—Replace by Fee.",
|
||||
"rbf_title": "Aumenta la commissione (RBF)",
|
||||
"status_bump": "Aumenta la commissione",
|
||||
@ -423,19 +439,24 @@
|
||||
"add_entropy_remain": "{gen} byte di entropia generata. I restanti {rem} byte saranno ottenuti da generatore di numeri casuali del sistema operativo.",
|
||||
"add_import_wallet": "Importa Portafoglio",
|
||||
"add_lightning": "Lightning",
|
||||
"add_lightning_explain": "Per invio con transazioni istantanee",
|
||||
"add_lndhub": "Connetti al tuo LNDHub",
|
||||
"add_lndhub_error": "L'indirizzo fornito è un nodo LNDHub invalido.",
|
||||
"add_lndhub_placeholder": "L'indirizzo del tuo nodo",
|
||||
"add_or": "o",
|
||||
"add_placeholder": "Il mio primo wallet",
|
||||
"add_title": "Aggiungi Portafoglio",
|
||||
"add_wallet_name": "Nome Portafoglio",
|
||||
"add_wallet_type": "Tipo",
|
||||
"balance": "Saldo",
|
||||
"clipboard_bitcoin": "Negli appunti è presente un indirizzo Bitcoin. Desideri usarlo per una transazione?",
|
||||
"clipboard_lightning": "Negli appunti è presente una fattura Lightning. Desideri usarla per una transazione?",
|
||||
"details_address": "Indirizzo",
|
||||
"details_advanced": "Avanzato",
|
||||
"details_are_you_sure": "Sei sicuro?",
|
||||
"details_connected_to": "Connesso a",
|
||||
"details_del_wb_err": "Il saldo fornito non coincide con il saldo di questo wallet. Si prega di riprovare.",
|
||||
"details_del_wb_q": "Attenzione: questo wallet non è vuoto, non sarà possibile recuperare i fondi senza la seed phrase del wallet. Per evitare la rimozione accidentale, si prega di inserire il saldo del wallet {balance} satoshi.",
|
||||
"details_delete": "Elimina",
|
||||
"details_delete_wallet": "Rimuovi portafoglio",
|
||||
"details_derivation_path": "derivation path",
|
||||
|
@ -491,10 +491,5 @@
|
||||
"addresses_title": "アドレス",
|
||||
"type_change": "チェンジ",
|
||||
"type_receive": "受取り"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "アドレス選択",
|
||||
"send_success": "署名は正常に送信されました",
|
||||
"send_error": "署名送信エラー"
|
||||
}
|
||||
}
|
||||
|
@ -648,17 +648,10 @@
|
||||
"sign_placeholder_address": "주소",
|
||||
"sign_placeholder_message": "메시지",
|
||||
"sign_placeholder_signature": "서명",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"sign_aopp_confirm": "서명된 메시지를 {hostname}으로 보내겠습니까?",
|
||||
"addresses_title": "주소",
|
||||
"type_change": "변경",
|
||||
"type_receive": "받기",
|
||||
"type_used": "사용됨",
|
||||
"transactions": "트랜잭션"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "주소 선택",
|
||||
"send_success": "서명 전송이 성공적으로 이루어졌습니다. ",
|
||||
"send_error": "서명 보내기 에러"
|
||||
}
|
||||
}
|
||||
|
@ -618,17 +618,10 @@
|
||||
"sign_placeholder_address": "Alamat",
|
||||
"sign_placeholder_message": "Pesanan",
|
||||
"sign_placeholder_signature": "Tandatangan",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"sign_aopp_confirm": "Adakah anda mahu menghantar pesanan bertanda tangan kepada {hostname}?",
|
||||
"addresses_title": "Alamat",
|
||||
"type_change": "Ubah",
|
||||
"type_receive": "Terima",
|
||||
"type_used": "Digunakan",
|
||||
"transactions": "Urus Niaga"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "Pilih Alamat",
|
||||
"send_success": "Tandatangan berjaya dihantar",
|
||||
"send_error": "Ralat Penghantaran Tandatangan"
|
||||
}
|
||||
}
|
||||
|
@ -651,17 +651,10 @@
|
||||
"sign_placeholder_address": "Adres",
|
||||
"sign_placeholder_message": "Bericht",
|
||||
"sign_placeholder_signature": "Ondertekening",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"sign_aopp_confirm": "Wil je een ondertekende boodschap sturen naar {hostname}",
|
||||
"addresses_title": "Adressen",
|
||||
"type_change": "Wisselgeld",
|
||||
"type_receive": "Ontvang",
|
||||
"type_used": "Gebruikt",
|
||||
"transactions": "Transacties"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "Selecteer adres",
|
||||
"send_success": "Ondertekening succesvol verstuurd",
|
||||
"send_error": "Fout bij versturen van Ondertekening"
|
||||
}
|
||||
}
|
||||
|
35
loc/pl.json
35
loc/pl.json
@ -28,7 +28,7 @@
|
||||
"discard_changes_detail": "Masz niezapisane zmiany. Czy jesteś pewien, że chcesz je odrzucić i opuścić ten ekran?"
|
||||
},
|
||||
"alert": {
|
||||
"default": "Uwaga"
|
||||
"default": "Powiadomienie"
|
||||
},
|
||||
"azteco": {
|
||||
"codeIs": "Twój kod vouchera to",
|
||||
@ -173,7 +173,7 @@
|
||||
"ok": "OK, zapisałem",
|
||||
"ok_lnd": "OK, zapisałem ",
|
||||
"text": "Poświęć chwilę by zapisać tę frazę mnemoniczną na kartce papieru\nTo Twoja kopia zapasowa, której możesz użyć później by odtworzyć portfel.",
|
||||
"text_lnd": "Proszę, poświęć chwilę, żeby zapisać to uwierzytelnienie LNDHub. To twoja kopia zapasowa, możesz użyć jej, aby odtworzyć portfel na innym urządzeniu.",
|
||||
"text_lnd": "Zachowaj tę kopię zapasową portfela. Umożliwi Ci odtworzenie portfela w przypadku utraty.",
|
||||
"text_lnd2": "Ten portfel jest obsługiwany przez BlueWallet.",
|
||||
"title": "Twój portfel został utworzony"
|
||||
},
|
||||
@ -295,8 +295,8 @@
|
||||
"currency": "Waluta",
|
||||
"currency_source": "Kurs jest pozyskiwany z",
|
||||
"currency_fetch_error": "Wystąpił błąd podczas pobierania kursu dla wybranej waluty.",
|
||||
"default_desc": "Po uruchomieniu BlueWallet natychmiast otworzy wcześniej wybrany domyślny portfel.",
|
||||
"default_info": "Informacje domyślne",
|
||||
"default_desc": "Gdy jest wyłączone, BlueWallet natychmiast otworzy wybrany domyślny portfel.",
|
||||
"default_info": "Domyślny portfel",
|
||||
"default_title": "Po uruchomieniu",
|
||||
"default_wallets": "Wyświetl wszystkie portfele",
|
||||
"electrum_connected": "Połączony",
|
||||
@ -340,7 +340,7 @@
|
||||
"general_adv_mode_e": "Gdy włączone, zobaczysz zaawansowane ustawienia takie jak np. różne typy portfeli, zdolność do określenia instancji LNDHub, z którą chcesz się połączyć oraz niestandardowej entropii w trakcie tworzenia portfela.",
|
||||
"general_continuity": "Funkcja Continuity",
|
||||
"general_continuity_e": "Gdy włączone, będziesz miał podgląd do wybranych portfeli i transakcji przy użyciu swoich urządzeń zalogowanych do Apple iCloud. ",
|
||||
"groundcontrol_explanation": "GroundControl jest darmową opcją serwera powiadamień push dla portfeli bitcoin. Możesz zainstalować swój własny serwer GroundControl i podać jego URL tutaj, tak aby nie polegać na infrastrukturze BlueWallet. Zostaw puste by użyć domyślnej wartości.",
|
||||
"groundcontrol_explanation": "GroundControl jest darmowym, open source'owym serwerem powiadomień push dla portfeli bitcoin. Możesz zainstalować swój własny serwer GroundControl i podać jego URL tutaj aby nie polegać na infrastrukturze BlueWallet. Zostaw puste by użyć domyślnej wartości.",
|
||||
"header": "Ustawienia",
|
||||
"language": "Język",
|
||||
"last_updated": "Ostatnia aktualizacja",
|
||||
@ -370,7 +370,7 @@
|
||||
"privacy_do_not_track": "Wyłącz analitykę",
|
||||
"privacy_do_not_track_explanation": "Informacje dotyczące wydajności i niezawodności nie będą przesyłane do analizy.",
|
||||
"push_notifications": "Powiadomienia Push",
|
||||
"rate": "Stawka",
|
||||
"rate": "Kurs",
|
||||
"retype_password": "Wprowadź Ponownie hasło",
|
||||
"selfTest": "Autotest",
|
||||
"save": "Zapisz",
|
||||
@ -525,6 +525,7 @@
|
||||
"no_ln_wallet_error": "Musisz najpierw dodać portfel Lightning, zanim zapłacisz fakturę.",
|
||||
"looks_like_bip38": "To wygląda na klucz prywatny chroniony hasłem (BIP38).",
|
||||
"reorder_title": "Zmień kolejność portfeli",
|
||||
"reorder_instructions": "Stuknij i przytrzmaj portfel aby go przeciągnąć na liście.",
|
||||
"please_continue_scanning": "Proszę skanuj dalej.",
|
||||
"scan_error": "Błąd skanowania",
|
||||
"select_no_bitcoin": "Nie ma dostępnych portfeli Bitcoin.",
|
||||
@ -625,6 +626,7 @@
|
||||
"cc": {
|
||||
"change": "Reszta",
|
||||
"coins_selected": "Wybrano monet ({number})",
|
||||
"selected_summ": "{value} wybrano",
|
||||
"empty": "Ten portfel nie ma żadnych monet w tej chwili.",
|
||||
"freeze": "Zamrożona",
|
||||
"freezeLabel": "Zamroź",
|
||||
@ -651,17 +653,26 @@
|
||||
"sign_placeholder_address": "Adres",
|
||||
"sign_placeholder_message": "Wiadomość",
|
||||
"sign_placeholder_signature": "Podpis",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"sign_aopp_confirm": "Czy chcesz przesłać podpisaną wiadomość do {hostname}?",
|
||||
"addresses_title": "Adresy",
|
||||
"type_change": "Reszta",
|
||||
"type_receive": "Otrzymaj",
|
||||
"type_used": "Używany",
|
||||
"transactions": "Transakcje"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "Wybierz adres",
|
||||
"send_success": "Podpis wysłany z powodzeniem",
|
||||
"send_error": "Błąd wysyłania podpisu"
|
||||
"lnurl_auth": {
|
||||
"register_question_part_1": "Czy chcesz zarejestrować konto w ",
|
||||
"register_question_part_2": "używając Twojego portfela Lightning Network?",
|
||||
"register_answer": "Konto w {hostname} zarejestrowane pomyślnie!",
|
||||
"login_question_part_1": "Czy chcesz się zalogować w ",
|
||||
"login_question_part_2": "używając Twojego portfela Lightning Network?",
|
||||
"login_answer": "Zalogowano pomyślnie w {hostname}!",
|
||||
"link_question_part_1": "Połączyć Twoje konto w ",
|
||||
"link_question_part_2": "z portfelem Lightning Network?",
|
||||
"link_answer": "Konto w {hostname} pomyślnie połączone z Twoim portfelem Lightning Network!",
|
||||
"auth_question_part_1": "Czy chcesz się uwierzytelnić w ",
|
||||
"auth_question_part_2": "używając Twojego portfela Lightning Network?",
|
||||
"auth_answer": "Uwierzytelnienie z {hostname} pomyślne!",
|
||||
"could_not_auth": "Nie można uwierzytelnić z {hostname}.",
|
||||
"authenticate": "Uwierzytelnianie"
|
||||
}
|
||||
}
|
||||
|
@ -651,17 +651,10 @@
|
||||
"sign_placeholder_address": "Endereço",
|
||||
"sign_placeholder_message": "Mensagem",
|
||||
"sign_placeholder_signature": "Assinatura",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"sign_aopp_confirm": "Deseja enviar uma mensagem assinada para {hostname}?",
|
||||
"addresses_title": "Endereços",
|
||||
"type_change": "Troco",
|
||||
"type_receive": "Receber",
|
||||
"type_used": "Usado",
|
||||
"transactions": "Transações"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "Selecionar endereço",
|
||||
"send_success": "Assinatura enviada com sucesso",
|
||||
"send_error": "Erro no envio da assinatura"
|
||||
}
|
||||
}
|
||||
|
@ -651,17 +651,10 @@
|
||||
"sign_placeholder_address": "Адрес",
|
||||
"sign_placeholder_message": "Сообщение",
|
||||
"sign_placeholder_signature": "Подпись",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"sign_aopp_confirm": "Отправить подписанное сообщение на {hostname}?",
|
||||
"addresses_title": "Адреса",
|
||||
"type_change": "Сдача",
|
||||
"type_receive": "Получение",
|
||||
"type_used": "Использован",
|
||||
"transactions": "Транзакции"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "Выберите адрес",
|
||||
"send_success": "Подпись успешно отправлена",
|
||||
"send_error": "Ошибка отправки подписи"
|
||||
}
|
||||
}
|
||||
|
@ -648,17 +648,10 @@
|
||||
"sign_placeholder_address": "ලිපිනය",
|
||||
"sign_placeholder_message": "පණිවිඩය",
|
||||
"sign_placeholder_signature": "අත්සන",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"sign_aopp_confirm": "ඔබට {hostname} වෙත අත්සන් කළ පණිවිඩයක් යැවීමට අවශ්යද?",
|
||||
"addresses_title": "ලිපිනයන්",
|
||||
"type_change": "වෙනස් කරන්න",
|
||||
"type_receive": "පිළිගන්න",
|
||||
"type_used": "භාවිතා කර ඇත",
|
||||
"transactions": "ගනුදෙනු"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "ලිපිනය තෝරන්න",
|
||||
"send_success": "අත්සන සාර්ථකව යවන ලදි",
|
||||
"send_error": "අත්සන යැවීමේ දෝෂයකි"
|
||||
}
|
||||
}
|
||||
|
@ -642,17 +642,10 @@
|
||||
"sign_placeholder_address": "Naslov",
|
||||
"sign_placeholder_message": "Sporočilo",
|
||||
"sign_placeholder_signature": "Podpis",
|
||||
"sign_aopp_title": "AOPP",
|
||||
"sign_aopp_confirm": "Ali želite podpisano sporočilo poslati na {hostname}?",
|
||||
"addresses_title": "Naslovi",
|
||||
"type_change": "Vračilo",
|
||||
"type_receive": "Prejemni",
|
||||
"type_used": "Uporabljen",
|
||||
"transactions": "Transakcije"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "Izberite Naslov",
|
||||
"send_success": "Podpis uspešno poslan",
|
||||
"send_error": "Napaka pri pošiljanju podpisa"
|
||||
}
|
||||
}
|
||||
|
@ -405,16 +405,10 @@
|
||||
"sign_placeholder_address": "Адреса",
|
||||
"sign_placeholder_message": "Повідомлення",
|
||||
"sign_placeholder_signature": "Підпис",
|
||||
"sign_aopp_confirm": "Ви хочете надіслати підписане повідомлення на адресу {hostname}?",
|
||||
"addresses_title": "Адреси",
|
||||
"type_change": "Здача",
|
||||
"type_receive": "Отримати",
|
||||
"type_used": "Використаний",
|
||||
"transactions": "Транзакцій"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "Виберіть Адреси",
|
||||
"send_success": "Підпис успішно надіслано",
|
||||
"send_error": "Помилка надсилання підпису"
|
||||
}
|
||||
}
|
||||
|
@ -554,8 +554,5 @@
|
||||
"addresses_title": "地址",
|
||||
"type_change": "改变",
|
||||
"type_receive": "接收"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "选择地址"
|
||||
}
|
||||
}
|
||||
|
@ -554,8 +554,5 @@
|
||||
"addresses_title": "地址",
|
||||
"type_change": "改變",
|
||||
"type_receive": "接收"
|
||||
},
|
||||
"aopp": {
|
||||
"title": "選擇地址"
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ const RateExtractors = {
|
||||
try {
|
||||
const res = await fetch(`https://api.coindesk.com/v1/bpi/currentprice/${ticker}.json`);
|
||||
json = await res.json();
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
throw new Error(`Could not update rate for ${ticker}: ${e.message}`);
|
||||
}
|
||||
let rate = json?.bpi?.[ticker]?.rate_float; // eslint-disable-line
|
||||
@ -30,7 +30,7 @@ const RateExtractors = {
|
||||
try {
|
||||
const res = await fetch(`https://api.yadio.io/json/${ticker}`);
|
||||
json = await res.json();
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
throw new Error(`Could not update rate for ${ticker}: ${e.message}`);
|
||||
}
|
||||
let rate = json?.[ticker]?.price;
|
||||
@ -46,7 +46,7 @@ const RateExtractors = {
|
||||
try {
|
||||
const res = await fetch('https://bitcoinduliban.org/api.php?key=lbpusd');
|
||||
json = await res.json();
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
throw new Error(`Could not update rate for ${ticker}: ${e.message}`);
|
||||
}
|
||||
let rate = json?.[`BTC/${ticker}`];
|
||||
@ -62,7 +62,7 @@ const RateExtractors = {
|
||||
try {
|
||||
const res = await fetch('https://api.exir.io/v1/ticker?symbol=btc-irt');
|
||||
json = await res.json();
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
throw new Error(`Could not update rate for ${ticker}: ${e.message}`);
|
||||
}
|
||||
let rate = json?.last;
|
||||
@ -78,7 +78,7 @@ const RateExtractors = {
|
||||
try {
|
||||
const res = await fetch(`https://api.wazirx.com/api/v2/tickers/btcinr`);
|
||||
json = await res.json();
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
throw new Error(`Could not update rate for ${ticker}: ${e.message}`);
|
||||
}
|
||||
let rate = json?.ticker?.buy; // eslint-disable-line
|
||||
|
40526
package-lock.json
generated
40526
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
51
package.json
51
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bluewallet",
|
||||
"version": "6.2.17",
|
||||
"version": "6.2.19",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -15,7 +15,7 @@
|
||||
"@types/create-hash": "^1.2.2",
|
||||
"@types/jest": "^26.0.24",
|
||||
"@types/react": "^17.0.14",
|
||||
"@types/react-native": "^0.64.12",
|
||||
"@types/react-native": "^0.66.15",
|
||||
"@types/react-test-renderer": "^17.0.1",
|
||||
"@typescript-eslint/eslint-plugin": "^4.28.3",
|
||||
"@typescript-eslint/parser": "^4.28.3",
|
||||
@ -37,7 +37,7 @@
|
||||
"jest": "^26.1.0",
|
||||
"node-fetch": "^2.6.2",
|
||||
"prettier": "^2.2.1",
|
||||
"react-test-renderer": "17.0.1",
|
||||
"react-test-renderer": "17.0.2",
|
||||
"typescript": "^4.3.5"
|
||||
},
|
||||
"engines": {
|
||||
@ -96,12 +96,12 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/preset-env": "7.16.8",
|
||||
"@bugsnag/react-native": "7.15.1",
|
||||
"@bugsnag/source-maps": "2.3.0",
|
||||
"@babel/preset-env": "7.16.11",
|
||||
"@bugsnag/react-native": "7.16.1",
|
||||
"@bugsnag/source-maps": "2.3.1",
|
||||
"@keystonehq/bc-ur-registry": "0.4.4",
|
||||
"@ngraveio/bc-ur": "1.1.6",
|
||||
"@react-native-async-storage/async-storage": "1.15.15",
|
||||
"@react-native-async-storage/async-storage": "1.16.1",
|
||||
"@react-native-clipboard/clipboard": "1.9.0",
|
||||
"@react-native-community/push-notification-ios": "1.10.1",
|
||||
"@react-navigation/drawer": "5.12.5",
|
||||
@ -125,7 +125,7 @@
|
||||
"coinselect": "3.1.12",
|
||||
"crypto-js": "4.1.1",
|
||||
"dayjs": "1.10.7",
|
||||
"detox": "19.4.2",
|
||||
"detox": "19.4.4",
|
||||
"ecpair": "2.0.1",
|
||||
"ecurve": "1.0.6",
|
||||
"electrum-client": "https://github.com/BlueWallet/rn-electrum-client#99ebcc649d91a8dc39bea7964b02dd9ead464aa4",
|
||||
@ -133,36 +133,36 @@
|
||||
"events": "3.3.0",
|
||||
"frisbee": "3.1.4",
|
||||
"junderw-crc32c": "1.2.0",
|
||||
"lottie-ios": "3.1.9",
|
||||
"lottie-react-native": "4.0.2",
|
||||
"metro-react-native-babel-preset": "0.66.2",
|
||||
"lottie-ios": "3.2.3",
|
||||
"lottie-react-native": "5.0.1",
|
||||
"metro-react-native-babel-preset": "0.68.0",
|
||||
"path-browserify": "1.0.1",
|
||||
"payjoin-client": "1.0.1",
|
||||
"process": "0.11.10",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "17.0.1",
|
||||
"react": "17.0.2",
|
||||
"react-localization": "1.0.17",
|
||||
"react-native": "0.64.2",
|
||||
"react-native": "0.67.2",
|
||||
"react-native-blue-crypto": "https://github.com/BlueWallet/react-native-blue-crypto#fbc2e6beded0b7f61e0986ce98cca1230f84bc1c",
|
||||
"react-native-camera": "4.2.1",
|
||||
"react-native-crypto": "2.2.0",
|
||||
"react-native-default-preference": "1.4.3",
|
||||
"react-native-device-info": "8.4.8",
|
||||
"react-native-device-info": "8.4.9",
|
||||
"react-native-document-picker": "https://github.com/BlueWallet/react-native-document-picker#c52e7a6d2a08f5506c23de86c1401775419f772c",
|
||||
"react-native-elements": "3.4.2",
|
||||
"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-gesture-handler": "2.2.0",
|
||||
"react-native-handoff": "https://github.com/BlueWallet/react-native-handoff#31d005f93d31099d0e564590a3bbd052b8a02b39",
|
||||
"react-native-haptic-feedback": "1.13.0",
|
||||
"react-native-idle-timer": "https://github.com/BlueWallet/react-native-idle-timer#8587876d68ab5920e79619726aeca9e672beaf2b",
|
||||
"react-native-image-picker": "4.7.1",
|
||||
"react-native-image-picker": "4.7.3",
|
||||
"react-native-ios-context-menu": "https://github.com/BlueWallet/react-native-ios-context-menu.git#v1.3.0",
|
||||
"react-native-keychain": "8.0.0",
|
||||
"react-native-level-fs": "3.0.1",
|
||||
"react-native-linear-gradient": "2.5.6",
|
||||
"react-native-localize": "2.1.7",
|
||||
"react-native-modal": "12.1.0",
|
||||
"react-native-localize": "2.1.9",
|
||||
"react-native-modal": "13.0.0",
|
||||
"react-native-navigation-bar-color": "https://github.com/BlueWallet/react-native-navigation-bar-color#3b2894ae62fbce99a3bd24105f0921cebaef5c94",
|
||||
"react-native-obscure": "https://github.com/BlueWallet/react-native-obscure.git#f4b83b4a261e39b1f5ed4a45ac5bcabc8a59eadb",
|
||||
"react-native-passcode-auth": "https://github.com/BlueWallet/react-native-passcode-auth#a2ff977ba92b36f8d0a5567f59c05cc608e8bd12",
|
||||
@ -175,21 +175,20 @@
|
||||
"react-native-rate": "1.2.9",
|
||||
"react-native-reanimated": "2.2.4",
|
||||
"react-native-safe-area-context": "3.3.2",
|
||||
"react-native-screens": "3.10.2",
|
||||
"react-native-screens": "3.11.0",
|
||||
"react-native-secure-key-store": "https://github.com/BlueWallet/react-native-secure-key-store#63ab38c9d382a819844a086a69cc204c46aa93f9",
|
||||
"react-native-share": "7.3.3",
|
||||
"react-native-sortable-list": "https://github.com/BlueWallet/react-native-sortable-list.git#e4e44a01a90ee2dcb9c57182262595abf36bfdf7",
|
||||
"react-native-share": "7.3.5",
|
||||
"react-native-svg": "12.1.1",
|
||||
"react-native-tcp-socket": "5.5.0",
|
||||
"react-native-tor": "0.1.7",
|
||||
"react-native-vector-icons": "9.0.0",
|
||||
"react-native-tor": "0.1.8",
|
||||
"react-native-vector-icons": "9.1.0",
|
||||
"react-native-watch-connectivity": "1.0.4",
|
||||
"react-native-webview": "11.16.0",
|
||||
"react-native-webview": "11.17.2",
|
||||
"react-native-widget-center": "https://github.com/BlueWallet/react-native-widget-center#b1382bbe1ed631b50a8aa03390f64c50775bc9ff",
|
||||
"react-native-windows": "0.64.14",
|
||||
"react-native-windows": "0.67.1",
|
||||
"react-test-render": "1.1.2",
|
||||
"readable-stream": "3.6.0",
|
||||
"realm": "10.11.0",
|
||||
"realm": "10.13.0",
|
||||
"rn-ldk": "git+https://github.com/BlueWallet/rn-ldk.git#v0.6.4",
|
||||
"rn-nodeify": "10.3.0",
|
||||
"scryptsy": "2.1.0",
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user