React Native: How to load Lottie file from local path - react-native

I use react-native-fs to download a Lottie file (json) from a remote server. After saving it to the filesystem I get a path like /Users/marlon/Library/Developer/CoreSimulator/Devices/8E0A092D0E86/data/Containers/Data/Application/AADD60D8DFAD/Documents/animation.json.
Is there now any way to use that filepath as a source for LottieView? I tried various approaches, but neither of them succeeded:
var path = '/Users/marlon/Library/Developer/CoreSimulator/Devices/8E0A092D0E86/data/Containers/Data/Application/AADD60D8DFAD/Documents/animation.json'
<LottieView source={{ uri: path }} />
<LottieView source={{ uri: 'file:/' + path }} />
<LottieView source={{ uri: 'file://' + path }} />
<LottieView source={{ uri: 'file://' + path, isStatic: true }} />
ANSWER
Its ok to just pass the animation file as a javascript object to the LottieView. So what I did now, was opening the file with react-native-fs and parsing it with JSON.parse. The final result looks like:
RNFS.readFile(animations.congratsAnimation).then(res => {
this.setState({ animation: JSON.parse(res) });
}
...
<LottieView source={this.state.animation} />

You should not hardcode the downloaded json file path, but rather keep it on a device's storage, e.g. Picture folder:
npm install --save react-native-fetch-blob
const { config, fs } = RNFetchBlob
RNFetchBlob.config({ path : RNFetchBlob.fs.dirs.DocumentDir + '/animation.png' + })
.fetch('GET', 'http://example.com/file/whichever', {
'Cache-Control' : 'no-store'
})
.then((res) => {
// where the file is, keep it as state.animationPath
this.setState(animationPath: res.path())
})
//render()
<LottieView source={{require(this.state.animationPath)}, isStatic: true }} />

I think you should use require() function while referencing the path for the resources.
For example you can do something like:
var path = require('/Users/marlon/Library/Developer/CoreSimulator/Devices/8E0A092D0E86/data/Containers/Data/Application/AADD60D8DFAD/Documents/animation.json');
or
<LottieView source = {require('/Users/marlon/Library/Developer/CoreSimulator/Devices/8E0A092D0E86/data/Containers/Data/Application/AADD60D8DFAD/Documents/animation.json')} />

Related

Download zip file in web view in react native

I'm trying to download file from a web view. I have used javascript inject to click on submit button.
I'm specifically trying this for offline aadhaar - https://resident.uidai.gov.in/offline-kyc
Reference Code -
<WebView
source={{ uri: "https://resident.uidai.gov.in/offline-kyc" }}
ref={webviewRef}
renderLoading={LoadingIndicatorView}
startInLoadingState={true}
injectedJavaScript={runFirst}
onMessage={onMessage}
renderError={loadError}
// onFileDownload={({ nativeEvent: { downloadUrl } }) => {
// console.log(downloadUrl);
// }}
/>
I have tried with api request by creating/replicating the browser behaviour for api call but it's not working. Any suggestions.
You can try react-native-fs
You can use downloadFile API to download and save the file to the device.

React native Image ' Warning: Failed prop type: Invalid prop `source` supplied to `Image`. '

So this is my code
I already answered the question.
export const BigCard = ({Title, Image, Description}) => {
console.log(Image)
return(
<StyledBigCard>
<StyledImage source={{
uri: Image,
}}/>
<StyledStroke>
<StyledStrokeText>
<StyledPBigCard>{Description}</StyledPBigCard>
</StyledStrokeText>
<FontAwesomeIcon style={style.icon} size={ 22 } icon={faChevronRight} />
</StyledStroke>
</StyledBigCard>
)
};
this is were i import the images etc. it is set in PBS1Detail, its an object so when i go to PBS1Detail.Image i get the image
const db = firebase.firestore();
const [PBS1Detail, setPBS1Detail] = useState([]);
const [partnerLevel, setPartnerLevel] = useState('');
useEffect(()=> {
{/* DATABASE */}
db.collection('Track').get().then((snapshot) => {
let results = []
snapshot.docs.forEach(doc => {
results.push(renderTracks(doc))
}
)
setPBS1Detail(results)
});
then i push it all the way to the screen were i import Image
all my imports are correct, and the console.log() gives me the good url to the image.
now when i now reload the app it gives the error "Warning: Failed prop type: Invalid prop source supplied to Image."
then when i update the image component to
<StyledImage source={{uri: 'https://s3.eu-central-1.wasabisys.com/image-parttime-bijbelschool-jaar-1/Track1Module1Thumbnail.jpg'}}
and than save the changes it works
then when i update it to
<StyledImage source={{uri: Image}} />
and than save the changes it also works
so when i run it the first time it gives me this error than when i change it to an url and than change it back to the Image prop it works. but when i reload the app it gives me this error again.
how can i fix this?
The PBS1Detail is an empty array until you actually get the image data from Firestore.
So when the first render, I guess you are trying to pass undefined or some invalid values for the source prop.
How about you give a condition for the render part?
export const BigCard = ({Title, Image, Description}) => {
console.log(Image)
return(
<StyledBigCard>
{!!Image && (
<StyledImage source={{
uri: Image,
}}/>
)}
<StyledStroke>
<StyledStrokeText>
<StyledPBigCard>{Description}</StyledPBigCard>
</StyledStrokeText>
<FontAwesomeIcon style={style.icon} size={ 22 } icon={faChevronRight} />
</StyledStroke>
</StyledBigCard>
)
};
The problem is not my code above, what i did was that on my homescreen i sended wrong props to Image is send
Image={Require('../../assets/Image.png')}
thats why te error occurded. i have set it to
Image={'https://s3.eu-central-1.wasabisys.com/image-parttime-bijbelschool-jaar-1/Track1Module1Thumbnail.jpg'}
and it works perfectly!

React-Native WebView: Issue downloading and saving dynamically generated file

We are opening a Url (in WebView) which has a button that dynamically generates and downloads a file (e.g. PDF or Excel or any other type) based on user selected filters. This means that we do not have direct link to those files which can be downloaded using network request. In chrome, we can see downloaded file. However in WebView, we neither see download file (the way chrome shows at the bottom of window) nor we get any way to intercept/view the location where it is downloaded silently. Below is webview:
<WebView
ref={ref => (webview = ref)}
originWhitelist={['*']}
source={{ uri: pageURL }}
javaScriptEnabled={true}
startInLoadingState={true}
scalesPageToFit={true}
domStorageEnabled={true}
onError={(err) => console.log(err)}
onHttpError={(err) => console.log(err)}
allowFileAccess={true}
allowFileAccessFromFileURLs={true}
allowUniversalAccessFromFileURLs={true}
allowingReadAccessToURL={true}
mixedContentMode="always"
onFileDownload={({ nativeEvent }) => {
const { downloadUrl } = nativeEvent;
console.log(downloadUrl);
}}
onNavigationStateChange={handleWebViewNavigationStateChange}
onLoad={() => {
webview.injectJavaScript(jsCode);
}}
onMessage={event => {
const { data } = event.nativeEvent;
}}
/>
So, we have below queries:
How to know if WebView actually downloaded a file?
Is there a way to know where WebView downloads a file?
Is there a way to specify default location where WebView should download a file?
Environment:
Expo: 40.0.0,
React-native: 0.63,
react-native-webview: 11.0.0
We clicked on "Allow" when it asked for permission to download and store file on device. Also, onNavigationStateChange is not firing when button is clicked (may be because the file is downloaded on same page without navigating). We have onError and onHttpError which does not print anything so there does not seem to be any issue there.
Below is the code (C#) that gets executed when button is clicked to download file:
string attachment = "attachment; filename=temp.csv";
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.AddHeader("content-disposition", attachment);
HttpContext.Current.Response.ContentType = "text/csv";
HttpContext.Current.Response.AddHeader("Pragma", "public");
// Prepare file content
HttpContext.Current.Response.Write(fileContent.ToString());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.Close();

How to display a video from an S3 bucket in React Native?

I am trying to download a video from an S3 bucket and pass it to Expo's Video component. I am using s3.getObject() and the callback function to get the object as an ArrayBuffer. But I don't know how to use this data from this point. I tried concatenating "data:video/mp4;base64," + videoData.body and passing that as an object. I also tried converting it to Base64String, which also didn't work.
let videoData = {}
const downloadIntro = async () => {
s3.getObject(bucketParams, function (err, data) {
if (err) {
console.log("Error:" + err)
} else {
console.log(data.ContentLength) // 1210362
console.log(data.ContentType) // video/mp4
console.log(data.Metadata) // Object {}
console.log(data.Body.buffer) // ArrayBuffer []
videoData.body = data.Body.buffer
}
})
}
export default function App() {
let [vidData, setVidData] = useState(null)
const playVideo = () => {
console.log("Trying to play")
setVidData({video: "data:video/mp4;base64," + videoData.body})
}
return (
<SafeAreaView style={styles.container}>
<Button title={"Load Video"} onPress={downloadIntro}/>
<Button title={"Start"} onPress={playVideo}/>
<Video
source={vidData}
rate={1.0}
volume={1.0}
isMuted={false}
resizeMode={"contain"}
shouldPlay={paused}
isLooping={false}
style={{
width: 300,
height: 300
}}
/>
</SafeAreaView>
);
}
It looks like you are trying to put the raw video data in the source. Try just setting the attribute to the url of the video :
<video controls width="250">
<source src="/media/cc0-videos/flower.mp4"
type="video/mp4">
</video>

Use <Image> with a local file

The documentation says that the only way to reference a static image is to use require.
But I'm not sure where does react expect to have those images. The examples don't have any domain, so it seems like you have to go to Xcode and add them to Images.xcassets, but that didn't work for me.
Using React Native 0.41 (in March 2017), targeting iOS, I just found it as easy as:
<Image source={require('./myimage.png')} />
The image file must exist in the same folder as the .js file requiring it for "./" to work.
I didn't have to change anything in the XCode project. It just worked.
Note that the path seems to have to start with "./" or "../" and be full lower case. I'm not sure what all the restrictions are, but start simple and work forward.
Hope this helps someone, as many other answers here seem overly complex and full of (naughty) off-site links.
UPDATE: BTW - The official documentation for this is here:
https://reactnative.dev/docs/images
It works exactly as you expect it to work. There's a bug https://github.com/facebook/react-native/issues/282 that prevents it from working correctly.
If you have node_modules (with react_native) in the same folder as the xcode project, you can edit node_modules/react-native/packager/packager.js and make this change: https://github.com/facebook/react-native/pull/286/files . It'll work magically :)
If your react_native is installed somewhere else and the patch doesn't work, comment on https://github.com/facebook/react-native/issues/282 to let them know about your setup.
ES6 solution:
import DefaultImage from '../assets/image.png';
const DEFAULT_IMAGE = Image.resolveAssetSource(DefaultImage).uri;
and then:
<Image source={{uri: DEFAULT_IMAGE}} />
If loading images dynamically one can create a .js file like following and do require in it.
export const data = [
{
id: "1",
text: "blablabla1",
imageLink: require('../assets/first-image.png')
},
{
id: "2",
text: "blablabla2",
imageLink: require('../assets/second-image.png')
}
]
In your component .js file
import {data} from './js-u-created-above';
...
function UsageExample({item}) {
<View>
<Image style={...} source={item.imageLink} />
</View>
}
function ComponentName() {
const elements = data.map(item => <UsageExample key={item.id} item={item}/> );
return (...);
}
I had this exact same issue until I realized I hadn't put the image in my Image.xcassets. I was able to drag and drop it into Xcode with Image.xcassets open and after rebuilding, it fixed the problem!
To display image from local folder, you need to write down code:
<Image source={require('../assets/self.png')}/>
Here I have put my image in asset folder.
From the UIExplorer sample app:
Static assets should be required by prefixing with image! and are located in the app bundle.
So like this:
render: function() {
return (
<View style={styles.horizontal}>
<Image source={require('image!uie_thumb_normal')} style={styles.icon} />
<Image source={require('image!uie_thumb_selected')} style={styles.icon} />
<Image source={require('image!uie_comment_normal')} style={styles.icon} />
<Image source={require('image!uie_comment_highlighted')} style={styles.icon} />
</View>
);
}
I was having trouble with react-native-navigation, I created my own header component, then inserted a image - as logo - on the left before title, then when I was triggering navigate to another screen and then back again, logo was loading again, with a timeout near 1s, my file were local. My solution :
Logo.json
{"file" : "base64 big string"}
App.js
import Logo from '.../Logo.json'
...
<Image source={{uri:Logo.file}} />
We can do like below:
const item= {
image: require("../../assets/dashboard/project1.jpeg"),
location: "Chennai",
status: 1,
projectId: 1
}
<Image source={item.image} style={[{ width: 150, height: 150}]} />
This from https://github.com/facebook/react-native/issues/282 worked for me:
adekbadek commented on Nov 11, 2015
It should be mentioned that you don't have to put the images in Images.xcassets - you just put them in the project root and then just require('./myimage.png') as #anback wrote
Look at this SO answer and the pull it references
For typescript user
import { ImageSourcePropType } from 'react-native'
type Data = {
image:ImageSourcePropType
}
const data:Data = {
image:require('../.../log.png')
}
and then
<Image source={data.image}/>
You have to add to the source property an object with a property called "uri" where you can specify the path of your image as you can see in the following example:
<Image style={styles.image} source={{uri: "http://www.mysyte.com/myimage.jpg"}} />
remember then to set the width and height via the style property:
var styles = StyleSheet.create({
image:{
width: 360,
height: 40,
}
});