Introduced thumbnail selection modal

This commit is contained in:
Nouman Tahir 2021-08-17 20:54:19 +05:00
parent 081e8db658
commit 3bc48fcb16
4 changed files with 167 additions and 12 deletions

View File

@ -320,7 +320,8 @@
"alert_btn_yes":"Yes",
"alert_btn_no":"No",
"draft_save_success":"Draft Saved",
"draft_save_fail":"Failed to save draft"
"draft_save_fail":"Failed to save draft",
"select_thumb":"Select Post Thumbnail"
},
"snippets":{
"label_no_snippets":"No Snippets Found",

View File

@ -0,0 +1,98 @@
import React, { useImperativeHandle, useRef, useState } from 'react';
import { FlatList, TouchableOpacity } from 'react-native-gesture-handler';
import ActionSheet from 'react-native-actions-sheet';
import EStyleSheet from 'react-native-extended-stylesheet';
import styles from './thumbSelectionModalStyles';
import { extractImageUrls } from '../../../utils/editor';
import FastImage from 'react-native-fast-image';
import { forwardRef } from 'react';
import { View, Text } from 'react-native';
import { useIntl } from 'react-intl';
export interface ThumbSelectionModalProps {
onThumbSelection:(index:number)=>void,
}
const ThumbSelectionModal = ({ onThumbSelection }:ThumbSelectionModalProps, ref) => {
const intl = useIntl();
const [imageUrls, setImageUrls] = useState<string[]>([]);
const sheetModalRef = useRef<ActionSheet>();
//CALLBACK_METHODS
useImperativeHandle(ref, () => ({
show: (postBody:string) => {
console.log("Showing action modal")
const urls = extractImageUrls({body:postBody});
if(urls.length < 2){
console.log("Skipping modal show as post images are less than 2");
onThumbSelection(0);
return;
}
setImageUrls(urls);
sheetModalRef.current?.setModalVisible(true);
}
}));
const _onSelection = (index:number) => {
onThumbSelection(index);
sheetModalRef.current?.setModalVisible(false);
}
//VIEW_RENDERERS
const _renderImageItem = ({item, index}:{item:string, index:number}) => {
const _onPress = () => {
_onSelection(index);
}
return (
<TouchableOpacity onPress={_onPress} >
<FastImage
source={{uri:item}}
style={styles.thumbStyle}
resizeMode='cover'
/>
</TouchableOpacity>
)
}
const _renderContent = () => {
return (
<View style={{alignItems:'center'}} >
<Text style={styles.title}>{intl.formatMessage({id:'editor.select_thumb'})}</Text>
<FlatList
data={imageUrls}
renderItem={_renderImageItem}
keyExtractor={(item, index)=>item.url + index}
horizontal={true}
contentContainerStyle={styles.listContainer}
showsHorizontalScrollIndicator={false}
/>
</View>
)
}
return (
<ActionSheet
ref={sheetModalRef}
gestureEnabled={false}
hideUnderlay
containerStyle={styles.sheetContent}
indicatorColor={EStyleSheet.value('$primaryWhiteLightBackground')}
>
{_renderContent()}
</ActionSheet>
);
};
export default forwardRef(ThumbSelectionModal);

View File

@ -0,0 +1,32 @@
import EStyleSheet from 'react-native-extended-stylesheet';
import { getBottomSpace } from 'react-native-iphone-x-helper';
export default EStyleSheet.create({
sheetContent: {
backgroundColor: '$primaryBackgroundColor',
position:'absolute',
bottom:0,
left:0,
right:0,
zIndex:999
},
thumbStyle:{
width:100,
height:100,
margin:8,
borderRadius:12,
backgroundColor:'$primaryLightGray'
},
title:{
color: '$primaryBlack',
fontWeight: 'bold',
fontSize: 18,
padding: 16,
textAlign:'center'
},
listContainer:{
paddingHorizontal:8,
paddingBottom:getBottomSpace() + 16,
}
});

View File

@ -129,35 +129,59 @@ export const makeJsonMetadataForUpdate = (oldJson, meta, tags) => {
return Object.assign({}, oldJson, mergedMeta, { tags });
};
export const extractMetadata = (body) => {
const extractUrls = (body:string) => {
const urlReg = /(\b(https?|ftp):\/\/[A-Z0-9+&@#/%?=~_|!:,.;-]*[-A-Z0-9+&@#/%=~_|])/gim;
const userReg = /(^|\s)(@[a-z][-.a-z\d]+[a-z\d])/gim;
const mUrls = body && body.match(urlReg);
return mUrls || [];
}
export const extractImageUrls = ({body, urls}:{body?:string, urls?:string[]}) => {
const imgReg = /(https?:\/\/.*\.(?:png|jpg|jpeg|gif|heic|webp))/gim;
let imgUrls = [];
const mUrls = urls || extractUrls(body);
mUrls.forEach((url)=>{
const isImage = url.match(imgReg);
if (isImage) {
imgUrls.push(url);
}
})
return imgUrls;
}
export const extractMetadata = (body:string, thumbIndex?:number) => {
const userReg = /(^|\s)(@[a-z][-.a-z\d]+[a-z\d])/gim;
const out = {};
const mUrls = body && body.match(urlReg);
const mUrls = extractUrls(body);
const mUsers = body && body.match(userReg);
const matchedImages = [];
const matchedImages = extractImageUrls({urls:mUrls});
const matchedLinks = [];
const matchedUsers = [];
if (mUrls) {
for (let i = 0; i < mUrls.length; i++) {
const ind = mUrls[i].match(imgReg);
if (ind) {
matchedImages.push(mUrls[i]);
} else {
matchedLinks.push(mUrls[i]);
mUrls.forEach((url)=>{
if(matchedImages.indexOf(url) < 0){
matchedLinks.push(url);
}
}
})
}
if (matchedLinks.length) {
out.links = matchedLinks;
}
if (matchedImages.length) {
if(thumbIndex){
matchedImages.splice(0, 0, matchedImages.splice(thumbIndex, 1)[0]);
}
out.image = matchedImages;
}