React Native how to use fast image for expo using cache - react-native

I uploaded images to firebase storage and fetching it on the display. It's working fine, but I noticed that it reloads every time changing to other page and the speed is quite slow.
So, after googling I found expo-fast-image (because I'm using expo)
https://www.npmjs.com/package/expo-fast-image
so, after installing it, I'm trying to follow or copy the given an example, but I don't know how to use it properly. Below is my code with expo-fast-image.
Does anyone know how to use it properly?
import ExpoFastImage from 'expo-fast-image';
const CustomListItem = ({id, number, data, coffeeBean, description, image, Order}) => {
const user = auth.currentUser;
const name = user.displayName;
const ImageLoad = (image, id) => (
<View>
<ExpoFastImage
uri= {image}
CacheKey={`cache.${id}`}
/>
</View>
)
return (
<ListItem key={id} bottomDivider onPress={() => {Order({id, number, coffeeBean, description, image})}} >
<ExpoFastImage image={image, id}/>
<Avatar rounded source={{CacheKey: `cache.${id}`}} />
<ListItem.Content >
<ListItem.Title style={{ fontWeight: '800'}}>{id}</ListItem.Title>
<ListItem.Subtitle numberOfLines={1} ellipsizeMode='tail'>
Stock: {number}
</ListItem.Subtitle>
</ListItem.Content>
</ListItem>
)
}
export default CustomListItem

If expo-fast-image uses Image from react-native, images are cached and they are downloaded again only when the url changes. So in your situation, you might be giving different urls to the component which propmts it to download again. Make sure the url is always the same. Even if you add some random string like #some-random-value at the end of url which does nothing. It triggers the download action.

Related

PageView's onPageScroll gives wrong position on iPhone 12+

Using "react-native-pager-view": "^6.1.2" package in ReactNative.
I have the same bug as here.
https://github.com/callstack/react-native-pager-view/issues/503
I'm trying PagerView with the code pasted below, but when I swipe to move the page, e.nativeEvent.position is different from the actual page index.
import PagerView, { PagerViewOnPageScrollEvent, PagerViewOnPageSelectedEvent } from 'react-native-pager-view';
import Modal from 'react-native-modal';
const onPageScroll = useCallback((e: PagerViewOnPageScrollEvent) => onPageScrollPagerView(e, setCurrentTabIndex), []);
const onPageScrollPagerView = (
e: PagerViewOnPageScrollEvent,
setCurrentTabIndex: React.Dispatch<React.SetStateAction<number>>,
) => {
console.log(`onPageScroll position = ${e.nativeEvent.position}`);
setCurrentTabIndex(e.nativeEvent.position);
};
return (
<Modal isVisible={isVisible}>
<SafeAreaView>
<View>
<PagerView ref={viewPager} initialPage={0} onPageScroll={onPageScroll} onPageSelected={onPageSelected}>
      {list.map((item) => (
     <View key={item.id}>
    {item.content}
     </View>
      ))}
        </PagerView>
</View>
</SafeAreaView>
</Modal>
);
This is the result obtained when scrolling to the first page.
onPageScroll is called twice, and for some reason the wrong position is returned the second time.
And 0 is set to setCurrentTabIndex.
onPageScroll position = 1
onPageScroll position = 0
Is there any way to resolve this?
It may be related to what you write in <Modal></Modal> of 'react-native-modal'.
As also written here, this problem does not occur on iPhone11, but on iPhone12 and newer devices.
I didn't use 'react-native-modal', I used fullscreen modal.
screenOptions={{ presentation: 'modal' }}

Populte WYSIWYG editor after react native fetch

I am trying to incorporate this WYSIWYG package into my react native project (0.64.3). I built my project with a managed workflow via Expo (~44.0.0).
The problem I am noticing is that the editor will sometimes render with the text from my database and sometimes render without it.
Here is a snippet of the function that retrieves the information from firebase.
const [note, setNote] = useState("");
const getNote = () => {
const myDoc = doc(db,"/users/" + user.uid + "/Destinations/Trip-" + trip.tripID + '/itinerary/' + date);
getDoc(myDoc)
.then(data => {
setNote(data.data()[date]);
}).catch();
}
The above code and the editor component are nested within a large function
export default function ItineraryScreen({route}) {
// functions
return (
<RichEditor
onChange={newText => {
setNote(newText)
}}
scrollEnabled={false}
ref={text}
initialFocus={false}
placeholder={'What are you planning to do this day?'}
initialContentHTML={note}
/>
)
}
Here is what it should look like with the text rendered (screenshot of simulator):
But this is what I get most of the time (screenshot from physical device):
My assumption is that there is a very slight delay between when the data for the text editor is actually available vs. when the editor is being rendered. I believe my simulator renders correctly because it is able to process the getNote() function faster.
what I have tried is using a setTimeOut function to the display of the parent View but it does not address the issue.
What do you recommend?
I believe I have solved the issue. I needed to parse the response better before assigning a value to note and only show the editor and toolbar once a value was established.
Before firebase gets queried, I assigned a null value to note
const [note, setNote] = useState(null);
Below, I will always assign value to note regardless of the outcome.
if(data.data() !== undefined){
setNote(data.data()[date]);
} else {
setNote("");
}
The last step was to only show the editor once note no longer had a null value.
{
note !== null &&
<RichToolbar
style={{backgroundColor:"white", width:"114%", flex:1, position:"absolute", left:0, zIndex:4, bottom: (toolbarVisible) ? keyboardHeight * 1.11 : 0 , marginBottom:-40, display: toolbarVisible ? "flex" : "none"}}
editor={text}
actions={[ actions.undo, actions.setBold, actions.setItalic, actions.setUnderline,actions.insertLink, actions.insertBulletsList, actions.insertOrderedList, actions.keyboard ]}
iconMap={{ [actions.heading1]: ({tintColor}) => (<Text style={[{color: tintColor}]}>H1</Text>), }}
/>
<RichEditor
disabled={disableEditor}
initialFocus={false}
onChange={ descriptionText => { setNote(descriptionText) }}
scrollEnabled={true}
ref={text}
placeholder={'What are you planning to do?'}
initialContentHTML={note}
/>
}
It is working properly.

react-native-image-zoom-viewer library not working as per expectation for image zoom in release build

I am using react-native-image-zoom-viewer for zooming of images when images are clicked in a carousal. The image zoom functionality works fine when the app is running in debug mode. But when i am trying to test this same functionality in release mode, it's not working as expectation.
I am passing props for initial view of the image as 300*300 (height*width), that runs fine on debug mode. But in release mode, the same doesn't work and i think new image size becomes 800*800 but i am never passing any-kind of values like that.
I have already tried by passing proper props as suggested by library as per its document. Did some alterations too. But nothing seems working on debug mode
const imageList = [];
for (let i=0; i<images.length; i++){
imageList.push({url:images[i].uri,width:300,height:300});
}
return(
<ImageViewerLib
imageUrls={imageList}
renderIndicator={()=>{}}
loadingRender={()=><Loader isLoader = { true } style = {{height:100,with:100}} />}
renderArrowLeft={()=>
<View style={{padding: 10}} >
<Icon
type = { 'Ionicons' }
name = { 'arrow-round-back' }
/>
</View>
}
renderArrowRight={()=>
<View style={{padding: 10}}>
<Icon
type = { 'Ionicons' }
name = { 'arrow-round-forward' }
/>
</View>
}
backgroundColor="white"
index={imageIndex}
saveToLocalByLongPress={false}
enablePreload={true}
flipThreshold={50}
maxOverflow={300}
/>
);
As you can see in the above code that i am passing fixed image width and height which works smoothly in debug mode.
But when in release mode, this size doesn't work. Initial rendered image is much lager that above provided dimension.

react-native-camera slow on react native android

I'm using react-native-camera library in my React Native project.
But I have a problem when I try to take the photo. It takes 3-4 seconds before the photo is saved. When I click on the button to take the photo I hear sound but then it takes about 3-4 seconds to save the photo.
The render method is as follows:
return (
<View style={styles.container}>
<Camera ref={(cam) => {this.camera = cam;}}
style={styles.preview}
aspect={Camera.constants.Aspect.fill}>
{this.imageOverlay()}
<Text style={styles.capture} onPress={this.takePicture.bind(this, this.state.type)}>[CAPTURE]</Text>
</Camera>
</View>
)
And takePicture function is as follows:
takePicture(type){
let self = this;
this.camera.capture({target: Camera.constants.CaptureTarget.disk})
.then((data) => {
<!---------------------------------------------------------->
<!------------It takes 3-4 seconds to come here------------!>
<!---------------------------------------------------------->
let n_pictures = [];
each(this.state.pictures, function (picture){
if(picture.item !== type.item){
n_pictures.push(picture)
}else{
n_pictures.push({
title: type.title,
noImage: false,
imageOverlay: type.imageOverlay,
image: data.path,
imageIcon: type.imageIcon,
overlay: false,
item: type.item,
mandatory: type.mandatory
})
}
});
self.setState({pictures: n_pictures, showCamera: false})
})
.catch(err => console.error(err));
}
Any idea how to solve it?
Can I at least put an loading screen until the photo is saved?
So I had this same issue, and after a while of searching on the internet I could not find an answer to speed it up.
However, to answer your query about using a loading screen you may want to look into Javascript promises. For my app, I redirected the user immediately to a new screen and showed a loading picture while the promise was not resolved/rejected. Once it was resolved, the picture showed.
I know this is an old answer, but I'm going to put this here for anyone else who may have a similar issue.

Can a React Native or NativeBase Picker have Items which include images?

I'm new to smartphone programming and have joined a project using React Native and NativeBase.
I'd like to include an image/icon in each Item in a Picker, which doesn't seem like an exotic concept, but it doesn't seem to be supported and I can't find anyone discussing doing it on SO or by Googling.
I've tried a couple ways of adding things inside the <Picker.Item> and </Picker.Item> but anything put there seems to simply be ignored.
Is it possible or is there a different approach to do what I want using these frameworks?
You can try this package
https://github.com/sohobloo/react-native-modal-dropdown
the complete example you can check here
https://github.com/sohobloo/react-native-modal-dropdown/blob/master/example/index.js
the use is something like this
_dropdown_2_renderRow(rowData, rowID, highlighted) {
let icon = highlighted ? require('./images/heart.png') : require('./images/flower.png');
let evenRow = rowID % 2;
return (
<TouchableHighlight underlayColor='cornflowerblue'>
<View style={[styles.dropdown_2_row, {backgroundColor: evenRow ? 'lemonchiffon' : 'white'}]}>
<Image style={styles.dropdown_2_image}
mode='stretch'
source={icon}
/>
<Text style={[styles.dropdown_2_row_text, highlighted && {color: 'mediumaquamarine'}]}>
{`${rowData.name} (${rowData.age})`}
</Text>
</View>
</TouchableHighlight>
);
}
the end product example is look like this :
all copyrights belongs to :
https://github.com/sohobloo