mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-12-03 11:40:44 +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_yes":"Yes",
|
||||||
"alert_btn_no":"No",
|
"alert_btn_no":"No",
|
||||||
"draft_save_success":"Draft Saved",
|
"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":{
|
"snippets":{
|
||||||
"label_no_snippets":"No Snippets Found",
|
"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 });
|
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 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;
|
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 out = {};
|
||||||
|
|
||||||
const mUrls = body && body.match(urlReg);
|
const mUrls = extractUrls(body);
|
||||||
const mUsers = body && body.match(userReg);
|
const mUsers = body && body.match(userReg);
|
||||||
|
|
||||||
const matchedImages = [];
|
const matchedImages = extractImageUrls({urls:mUrls});
|
||||||
const matchedLinks = [];
|
const matchedLinks = [];
|
||||||
const matchedUsers = [];
|
const matchedUsers = [];
|
||||||
|
|
||||||
if (mUrls) {
|
if (mUrls) {
|
||||||
for (let i = 0; i < mUrls.length; i++) {
|
mUrls.forEach((url)=>{
|
||||||
const ind = mUrls[i].match(imgReg);
|
if(matchedImages.indexOf(url) < 0){
|
||||||
if (ind) {
|
matchedLinks.push(url);
|
||||||
matchedImages.push(mUrls[i]);
|
|
||||||
} else {
|
|
||||||
matchedLinks.push(mUrls[i]);
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchedLinks.length) {
|
if (matchedLinks.length) {
|
||||||
out.links = matchedLinks;
|
out.links = matchedLinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchedImages.length) {
|
if (matchedImages.length) {
|
||||||
|
if(thumbIndex){
|
||||||
|
matchedImages.splice(0, 0, matchedImages.splice(thumbIndex, 1)[0]);
|
||||||
|
}
|
||||||
|
|
||||||
out.image = matchedImages;
|
out.image = matchedImages;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user