mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-12-21 20:31:37 +03:00
url validation
This commit is contained in:
parent
c50dd07e74
commit
6e84ee5f37
@ -745,6 +745,7 @@
|
|||||||
},
|
},
|
||||||
"qr":{
|
"qr":{
|
||||||
"qr_scan": "QR Scan",
|
"qr_scan": "QR Scan",
|
||||||
"open": "Open URL"
|
"open": "Open URL",
|
||||||
|
"detected_url": "Detected URL"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,139 +1,70 @@
|
|||||||
import React, { Fragment, useRef, useState } from 'react';
|
import React, { Fragment, useRef, useState } from 'react';
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
import { View, Text, ScrollView, Button, TouchableOpacity, Dimensions } from 'react-native';
|
import { View, Text } from 'react-native';
|
||||||
import { BasicHeader, MainButton } from '../../components';
|
import { BasicHeader, Icon, MainButton } from '../../components';
|
||||||
import QRCodeScanner from 'react-native-qrcode-scanner';
|
import QRCodeScanner from 'react-native-qrcode-scanner';
|
||||||
|
import { useAppSelector } from '../../hooks';
|
||||||
|
import { navigate } from '../../navigation/service';
|
||||||
|
import { deepLinkParser } from '../../utils/deepLinkParser';
|
||||||
// styles
|
// styles
|
||||||
import styles from './qrScreenStyle';
|
import styles from './qrScreenStyle';
|
||||||
import { useAppSelector } from '../../hooks';
|
|
||||||
import postUrlParser from '../../utils/postUrlParser';
|
|
||||||
import { getPost, getUser } from '../../providers/hive/dhive';
|
|
||||||
import ROUTES from '../../constants/routeNames';
|
|
||||||
import get from 'lodash/get';
|
|
||||||
import parseAuthUrl from '../../utils/parseAuthUrl';
|
|
||||||
import { navigate } from '../../navigation/service';
|
|
||||||
|
|
||||||
const screenWidth = Dimensions.get('screen').width;
|
|
||||||
const QRScreen = () => {
|
const QRScreen = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const currentAccount = useAppSelector((state) => state.account.currentAccount);
|
const currentAccount = useAppSelector((state) => state.account.currentAccount);
|
||||||
|
|
||||||
const [isActive, setIsActive] = useState(true);
|
const [isActive, setIsActive] = useState(true);
|
||||||
const [scanResult, setScanResult] = useState(null);
|
const [scanURL, setScanURL] = useState(null);
|
||||||
|
const [navData, setNavData] = useState(null);
|
||||||
|
const [isURLValid, setIsURLValid] = useState(false);
|
||||||
|
|
||||||
const scannerRef = useRef(null);
|
const scannerRef = useRef(null);
|
||||||
const onSuccess = (e) => {
|
const onSuccess = (e) => {
|
||||||
setScanResult(e.data);
|
_handleDeepLink(e.data);
|
||||||
setIsActive(false);
|
setIsActive(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const _handleOpen = () => {
|
const _handleOpen = () => {
|
||||||
console.log('scanResult : ', scanResult);
|
if (navData) {
|
||||||
_handleDeepLink(scanResult)
|
navigate(navData);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const _handleDeepLink = async (url = '') => {
|
const _handleDeepLink = async (url) => {
|
||||||
if (!url || url.indexOf('ShareMedia://') >= 0) return;
|
const deepLinkData = await deepLinkParser(url, currentAccount);
|
||||||
|
const { routeName, params, key } = deepLinkData || {};
|
||||||
let routeName;
|
setNavData(routeName && params && key ? deepLinkData : null);
|
||||||
let params;
|
setIsURLValid(routeName && params && key ? true : false);
|
||||||
let content;
|
setScanURL(url);
|
||||||
let profile;
|
|
||||||
let keey;
|
|
||||||
|
|
||||||
const postUrl = postUrlParser(url);
|
|
||||||
const { author, permlink, feedType, tag } = postUrl || {};
|
|
||||||
|
|
||||||
try {
|
|
||||||
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 || ''}`;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
// this._handleAlert('deep_link.no_existing_user');
|
|
||||||
console.log('No existing user!');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!routeName) {
|
|
||||||
const { mode, referredUser } = parseAuthUrl(url);
|
|
||||||
if (mode === 'SIGNUP') {
|
|
||||||
routeName = ROUTES.SCREENS.REGISTER;
|
|
||||||
params = {
|
|
||||||
referredUser,
|
|
||||||
};
|
|
||||||
keey = `${mode}/${referredUser || ''}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (routeName && keey) {
|
|
||||||
navigate({
|
|
||||||
routeName,
|
|
||||||
params,
|
|
||||||
key: keey,
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
console.log('unable to open url');
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const _renderBottomContent = () => {
|
const _renderBottomContent = () => {
|
||||||
return (
|
return (
|
||||||
<View style={styles.bottomContent}>
|
<View style={styles.bottomContent}>
|
||||||
<Text>Detected URL:</Text>
|
<View style={styles.urlContainer}>
|
||||||
<Text>{scanResult}</Text>
|
<View style={styles.urlTextContainer}>
|
||||||
|
<Text>
|
||||||
|
{intl.formatMessage({
|
||||||
|
id: 'qr.detected_url',
|
||||||
|
})}
|
||||||
|
:
|
||||||
|
</Text>
|
||||||
|
<Text>{scanURL}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.validIcon}>
|
||||||
|
{scanURL && (
|
||||||
|
<Icon
|
||||||
|
iconType="Ionicons"
|
||||||
|
name={isURLValid ? 'checkmark-circle-outline' : 'close-circle-outline'}
|
||||||
|
size={20}
|
||||||
|
color={isURLValid ? 'green' : 'red'}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
<MainButton
|
<MainButton
|
||||||
// isLoading={isLoading}
|
// isLoading={isLoading}
|
||||||
isDisable={isActive}
|
isDisable={isActive || !isURLValid}
|
||||||
style={styles.mainButton}
|
style={styles.mainButton}
|
||||||
height={50}
|
height={50}
|
||||||
onPress={_handleOpen}
|
onPress={_handleOpen}
|
||||||
@ -166,8 +97,7 @@ const QRScreen = () => {
|
|||||||
bottomContent={_renderBottomContent()}
|
bottomContent={_renderBottomContent()}
|
||||||
containerStyle={styles.scannerContainer}
|
containerStyle={styles.scannerContainer}
|
||||||
cameraContainerStyle={styles.cameraContainer}
|
cameraContainerStyle={styles.cameraContainer}
|
||||||
cameraStyle={{ alignSelf: 'center', justifyContent: 'center', width: 200 }}
|
cameraStyle={styles.cameraStyle}
|
||||||
cameraProps={{}}
|
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
@ -31,4 +31,21 @@ export default EStyleSheet.create({
|
|||||||
alignSelf: 'center',
|
alignSelf: 'center',
|
||||||
textTransform: 'uppercase',
|
textTransform: 'uppercase',
|
||||||
},
|
},
|
||||||
|
urlContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
paddingVertical: 16,
|
||||||
|
},
|
||||||
|
urlTextContainer: {
|
||||||
|
flex: 1,
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
},
|
||||||
|
validIcon: {
|
||||||
|
width: 30,
|
||||||
|
},
|
||||||
|
cameraStyle: {
|
||||||
|
alignSelf: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
width: 200,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user