/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
*/
'use strict';
var React = require('react');
var createReactClass = require('create-react-class');
var ReactNative = require('react-native');
var {
ActivityIndicator,
Image,
Platform,
StyleSheet,
Text,
View,
ImageBackground,
} = ReactNative;
var base64Icon =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEsAAABLCAQAAACSR7JhAAADtUlEQVR4Ac3YA2Bj6QLH0XPT1Fzbtm29tW3btm3bfLZtv7e2ObZnms7d8Uw098tuetPzrxv8wiISrtVudrG2JXQZ4VOv+qUfmqCGGl1mqLhoA52oZlb0mrjsnhKpgeUNEs91Z0pd1kvihA3ULGVHiQO2narKSHKkEMulm9VgUyE60s1aWoMQUbpZOWE+kaqs4eLEjdIlZTcFZB0ndc1+lhB1lZrIuk5P2aib1NBpZaL+JaOGIt0ls47SKzLC7CqrlGF6RZ09HGoNy1lYl2aRSWL5GuzqWU1KafRdoRp0iOQEiDzgZPnG6DbldcomadViflnl/cL93tOoVbsOLVM2jylvdWjXolWX1hmfZbGR/wjypDjFLSZIRov09BgYmtUqPQPlQrPapecLgTIy0jMgPKtTeob2zWtrGH3xvjUkPCtNg/tm1rjwrMa+mdUkPd3hWbH0jArPGiU9ufCsNNWFZ40wpwn+62/66R2RUtoso1OB34tnLOcy7YB1fUdc9e0q3yru8PGM773vXsuZ5YIZX+5xmHwHGVvlrGPN6ZSiP1smOsMMde40wKv2VmwPPVXNut4sVpUreZiLBHi0qln/VQeI/LTMYXpsJtFiclUN+5HVZazim+Ky+7sAvxWnvjXrJFneVtLWLyPJu9K3cXLWeOlbMTlrIelbMDlrLenrjEQOtIF+fuI9xRp9ZBFp6+b6WT8RrxEpdK64BuvHgDk+vUy+b5hYk6zfyfs051gRoNO1usU12WWRWL73/MMEy9pMi9qIrR4ZpV16Rrvduxazmy1FSvuFXRkqTnE7m2kdb5U8xGjLw/spRr1uTov4uOgQE+0N/DvFrG/Jt7i/FzwxbA9kDanhf2w+t4V97G8lrT7wc08aA2QNUkuTfW/KimT01wdlfK4yEw030VfT0RtZbzjeMprNq8m8tnSTASrTLti64oBNdpmMQm0eEwvfPwRbUBywG5TzjPCsdwk3IeAXjQblLCoXnDVeoAz6SfJNk5TTzytCNZk/POtTSV40NwOFWzw86wNJRpubpXsn60NJFlHeqlYRbslqZm2jnEZ3qcSKgm0kTli3zZVS7y/iivZTweYXJ26Y+RTbV1zh3hYkgyFGSTKPfRVbRqWWVReaxYeSLarYv1Qqsmh1s95S7G+eEWK0f3jYKTbV6bOwepjfhtafsvUsqrQvrGC8YhmnO9cSCk3yuY984F1vesdHYhWJ5FvASlacshUsajFt2mUM9pqzvKGcyNJW0arTKN1GGGzQlH0tXwLDgQTurS8eIQAAAABJRU5ErkJggg==';
var ImageCapInsetsExample = require('./ImageCapInsetsExample');
const IMAGE_PREFETCH_URL =
'http://origami.design/public/images/bird-logo.png?r=1&t=' + Date.now();
var prefetchTask = Image.prefetch(IMAGE_PREFETCH_URL);
/* $FlowFixMe(>=0.63.0 site=react_native_fb) This comment suppresses an error
* found when Flow v0.63 was deployed. To see the error delete this comment and
* run Flow. */
var NetworkImageCallbackExample = createReactClass({
displayName: 'NetworkImageCallbackExample',
getInitialState: function() {
return {
events: [],
startLoadPrefetched: false,
mountTime: new Date(),
};
},
UNSAFE_componentWillMount() {
this.setState({mountTime: new Date()});
},
render: function() {
var {mountTime} = this.state;
return (
this._loadEventFired(`✔ onLoadStart (+${new Date() - mountTime}ms)`)
}
onLoad={event => {
if (event.nativeEvent.source) {
const url = event.nativeEvent.source.url;
this._loadEventFired(
`✔ onLoad (+${new Date() - mountTime}ms) for URL ${url}`,
);
} else {
this._loadEventFired(`✔ onLoad (+${new Date() - mountTime}ms)`);
}
}}
onLoadEnd={() => {
this._loadEventFired(`✔ onLoadEnd (+${new Date() - mountTime}ms)`);
this.setState({startLoadPrefetched: true}, () => {
prefetchTask.then(
() => {
this._loadEventFired(
`✔ Prefetch OK (+${new Date() - mountTime}ms)`,
);
Image.queryCache([IMAGE_PREFETCH_URL]).then((map) => {
var result = map.get(IMAGE_PREFETCH_URL);
if (result) {
this._loadEventFired(
`✔ queryCache "${result}" (+${new Date() - mountTime}ms)`,
);
} else {
this._loadEventFired(
`✘ queryCache (+${new Date() - mountTime}ms)`,
);
}
});
},
error => {
this._loadEventFired(
`✘ Prefetch failed (+${new Date() - mountTime}ms)`,
);
},
);
});
}}
/>
{this.state.startLoadPrefetched ? (
this._loadEventFired(
`✔ (prefetched) onLoadStart (+${new Date() - mountTime}ms)`,
)
}
onLoad={event => {
// Currently this image source feature is only available on iOS.
if (event.nativeEvent.source) {
const url = event.nativeEvent.source.url;
this._loadEventFired(
`✔ (prefetched) onLoad (+${new Date() -
mountTime}ms) for URL ${url}`,
);
} else {
this._loadEventFired(
`✔ (prefetched) onLoad (+${new Date() - mountTime}ms)`,
);
}
}}
onLoadEnd={() =>
this._loadEventFired(
`✔ (prefetched) onLoadEnd (+${new Date() - mountTime}ms)`,
)
}
/>
) : null}
{this.state.events.join('\n')}
);
},
_loadEventFired(event) {
this.setState(state => {
return (state.events = [...state.events, event]);
});
},
});
var NetworkImageExample = createReactClass({
getInitialState: function() {
return {
error: false,
loading: false,
progress: 0,
};
},
render: function() {
var loader = this.state.loading ? (
{this.state.progress}%
) : null;
return this.state.error ? (
{this.state.error}
) : (
this.setState({loading: true})}
onError={e =>
this.setState({error: e.nativeEvent.error, loading: false})
}
onProgress={e =>
this.setState({
progress: Math.round(
(100 * e.nativeEvent.loaded) / e.nativeEvent.total,
),
})
}
onLoad={() => this.setState({loading: false, error: false})}>
{loader}
);
},
});
var ImageSizeExample = createReactClass({
getInitialState: function() {
return {
width: 0,
height: 0,
};
},
componentDidMount: function() {
Image.getSize(this.props.source.uri, (width, height) => {
this.setState({width, height});
});
},
render: function() {
return (
Actual dimensions:{'\n'}
Width: {this.state.width}, Height: {this.state.height}
);
},
});
var MultipleSourcesExample = createReactClass({
getInitialState: function() {
return {
width: 30,
height: 30,
};
},
render: function() {
return (
Decrease image size
Increase image size
Container image size: {this.state.width}x{this.state.height}{' '}
);
},
increaseImageSize: function() {
if (this.state.width >= 100) {
return;
}
this.setState({
width: this.state.width + 10,
height: this.state.height + 10,
});
},
decreaseImageSize: function() {
if (this.state.width <= 10) {
return;
}
this.setState({
width: this.state.width - 10,
height: this.state.height - 10,
});
},
});
exports.displayName = (undefined: ?string);
exports.framework = 'React';
exports.title = '';
exports.description =
'Base component for displaying different types of images.';
exports.examples = [
{
title: 'Plain Network Image',
description:
'If the `source` prop `uri` property is prefixed with ' +
'"http", then it will be downloaded from the network.',
render: function() {
return ;
},
},
{
title: 'Plain Static Image',
description:
'Static assets should be placed in the source code tree, and ' +
'required in the same way as JavaScript modules.',
render: function() {
return (
);
},
},
{
title: 'Image Loading Events',
render: function() {
return (
);
},
},
{
title: 'Error Handler',
render: function() {
return (
);
},
platform: 'ios',
},
{
title: 'Image Download Progress',
render: function() {
return (
);
},
platform: 'ios',
},
{
title: 'defaultSource',
description: 'Show a placeholder image when a network image is loading',
render: function() {
return (
);
},
platform: 'ios',
},
{
title: 'Cache Policy',
description:
'First image has never been loaded before and is instructed not to load unless in cache.' +
'Placeholder image from above will stay. Second image is the same but forced to load regardless of' +
' local cache state.',
render: function() {
return (
);
},
platform: 'ios',
},
{
title: 'Border Color',
render: function() {
return (
);
},
},
{
title: 'Border Width',
render: function() {
return (
);
},
},
{
title: 'Border Radius',
render: function() {
return (
);
},
},
{
title: 'Background Color',
render: function() {
return (
);
},
},
{
title: 'Opacity',
render: function() {
return (
);
},
},
{
title: 'Nesting content inside component',
render: function() {
return (
React
);
},
},
{
title: 'Nesting content inside component',
render: function() {
return (
React
);
},
},
{
title: 'Tint Color',
description:
'The `tintColor` style prop changes all the non-alpha ' +
'pixels to the tint color.',
render: function() {
return (
It also works with downloaded images:
);
},
},
{
title: 'Resize Mode',
description:
'The `resizeMode` style prop controls how the image is ' +
'rendered within the frame.',
render: function() {
return (
{[smallImage, fullImage].map((image, index) => {
return (
Contain
Cover
Stretch
Repeat
Center
);
})}
);
},
},
{
title: 'Animated GIF',
render: function() {
return (
);
},
platform: 'ios',
},
{
title: 'Base64 image',
render: function() {
return (
);
},
platform: 'ios',
},
{
title: 'Cap Insets',
description:
'When the image is resized, the corners of the size specified ' +
'by capInsets will stay a fixed size, but the center content and ' +
'borders of the image will be stretched. This is useful for creating ' +
'resizable rounded buttons, shadows, and other resizable assets.',
render: function() {
return ;
},
platform: 'ios',
},
{
title: 'Image Size',
render: function() {
return ;
},
},
{
title: 'MultipleSourcesExample',
description:
'The `source` prop allows passing in an array of uris, so that native to choose which image ' +
'to diplay based on the size of the of the target image',
render: function() {
return ;
},
},
{
title: 'Legacy local image',
description:
'Images shipped with the native bundle, but not managed ' +
'by the JS packager',
render: function() {
return ;
},
},
{
title: 'Bundled images',
description: 'Images shipped in a separate native bundle',
render: function() {
return (
);
},
platform: 'ios',
},
{
title: 'Blur Radius',
render: function() {
return (
);
},
},
];
var fullImage = {
uri: 'https://facebook.github.io/react-native/img/opengraph.png',
};
var smallImage = {
uri: 'https://facebook.github.io/react-native/img/favicon.png',
};
var styles = StyleSheet.create({
base: {
width: 38,
height: 38,
},
progress: {
flex: 1,
alignItems: 'center',
flexDirection: 'row',
width: 100,
},
leftMargin: {
marginLeft: 10,
},
background: {
backgroundColor: '#222222',
},
sectionText: {
marginVertical: 6,
},
nestedText: {
marginLeft: 12,
marginTop: 20,
backgroundColor: 'transparent',
color: 'white',
},
resizeMode: {
width: 90,
height: 60,
borderWidth: 0.5,
borderColor: 'black',
},
resizeModeText: {
fontSize: 11,
marginBottom: 3,
},
icon: {
width: 15,
height: 15,
},
horizontal: {
flexDirection: 'row',
},
gif: {
flex: 1,
height: 200,
},
base64: {
flex: 1,
height: 50,
resizeMode: 'contain',
},
touchableText: {
fontWeight: '500',
color: 'blue',
},
});