mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-11-29 11:12:18 +03:00
Merge remote-tracking branch 'upstream/development' into nt/wallet-redesign
# Conflicts: # package.json # src/components/index.js # src/constants/routeNames.js # src/redux/store/store.ts # yarn.lock
This commit is contained in:
commit
e2d171456c
@ -153,6 +153,8 @@ android {
|
||||
abiFilters "armeabi-v7a",'x86',"arm64-v8a",'x86_64'
|
||||
}
|
||||
missingDimensionStrategy 'store', 'play'
|
||||
missingDimensionStrategy 'react-native-camera', 'general'
|
||||
missingDimensionStrategy 'react-native-camera', 'mlkit'
|
||||
|
||||
}
|
||||
dexOptions {
|
||||
|
@ -9,6 +9,7 @@
|
||||
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
|
@ -5,7 +5,8 @@ platform :ios, '10.0'
|
||||
|
||||
target 'Ecency' do
|
||||
config = use_native_modules!
|
||||
|
||||
permissions_path = '../node_modules/react-native-permissions/ios'
|
||||
pod 'Permission-Camera', :path => "#{permissions_path}/Camera"
|
||||
# Pods for Ecency
|
||||
|
||||
use_react_native!(:path => config["reactNativePath"])
|
||||
|
@ -140,6 +140,8 @@ PODS:
|
||||
- nanopb/encode (= 1.30906.0)
|
||||
- nanopb/decode (1.30906.0)
|
||||
- nanopb/encode (1.30906.0)
|
||||
- Permission-Camera (3.3.0):
|
||||
- RNPermissions
|
||||
- PromisesObjC (1.2.12)
|
||||
- Protobuf (3.17.0)
|
||||
- RCTRequired (0.63.4)
|
||||
@ -308,6 +310,14 @@ PODS:
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsinspector (0.63.4)
|
||||
- react-native-camera (4.2.1):
|
||||
- React-Core
|
||||
- react-native-camera/RCT (= 4.2.1)
|
||||
- react-native-camera/RN (= 4.2.1)
|
||||
- react-native-camera/RCT (4.2.1):
|
||||
- React-Core
|
||||
- react-native-camera/RN (4.2.1):
|
||||
- React-Core
|
||||
- react-native-cameraroll (1.8.1):
|
||||
- React
|
||||
- react-native-config (1.4.2):
|
||||
@ -443,6 +453,8 @@ PODS:
|
||||
- TOCropViewController
|
||||
- RNOS (1.2.6):
|
||||
- React
|
||||
- RNPermissions (3.3.0):
|
||||
- React-Core
|
||||
- RNReanimated (1.13.2):
|
||||
- React-Core
|
||||
- RNScreens (2.18.1):
|
||||
@ -477,6 +489,7 @@ DEPENDENCIES:
|
||||
- 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`)
|
||||
- Permission-Camera (from `../node_modules/react-native-permissions/ios/Camera`)
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
|
||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
||||
- React (from `../node_modules/react-native/`)
|
||||
@ -489,6 +502,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-native-camera (from `../node_modules/react-native-camera`)
|
||||
- "react-native-cameraroll (from `../node_modules/@react-native-community/cameraroll`)"
|
||||
- react-native-config (from `../node_modules/react-native-config`)
|
||||
- react-native-date-picker (from `../node_modules/react-native-date-picker`)
|
||||
@ -525,6 +539,7 @@ DEPENDENCIES:
|
||||
- RNIap (from `../node_modules/react-native-iap`)
|
||||
- RNImageCropPicker (from `../node_modules/react-native-image-crop-picker`)
|
||||
- RNOS (from `../node_modules/react-native-os`)
|
||||
- RNPermissions (from `../node_modules/react-native-permissions`)
|
||||
- RNReanimated (from `../node_modules/react-native-reanimated`)
|
||||
- RNScreens (from `../node_modules/react-native-screens`)
|
||||
- RNSVG (from `../node_modules/react-native-svg`)
|
||||
@ -583,6 +598,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/lottie-ios"
|
||||
lottie-react-native:
|
||||
:path: "../node_modules/lottie-react-native"
|
||||
Permission-Camera:
|
||||
:path: "../node_modules/react-native-permissions/ios/Camera"
|
||||
RCTRequired:
|
||||
:path: "../node_modules/react-native/Libraries/RCTRequired"
|
||||
RCTTypeSafety:
|
||||
@ -603,6 +620,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsiexecutor"
|
||||
React-jsinspector:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsinspector"
|
||||
react-native-camera:
|
||||
:path: "../node_modules/react-native-camera"
|
||||
react-native-cameraroll:
|
||||
:path: "../node_modules/@react-native-community/cameraroll"
|
||||
react-native-config:
|
||||
@ -675,6 +694,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native-image-crop-picker"
|
||||
RNOS:
|
||||
:path: "../node_modules/react-native-os"
|
||||
RNPermissions:
|
||||
:path: "../node_modules/react-native-permissions"
|
||||
RNReanimated:
|
||||
:path: "../node_modules/react-native-reanimated"
|
||||
RNScreens:
|
||||
@ -720,6 +741,7 @@ SPEC CHECKSUMS:
|
||||
lottie-react-native: 96361a9891cf651534ea35c4f85f33d4cf14ed13
|
||||
MatomoTracker: 24a846c9d3aa76933183fe9d47fd62c9efa863fb
|
||||
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
|
||||
Permission-Camera: 597646618d1edcc055a3f660844c2ee6de8e0596
|
||||
PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97
|
||||
Protobuf: 7327d4444215b5f18e560a97f879ff5503c4581c
|
||||
RCTRequired: 082f10cd3f905d6c124597fd1c14f6f2655ff65e
|
||||
@ -732,6 +754,7 @@ SPEC CHECKSUMS:
|
||||
React-jsi: a0418934cf48f25b485631deb27c64dc40fb4c31
|
||||
React-jsiexecutor: 93bd528844ad21dc07aab1c67cb10abae6df6949
|
||||
React-jsinspector: 58aef7155bc9a9683f5b60b35eccea8722a4f53a
|
||||
react-native-camera: 3eae183c1d111103963f3dd913b65d01aef8110f
|
||||
react-native-cameraroll: e2917a5e62da9f10c3d525e157e25e694d2d6dfa
|
||||
react-native-config: c98128a72bc2c3a1ca72caec0b021f0fa944aa29
|
||||
react-native-date-picker: 242eec7af56cea5fb2706d5db5d3837060b3884b
|
||||
@ -768,6 +791,7 @@ SPEC CHECKSUMS:
|
||||
RNIap: 536b64f090a3d2e707b4f55d9aa5351482f20ea4
|
||||
RNImageCropPicker: 08ba3a2e2f4f8833d606f01906c371e382c4dea9
|
||||
RNOS: 6f2f9a70895bbbfbdad7196abd952e7b01d45027
|
||||
RNPermissions: bcd846e8f5a7f39e921cc7ca7172e2de0e698b6f
|
||||
RNReanimated: e03f7425cb7a38dcf1b644d680d1bfc91c3337ad
|
||||
RNScreens: f7ad633b2e0190b77b6a7aab7f914fad6f198d8d
|
||||
RNSVG: 551acb6562324b1d52a4e0758f7ca0ec234e278f
|
||||
@ -779,6 +803,6 @@ SPEC CHECKSUMS:
|
||||
toolbar-android: 85f3ef4d691469f2d304e7dee4bca013aa1ba1ff
|
||||
Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6
|
||||
|
||||
PODFILE CHECKSUM: 9c48318ea254e2c78005a7a0c2d8bfc14ddd783d
|
||||
PODFILE CHECKSUM: d6141a7068f8cadf52fa413e9f123818237316d9
|
||||
|
||||
COCOAPODS: 1.11.2
|
||||
|
@ -84,6 +84,7 @@
|
||||
"react-native-actionsheet": "ecency/react-native-actionsheet",
|
||||
"react-native-animatable": "^1.3.3",
|
||||
"react-native-autoheight-webview": "^1.5.8",
|
||||
"react-native-camera": "^4.2.1",
|
||||
"react-native-chart-kit": "^6.11.0",
|
||||
"react-native-config": "luggit/react-native-config#master",
|
||||
"react-native-crypto": "^2.2.0",
|
||||
@ -109,9 +110,11 @@
|
||||
"react-native-modal-translucent": "^5.0.0",
|
||||
"react-native-navigation-bar-color": "^1.0.0",
|
||||
"react-native-os": "^1.0.1",
|
||||
"react-native-permissions": "^3.3.0",
|
||||
"react-native-portalize": "^1.0.7",
|
||||
"react-native-progress": "^5.0.0",
|
||||
"react-native-push-notification": "^7.3.1",
|
||||
"react-native-qrcode-scanner": "^1.5.5",
|
||||
"react-native-qrcode-svg": "^6.0.3",
|
||||
"react-native-randombytes": "^3.6.1",
|
||||
"react-native-reanimated": "^1",
|
||||
|
@ -233,7 +233,7 @@ const CommentView = ({
|
||||
onPress={() => handleOnEditPress && handleOnEditPress(comment)}
|
||||
iconType="MaterialIcons"
|
||||
/>
|
||||
{!childCount && !activeVotes.length && isCommentDeletable && (
|
||||
{!childCount && !activeVotes.length && comment.isDeletable && (
|
||||
<Fragment>
|
||||
<IconButton
|
||||
size={20}
|
||||
@ -283,7 +283,6 @@ const CommentView = ({
|
||||
}
|
||||
|
||||
const customContainerStyle = commentNumber > 2 ? {marginLeft: 44}:null
|
||||
const isCommentDeletable = comment && !(comment.children > 0 || comment.net_rshares > 0 || comment.is_paidout);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
|
@ -95,6 +95,7 @@ import { QuickProfileModal } from './organisms';
|
||||
import QuickReplyModal from './quickReplyModal/quickReplyModalView';
|
||||
import Tooltip from './tooltip/tooltipView';
|
||||
import VideoPlayer from './videoPlayer/videoPlayerView';
|
||||
import QRModal from './qrModal/qrModalView';
|
||||
import { SimpleChart } from './simpleChart';
|
||||
|
||||
// Basic UI Elements
|
||||
@ -239,5 +240,6 @@ export {
|
||||
QuickReplyModal,
|
||||
Tooltip,
|
||||
VideoPlayer,
|
||||
QRModal,
|
||||
SimpleChart,
|
||||
};
|
||||
|
@ -89,7 +89,7 @@ class PostHeaderDescription extends PureComponent {
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<View>
|
||||
<View style={{ flex: 1 }}>
|
||||
<View style={[styles.container, customStyle]}>
|
||||
<TouchableOpacity
|
||||
style={styles.avatarNameWrapper}
|
||||
|
@ -7,6 +7,7 @@ export default EStyleSheet.create({
|
||||
},
|
||||
leftContainer: {
|
||||
flexDirection: 'column',
|
||||
flex: 1,
|
||||
},
|
||||
primaryDetails: {
|
||||
flexDirection: 'row',
|
||||
|
@ -281,9 +281,9 @@ export const PostHtmlRenderer = memo(
|
||||
img: styles.img,
|
||||
table: styles.table,
|
||||
tr: { ...styles.tr, width: contentWidth }, //center tag causes tr to have 0 width if not exclusivly set, contentWidth help avoid that
|
||||
th: {...styles.th, minWidth: _minTableColWidth},
|
||||
td: {...styles.td, minWidth: _minTableColWidth},
|
||||
div:{width:contentWidth},
|
||||
th: { ...styles.th, minWidth: _minTableColWidth},
|
||||
td: { ...styles.td, minWidth: _minTableColWidth},
|
||||
div: { ...styles.div, maxWidth:contentWidth }, //makes sure width covers the available horizontal space for view and not exceed the contentWidth if parent bound id not defined
|
||||
blockquote: styles.blockquote,
|
||||
code: styles.code,
|
||||
li: styles.li,
|
||||
|
@ -12,13 +12,15 @@ export default EStyleSheet.create({
|
||||
body: {
|
||||
color: '$primaryBlack',
|
||||
} as TextStyle,
|
||||
div: {
|
||||
width:'100%',
|
||||
},
|
||||
p:{
|
||||
marginTop:6,
|
||||
marginBottom:6,
|
||||
flexDirection:'row',
|
||||
alignItems:'center',
|
||||
flexWrap:'wrap'
|
||||
|
||||
} as TextStyle,
|
||||
pLi:{
|
||||
marginTop:0,
|
||||
|
39
src/components/qrModal/qrModalStyles.ts
Normal file
39
src/components/qrModal/qrModalStyles.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import EStyleSheet from 'react-native-extended-stylesheet';
|
||||
|
||||
export default EStyleSheet.create({
|
||||
sheetContent: {
|
||||
backgroundColor: '$black',
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
zIndex: 999,
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
mainContainer: {
|
||||
backgroundColor: '$black',
|
||||
height: '100%',
|
||||
},
|
||||
scannerContainer: {
|
||||
backgroundColor: '$black',
|
||||
},
|
||||
cameraContainer: {
|
||||
backgroundColor: '$black',
|
||||
},
|
||||
cameraStyle: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
activityIndicatorContainer: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
activityIndicator: {},
|
||||
});
|
163
src/components/qrModal/qrModalView.tsx
Normal file
163
src/components/qrModal/qrModalView.tsx
Normal file
@ -0,0 +1,163 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { ActivityIndicator, Alert, PermissionsAndroid, Platform, Text, View } from 'react-native';
|
||||
import ActionSheet from 'react-native-actions-sheet';
|
||||
import EStyleSheet from 'react-native-extended-stylesheet';
|
||||
import styles from './qrModalStyles';
|
||||
import { useAppDispatch, useAppSelector } from '../../hooks';
|
||||
import { toggleQRModal } from '../../redux/actions/uiAction';
|
||||
import QRCodeScanner from 'react-native-qrcode-scanner';
|
||||
import { deepLinkParser } from '../../utils/deepLinkParser';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { navigate } from '../../navigation/service';
|
||||
import { Icon } from '..';
|
||||
import { Dimensions } from 'react-native';
|
||||
import { check, request, PERMISSIONS, RESULTS, openSettings } from 'react-native-permissions';
|
||||
|
||||
export interface QRModalProps {}
|
||||
|
||||
const screenHeight = Dimensions.get('window').height;
|
||||
export const QRModal = ({}: QRModalProps) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
const isVisibleQRModal = useAppSelector((state) => state.ui.isVisibleQRModal);
|
||||
const currentAccount = useAppSelector((state) => state.account.currentAccount);
|
||||
|
||||
const [isScannerActive, setIsScannerActive] = useState(true);
|
||||
const [isProcessing, setIsProcessing] = useState(false);
|
||||
const sheetModalRef = useRef<ActionSheet>();
|
||||
const scannerRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (isVisibleQRModal) {
|
||||
requestCameraPermission();
|
||||
sheetModalRef.current.show();
|
||||
} else {
|
||||
sheetModalRef.current.hide();
|
||||
}
|
||||
}, [isVisibleQRModal]);
|
||||
|
||||
const requestCameraPermission = async () => {
|
||||
if (Platform.OS === 'ios') {
|
||||
const permissionStatus = await check(PERMISSIONS.IOS.CAMERA);
|
||||
if (permissionStatus !== RESULTS.GRANTED) {
|
||||
request(PERMISSIONS.IOS.CAMERA).then((result) => {
|
||||
if (result === RESULTS.GRANTED) {
|
||||
console.log('Camera permission granted');
|
||||
} else {
|
||||
console.log('Camera permission blocked');
|
||||
Alert.alert(
|
||||
'Unable to get Camera permission',
|
||||
'Please grant camera permission in ecency settings.',
|
||||
[
|
||||
{
|
||||
text: 'Close',
|
||||
onPress: () => {
|
||||
_onClose();
|
||||
},
|
||||
style: 'cancel',
|
||||
},
|
||||
{
|
||||
text: 'Allow',
|
||||
onPress: () => {
|
||||
openSettings();
|
||||
},
|
||||
},
|
||||
],
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (Platform.OS === 'android') {
|
||||
try {
|
||||
const permissionStatus = await PermissionsAndroid.check(
|
||||
PermissionsAndroid.PERMISSIONS.CAMERA,
|
||||
);
|
||||
if (!permissionStatus) {
|
||||
const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA, {
|
||||
title: 'Ecency Camera Permission',
|
||||
message: 'To scan QR, Ecency needs your permission.',
|
||||
buttonNegative: 'Cancel',
|
||||
buttonPositive: 'OK',
|
||||
});
|
||||
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
|
||||
console.log('Camera permission granted');
|
||||
} else {
|
||||
console.log('Camera permission denied');
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const _onClose = () => {
|
||||
dispatch(toggleQRModal(false));
|
||||
};
|
||||
|
||||
const onSuccess = (e) => {
|
||||
setIsScannerActive(false);
|
||||
_handleDeepLink(e.data);
|
||||
};
|
||||
|
||||
const _handleDeepLink = async (url) => {
|
||||
setIsProcessing(true);
|
||||
const deepLinkData = await deepLinkParser(url, currentAccount);
|
||||
const { routeName, params, key } = deepLinkData || {};
|
||||
setIsProcessing(false);
|
||||
if (routeName && params && key) {
|
||||
setIsScannerActive(false);
|
||||
_onClose();
|
||||
navigate(deepLinkData);
|
||||
} else {
|
||||
Alert.alert('Unsupported URL!', 'Please scan a valid ecency url.', [
|
||||
{
|
||||
text: 'Close',
|
||||
onPress: () => {
|
||||
_onClose();
|
||||
},
|
||||
style: 'cancel',
|
||||
},
|
||||
{
|
||||
text: 'Rescan',
|
||||
onPress: () => {
|
||||
setIsScannerActive(true);
|
||||
scannerRef.current?.reactivate();
|
||||
},
|
||||
},
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ActionSheet
|
||||
ref={sheetModalRef}
|
||||
gestureEnabled={true}
|
||||
containerStyle={{ ...styles.sheetContent, height: screenHeight }}
|
||||
onClose={_onClose}
|
||||
indicatorColor={EStyleSheet.value('$primaryWhiteLightBackground')}
|
||||
>
|
||||
<View style={styles.mainContainer}>
|
||||
<QRCodeScanner
|
||||
reactivate={isScannerActive}
|
||||
showMarker={true}
|
||||
ref={scannerRef}
|
||||
onRead={onSuccess}
|
||||
topViewStyle={{ display: 'none' }}
|
||||
bottomViewStyle={{ display: 'none' }}
|
||||
containerStyle={styles.scannerContainer}
|
||||
cameraContainerStyle={styles.cameraContainer}
|
||||
cameraStyle={styles.cameraStyle}
|
||||
/>
|
||||
{isProcessing && (
|
||||
<View style={styles.activityIndicatorContainer}>
|
||||
<ActivityIndicator color={'white'} style={styles.activityIndicator} />
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</ActionSheet>
|
||||
);
|
||||
};
|
||||
|
||||
export default QRModal;
|
@ -12,6 +12,7 @@ import { injectIntl, useIntl } from 'react-intl';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import VersionNumber from 'react-native-version-number';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { getStorageType } from '../../../realm/realm';
|
||||
|
||||
// Components
|
||||
@ -28,6 +29,7 @@ import { getVotingPower } from '../../../utils/manaBar';
|
||||
// Styles
|
||||
import styles from './sideMenuStyles';
|
||||
import { OptionsModal } from '../../atoms';
|
||||
import { toggleQRModal } from '../../../redux/actions/uiAction';
|
||||
|
||||
// Images
|
||||
const SIDE_MENU_BACKGROUND = require('../../../assets/side_menu_background.png');
|
||||
@ -40,6 +42,7 @@ const SideMenuView = ({
|
||||
handlePressOptions,
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useDispatch();
|
||||
const ActionSheetRef = useRef(null);
|
||||
|
||||
const [menuItems, setMenuItems] = useState(
|
||||
@ -81,6 +84,10 @@ const SideMenuView = ({
|
||||
});
|
||||
return;
|
||||
} */
|
||||
if (item.id === 'qr') {
|
||||
dispatch(toggleQRModal(true));
|
||||
return;
|
||||
}
|
||||
|
||||
navigateToRoute(item.route);
|
||||
};
|
||||
@ -102,7 +109,11 @@ const SideMenuView = ({
|
||||
>
|
||||
<View style={styles.itemWrapper}>
|
||||
{item.item.icon && (
|
||||
<Icon iconType="SimpleLineIcons" style={styles.listItemIcon} name={item.item.icon} />
|
||||
<Icon
|
||||
iconType={item.item.iconType ? item.item.iconType : 'SimpleLineIcons'}
|
||||
style={styles.listItemIcon}
|
||||
name={item.item.icon}
|
||||
/>
|
||||
)}
|
||||
{item.item.username && (
|
||||
<UserAvatar noAction username={item.item.username} style={styles.otherUserAvatar} />
|
||||
|
@ -290,7 +290,8 @@
|
||||
"create_a_new_account": "Create a new account",
|
||||
"add_an_existing_account": "Add an existing account",
|
||||
"accounts": "Accounts",
|
||||
"refer":"Refer & Earn"
|
||||
"refer":"Refer & Earn",
|
||||
"qr": "QR Scan"
|
||||
},
|
||||
"header": {
|
||||
"title": "Login to customize your feed",
|
||||
@ -759,6 +760,11 @@
|
||||
"delegate_hp": "Delegate HP",
|
||||
"earned": "Earned Points",
|
||||
"pending": "Pending Points",
|
||||
"empty_text": "Refer your loved ones today and earn free points"
|
||||
"empty_text": "Refer your loved ones today and earn free points",
|
||||
},
|
||||
"qr":{
|
||||
"qr_scan": "QR Scan",
|
||||
"open": "Open URL",
|
||||
"detected_url": "Detected URL"
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ export default {
|
||||
COMMUNITIES: `Communities${SCREEN_SUFFIX}`,
|
||||
WEB_BROWSER: `WebBrowser${SCREEN_SUFFIX}`,
|
||||
REFER: `Refer${SCREEN_SUFFIX}`,
|
||||
QR: `QR${SCREEN_SUFFIX}`,
|
||||
COIN_DETAILS: `CoinDetails${SCREEN_SUFFIX}`,
|
||||
},
|
||||
DRAWER: {
|
||||
|
@ -25,6 +25,13 @@ const authMenuItems = [
|
||||
icon: 'people',
|
||||
id: 'communities',
|
||||
},
|
||||
{
|
||||
name: 'QR Scan',
|
||||
route: '',
|
||||
icon: 'qrcode-scan',
|
||||
iconType: 'MaterialCommunityIcons',
|
||||
id: 'qr',
|
||||
},
|
||||
{
|
||||
name: 'Refer $ Earn',
|
||||
route: ROUTES.SCREENS.REFER,
|
||||
|
@ -49,6 +49,7 @@ import { Comment, Vote } from '../reducers/cacheReducer';
|
||||
comment.author_reputation = comment.author_reputation || 25;
|
||||
comment.total_payout = comment.total_payout || 0;
|
||||
comment.json_metadata = comment.json_metadata || makeJsonMetadataReply(options.parentTags)
|
||||
comment.isDeletable = comment.isDeletable || true;
|
||||
|
||||
comment.body = renderPostBody({
|
||||
author:comment.author,
|
||||
|
@ -10,7 +10,8 @@ import {
|
||||
HIDE_ACTION_MODAL,
|
||||
SET_AVATAR_CACHE_STAMP,
|
||||
SHOW_PROFILE_MODAL,
|
||||
HIDE_PROFILE_MODAL
|
||||
HIDE_PROFILE_MODAL,
|
||||
TOGGLE_QR_MODAL
|
||||
} from '../constants/constants';
|
||||
|
||||
export const updateActiveBottomTab = (payload:string) => ({
|
||||
@ -70,3 +71,8 @@ export const setAvatarCacheStamp = (payload:number) => ({
|
||||
payload,
|
||||
type:SET_AVATAR_CACHE_STAMP
|
||||
})
|
||||
|
||||
export const toggleQRModal = (payload:boolean) => ({
|
||||
payload,
|
||||
type: TOGGLE_QR_MODAL,
|
||||
});
|
||||
|
@ -52,6 +52,7 @@ export const TOAST_NOTIFICATION = 'TOAST_NOTIFICATION';
|
||||
export const HIDE_POSTS_THUMBNAILS = 'HIDE_POSTS_THUMBNAILS';
|
||||
export const RC_OFFER = 'RC_OFFER';
|
||||
export const TOGGLE_ACCOUNTS_BOTTOM_SHEET = 'TOGGLE_ACCOUNTS_BOTTOM_SHEET';
|
||||
export const TOGGLE_QR_MODAL = 'TOGGLE_QR_MODAL';
|
||||
export const SHOW_ACTION_MODAL = 'SHOW_ACTION_MODAL';
|
||||
export const HIDE_ACTION_MODAL = 'HIDE_ACTION_MODAL';
|
||||
export const SET_AVATAR_CACHE_STAMP = 'SET_AVATAR_CACHE_STAMP';
|
||||
|
@ -20,6 +20,7 @@ export interface Comment {
|
||||
net_rshares?:number,
|
||||
active_votes?:Array<{rshares:number, voter:string}>,
|
||||
json_metadata?:any,
|
||||
isDeletable?:boolean,
|
||||
created?:string, //handle created and updated separatly
|
||||
updated?:string,
|
||||
expiresAt?:number,
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
SET_AVATAR_CACHE_STAMP,
|
||||
SHOW_PROFILE_MODAL,
|
||||
HIDE_PROFILE_MODAL,
|
||||
TOGGLE_QR_MODAL,
|
||||
} from '../constants/constants';
|
||||
|
||||
interface UiState {
|
||||
@ -21,6 +22,7 @@ interface UiState {
|
||||
actionModalData:any;
|
||||
avatarCacheStamp:number;
|
||||
profileModalUsername:string;
|
||||
isVisibleQRModal:boolean;
|
||||
}
|
||||
|
||||
const initialState:UiState = {
|
||||
@ -32,7 +34,8 @@ const initialState:UiState = {
|
||||
actionModalVisible: false,
|
||||
actionModalData: null,
|
||||
avatarCacheStamp: 0,
|
||||
profileModalUsername: ''
|
||||
profileModalUsername: '',
|
||||
isVisibleQRModal: false,
|
||||
};
|
||||
|
||||
export default function (state = initialState, action) {
|
||||
@ -101,6 +104,11 @@ export default function (state = initialState, action) {
|
||||
...state,
|
||||
avatarCacheStamp: action.payload
|
||||
}
|
||||
case TOGGLE_QR_MODAL:
|
||||
return {
|
||||
...state,
|
||||
isVisibleQRModal: action.payload,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import AsyncStorage from '@react-native-community/async-storage';
|
||||
import Reactotron from '../../../reactotron-config';
|
||||
|
||||
import reducer from '../reducers';
|
||||
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
|
||||
|
||||
const transformCacheVoteMap = createTransform(
|
||||
(inboundState:any) => ({
|
||||
@ -44,7 +45,7 @@ const persistConfig = {
|
||||
};
|
||||
|
||||
// Middleware: Redux Persist Persisted Reducer
|
||||
const persistedReducer = persistReducer(persistConfig, reducer);
|
||||
const persistedReducer = persistReducer(persistConfig, reducer as any);
|
||||
|
||||
const middleware = [thunk];
|
||||
|
||||
|
@ -26,6 +26,7 @@ import {
|
||||
ActionModal,
|
||||
ForegroundNotification,
|
||||
QuickProfileModal,
|
||||
QRModal,
|
||||
} from '../../../components';
|
||||
|
||||
// Themes (Styles)
|
||||
@ -174,6 +175,7 @@ class ApplicationScreen extends Component {
|
||||
<AccountsBottomSheet />
|
||||
<ActionModal />
|
||||
<QuickProfileModal navigation={{ navigate }} />
|
||||
<QRModal />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { Alert, Text, View } from 'react-native';
|
||||
import { Text, TouchableOpacity, View } from 'react-native';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
import { FlatList, TouchableOpacity } from 'react-native-gesture-handler';
|
||||
import { FlatList } from 'react-native-gesture-handler';
|
||||
import { extractImageUrls } from '../../../utils/editor';
|
||||
import styles from './styles';
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
import React, { useImperativeHandle, useRef, useState } from 'react';
|
||||
import { FlatList, TouchableOpacity } from 'react-native-gesture-handler';
|
||||
import { FlatList } from 'react-native-gesture-handler';
|
||||
import ActionSheet from 'react-native-actions-sheet';
|
||||
import EStyleSheet from 'react-native-extended-stylesheet';
|
||||
import styles from './styles';
|
||||
import { extractImageUrls } from '../../../utils/editor';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
import { forwardRef } from 'react';
|
||||
import { View, Text, Alert } from 'react-native';
|
||||
import { View, Text, Alert, TouchableOpacity } from 'react-native';
|
||||
import { useIntl } from 'react-intl';
|
||||
|
||||
|
||||
|
90
src/utils/deepLinkParser.ts
Normal file
90
src/utils/deepLinkParser.ts
Normal file
@ -0,0 +1,90 @@
|
||||
import { getPost, getUser } from '../providers/hive/dhive';
|
||||
import postUrlParser from './postUrlParser';
|
||||
import parseAuthUrl from './parseAuthUrl';
|
||||
import get from 'lodash/get';
|
||||
import ROUTES from '../constants/routeNames';
|
||||
|
||||
export const deepLinkParser = async (url, currentAccount) => {
|
||||
if (!url || url.indexOf('ShareMedia://') >= 0) return;
|
||||
|
||||
let routeName;
|
||||
let params;
|
||||
let content;
|
||||
let profile;
|
||||
let keey;
|
||||
|
||||
const postUrl = postUrlParser(url);
|
||||
console.log('postUrl : ', postUrl);
|
||||
|
||||
const { author, permlink, feedType, tag } = postUrl || {};
|
||||
|
||||
if (author) {
|
||||
if (
|
||||
!permlink ||
|
||||
permlink === 'wallet' ||
|
||||
permlink === 'points' ||
|
||||
permlink === 'comments' ||
|
||||
permlink === 'replies' ||
|
||||
permlink === 'posts'
|
||||
) {
|
||||
let deepLinkFilter;
|
||||
if (permlink) {
|
||||
deepLinkFilter = permlink === 'points' ? 'wallet' : permlink;
|
||||
}
|
||||
|
||||
profile = await getUser(author);
|
||||
routeName = ROUTES.SCREENS.PROFILE;
|
||||
params = {
|
||||
username: get(profile, 'name'),
|
||||
reputation: get(profile, 'reputation'),
|
||||
deepLinkFilter, //TODO: process this in profile screen
|
||||
};
|
||||
keey = get(profile, 'name');
|
||||
} else if (permlink === 'communities') {
|
||||
routeName = ROUTES.SCREENS.WEB_BROWSER;
|
||||
params = {
|
||||
url: url,
|
||||
};
|
||||
keey = 'WebBrowser';
|
||||
} else if (permlink) {
|
||||
content = await getPost(author, permlink, currentAccount.name);
|
||||
routeName = ROUTES.SCREENS.POST;
|
||||
params = {
|
||||
content,
|
||||
};
|
||||
keey = `${author}/${permlink}`;
|
||||
}
|
||||
}
|
||||
|
||||
if (feedType === 'hot' || feedType === 'trending' || feedType === 'created') {
|
||||
if (!tag) {
|
||||
routeName = ROUTES.SCREENS.TAG_RESULT;
|
||||
} else if (/hive-[1-3]\d{4,6}$/.test(tag)) {
|
||||
routeName = ROUTES.SCREENS.COMMUNITY;
|
||||
} else {
|
||||
routeName = ROUTES.SCREENS.TAG_RESULT;
|
||||
}
|
||||
params = {
|
||||
tag,
|
||||
filter: feedType,
|
||||
};
|
||||
keey = `${feedType}/${tag || ''}`;
|
||||
}
|
||||
|
||||
if (!routeName) {
|
||||
const { mode, referredUser } = parseAuthUrl(url) || {};
|
||||
if (mode === 'SIGNUP') {
|
||||
routeName = ROUTES.SCREENS.REGISTER;
|
||||
params = {
|
||||
referredUser,
|
||||
};
|
||||
keey = `${mode}/${referredUser || ''}`;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
routeName: routeName,
|
||||
params: params,
|
||||
key: keey,
|
||||
};
|
||||
};
|
@ -165,6 +165,8 @@ export const parseComment = (comment:any) => {
|
||||
|
||||
comment.total_payout = totalPayout;
|
||||
|
||||
comment.isDeletable = !(comment.active_votes?.length > 0 ||comment.children > 0 || comment.net_rshares > 0 || comment.is_paidout);
|
||||
|
||||
//stamp comments with fetched time;
|
||||
comment.post_fetched_at = new Date().getTime();
|
||||
|
||||
|
45
yarn.lock
45
yarn.lock
@ -1475,6 +1475,13 @@
|
||||
htmlparser2 "^6.1.0"
|
||||
ramda "^0.27.1"
|
||||
|
||||
"@react-native-async-storage/async-storage@^1.13.4":
|
||||
version "1.16.1"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-async-storage/async-storage/-/async-storage-1.16.1.tgz#1dbaa9e0f9736e4ab8fc04c628bbb608fd80b068"
|
||||
integrity sha512-aQ7ka+Ii1e/q+7AVFIZPt4kDeSH8b784wMDtz19Kf4A7hf+OgCHBlUQpOXsrv8XxhlBxu0hv4tfrDO15ChnV0Q==
|
||||
dependencies:
|
||||
merge-options "^3.0.4"
|
||||
|
||||
"@react-native-community/async-storage@1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/async-storage/-/async-storage-1.5.0.tgz#647ffcd832272068b0be57332e08d73036ed391f"
|
||||
@ -5733,6 +5740,11 @@ is-observable@^1.1.0:
|
||||
dependencies:
|
||||
symbol-observable "^1.1.0"
|
||||
|
||||
is-plain-obj@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
|
||||
integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
|
||||
|
||||
is-plain-object@^2.0.3, is-plain-object@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
|
||||
@ -7028,6 +7040,13 @@ mdn-data@2.0.14:
|
||||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
|
||||
integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
|
||||
|
||||
merge-options@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/merge-options/-/merge-options-3.0.4.tgz#84709c2aa2a4b24c1981f66c179fe5565cc6dbb7"
|
||||
integrity sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==
|
||||
dependencies:
|
||||
is-plain-obj "^2.1.0"
|
||||
|
||||
merge-stream@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1"
|
||||
@ -8539,6 +8558,13 @@ react-native-autoheight-webview@^1.5.8:
|
||||
dependencies:
|
||||
prop-types "^15.7.2"
|
||||
|
||||
react-native-camera@^4.2.1:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-4.2.1.tgz#caf74081f055e89d7e9b0cd5108965d808c60e90"
|
||||
integrity sha512-+Vkql24PFYQfsPRznJCvPwJQfyzCnjlcww/iZ4Ej80bgivKjL9eU0IMQIXp4yi6XCrKi4voWXxIDPMupQZKeIQ==
|
||||
dependencies:
|
||||
prop-types "^15.6.2"
|
||||
|
||||
react-native-chart-kit@^6.11.0:
|
||||
version "6.11.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-chart-kit/-/react-native-chart-kit-6.11.0.tgz#513e0944cd8f946e1827facc17fe766ae487d91b"
|
||||
@ -8726,6 +8752,16 @@ react-native-os@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/react-native-os/-/react-native-os-1.2.6.tgz#1bb16d78ccad1143972183a04f443cf1af9fbefa"
|
||||
integrity sha512-OlT+xQAcvkcnf7imgXiu+myMkqDt4xw2bP5SlVo19hEn5XHBkPMLX7dk3sSGxxncH/ToMDsf1KLyrPabNVtadA==
|
||||
|
||||
react-native-permissions@^2.0.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/react-native-permissions/-/react-native-permissions-2.2.2.tgz#3d2a63f6b7d6be52fc86e30f77412a9566283028"
|
||||
integrity sha512-ihf4shQDSX5Oo9ChQXb9kr13mmyyNem5MaEvOpr3dCjhBOBWyEMztXm9/uPK1Qg5PsNpaYLa1KpcPZDCw87LXg==
|
||||
|
||||
react-native-permissions@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-permissions/-/react-native-permissions-3.3.0.tgz#f63b7f91457dd2b11991ca46ebe4262a8eb1f73c"
|
||||
integrity sha512-F0Yjcp0V340lQW2ibg1lTGmStsMoWsBtosSCRIZOatOQAsNMp77zL6SdYcIGwJUBMVDX3BMraB4AX4Ph3cW1NA==
|
||||
|
||||
react-native-portalize@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/react-native-portalize/-/react-native-portalize-1.0.7.tgz#8b3c742a06f863654d526ea1075a8596625f8482"
|
||||
@ -8743,6 +8779,15 @@ react-native-push-notification@^7.3.1:
|
||||
resolved "https://registry.yarnpkg.com/react-native-push-notification/-/react-native-push-notification-7.3.1.tgz#1495feacd25169b998446dcf7b448a197ae5dca0"
|
||||
integrity sha512-5kSKPvDU23uZRmzgKTsGhbwGNvB2tidu1VnInBHP53ZD0VEPSBl5fbpuTfHH98ED+Gp1SCcT2/e6bJWkIspKvg==
|
||||
|
||||
react-native-qrcode-scanner@^1.5.5:
|
||||
version "1.5.5"
|
||||
resolved "https://registry.yarnpkg.com/react-native-qrcode-scanner/-/react-native-qrcode-scanner-1.5.5.tgz#0d20101712715da108742a2bbbd0397569031b01"
|
||||
integrity sha512-il79uStkFqUvofqXJQfOL30qgQyU17MUKxj7IGHv6oT2OxIY/vutTwuPPDbsivtv0yTMHP4dGx/79oys4eAuNw==
|
||||
dependencies:
|
||||
"@react-native-async-storage/async-storage" "^1.13.4"
|
||||
prop-types "^15.5.10"
|
||||
react-native-permissions "^2.0.2"
|
||||
|
||||
react-native-qrcode-svg@^6.0.3:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/react-native-qrcode-svg/-/react-native-qrcode-svg-6.1.1.tgz#19dd15545b1cbcfc1b2738af170e9fd0f1d4d8a0"
|
||||
|
Loading…
Reference in New Issue
Block a user