mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-12-02 11:15:35 +03:00
Introduced thumbnail selection modal
This commit is contained in:
parent
081e8db658
commit
3bc48fcb16
@ -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",
|
||||
|
98
src/screens/editor/children/thumbSelectionModal.tsx
Normal file
98
src/screens/editor/children/thumbSelectionModal.tsx
Normal 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);
|
32
src/screens/editor/children/thumbSelectionModalStyles.ts
Normal file
32
src/screens/editor/children/thumbSelectionModalStyles.ts
Normal 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,
|
||||
}
|
||||
});
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user