diff --git a/dist/Assets/Images/Placeholders/avatar_default@3x.png b/dist/Assets/Images/Placeholders/avatar_default@3x.png index e50bfbc..bb5653e 100644 Binary files a/dist/Assets/Images/Placeholders/avatar_default@3x.png and b/dist/Assets/Images/Placeholders/avatar_default@3x.png differ diff --git a/dist/Components/Basic/ImageBackground.js b/dist/Components/Basic/ImageBackground.js index 5220f52..709f71d 100644 --- a/dist/Components/Basic/ImageBackground.js +++ b/dist/Components/Basic/ImageBackground.js @@ -1,8 +1,8 @@ import React from 'react'; import { Image, StyleSheet, View, } from 'react-native'; -export class ImageBackground extends React.PureComponent { - constructor() { - super(...arguments); +export class ImageBackground extends React.Component { + constructor(props) { + super(props); this.onLoad = (data) => { if (this.props.onLoad) { this.props.onLoad(data); @@ -13,9 +13,27 @@ export class ImageBackground extends React.PureComponent { this.props.onError(error); } }; + this.state = { + ratio: 1, + }; + } + componentDidMount() { + const { url } = this.props; + if (url) { + Image.getSize(url, (width, height) => { + if (width > 0 && height > 0) { + this.setState({ + ratio: width / height, + }); + } + }, (error) => { + this.props.onError(error); + }); + } } render() { - return (React.createElement(View, { style: [{ + return (React.createElement(View, { style: [ + { flex: this.props.flex, position: 'relative', marginTop: this.props.marginTop, @@ -26,11 +44,26 @@ export class ImageBackground extends React.PureComponent { paddingRight: this.props.paddingRight, paddingBottom: this.props.paddingBottom, paddingLeft: this.props.paddingLeft - }, this.props.containerStyle] }, + }, this.props.containerStyle + ] }, React.createElement(Image, { source: { uri: this.props.url }, style: [ StyleSheet.absoluteFill, this.props.imageStyle - ], onLoad: this.onLoad, onError: this.onError }), + ], onLoad: this.onLoad, onError: this.onError, resizeMethod: 'auto', resizeMode: this.resizeMethod }), this.props.children)); } + get resizeMethod() { + switch (this.props.resizeMode) { + case 'repeat': + return 'repeat'; + case 'stretch': + default: + if (this.state.ratio > 1) { + return 'contain'; + } + else { + return 'cover'; + } + } + } } diff --git a/dist/Views/CardElements/BackgroundImage.js b/dist/Views/CardElements/BackgroundImage.js index 9e2af1a..3a5e46b 100644 --- a/dist/Views/CardElements/BackgroundImage.js +++ b/dist/Views/CardElements/BackgroundImage.js @@ -39,6 +39,6 @@ export class BackgroundImageView extends React.Component { if (!model || !model.isSchemaCheckPassed) { return DebugOutputFactory.createDebugOutputBanner(model.type + '>>' + model.url + ' is not valid', theme, 'error'); } - return (React.createElement(ImageBackground, { url: model.url, flex: 1, onLoad: this.onImageLoad, onError: this.onError }, this.props.children)); + return (React.createElement(ImageBackground, { url: model.url, flex: 1, resizeMode: model.mode, onLoad: this.onImageLoad, onError: this.onError }, this.props.children)); } } diff --git a/examples/AdaptiveCards/Assets/Images/Placeholders/avatar_default@3x.png b/examples/AdaptiveCards/Assets/Images/Placeholders/avatar_default@3x.png index e50bfbc..bb5653e 100644 Binary files a/examples/AdaptiveCards/Assets/Images/Placeholders/avatar_default@3x.png and b/examples/AdaptiveCards/Assets/Images/Placeholders/avatar_default@3x.png differ diff --git a/examples/AdaptiveCards/Components/Basic/ImageBackground.js b/examples/AdaptiveCards/Components/Basic/ImageBackground.js index 5220f52..709f71d 100644 --- a/examples/AdaptiveCards/Components/Basic/ImageBackground.js +++ b/examples/AdaptiveCards/Components/Basic/ImageBackground.js @@ -1,8 +1,8 @@ import React from 'react'; import { Image, StyleSheet, View, } from 'react-native'; -export class ImageBackground extends React.PureComponent { - constructor() { - super(...arguments); +export class ImageBackground extends React.Component { + constructor(props) { + super(props); this.onLoad = (data) => { if (this.props.onLoad) { this.props.onLoad(data); @@ -13,9 +13,27 @@ export class ImageBackground extends React.PureComponent { this.props.onError(error); } }; + this.state = { + ratio: 1, + }; + } + componentDidMount() { + const { url } = this.props; + if (url) { + Image.getSize(url, (width, height) => { + if (width > 0 && height > 0) { + this.setState({ + ratio: width / height, + }); + } + }, (error) => { + this.props.onError(error); + }); + } } render() { - return (React.createElement(View, { style: [{ + return (React.createElement(View, { style: [ + { flex: this.props.flex, position: 'relative', marginTop: this.props.marginTop, @@ -26,11 +44,26 @@ export class ImageBackground extends React.PureComponent { paddingRight: this.props.paddingRight, paddingBottom: this.props.paddingBottom, paddingLeft: this.props.paddingLeft - }, this.props.containerStyle] }, + }, this.props.containerStyle + ] }, React.createElement(Image, { source: { uri: this.props.url }, style: [ StyleSheet.absoluteFill, this.props.imageStyle - ], onLoad: this.onLoad, onError: this.onError }), + ], onLoad: this.onLoad, onError: this.onError, resizeMethod: 'auto', resizeMode: this.resizeMethod }), this.props.children)); } + get resizeMethod() { + switch (this.props.resizeMode) { + case 'repeat': + return 'repeat'; + case 'stretch': + default: + if (this.state.ratio > 1) { + return 'contain'; + } + else { + return 'cover'; + } + } + } } diff --git a/examples/AdaptiveCards/Views/CardElements/BackgroundImage.js b/examples/AdaptiveCards/Views/CardElements/BackgroundImage.js index 9e2af1a..3a5e46b 100644 --- a/examples/AdaptiveCards/Views/CardElements/BackgroundImage.js +++ b/examples/AdaptiveCards/Views/CardElements/BackgroundImage.js @@ -39,6 +39,6 @@ export class BackgroundImageView extends React.Component { if (!model || !model.isSchemaCheckPassed) { return DebugOutputFactory.createDebugOutputBanner(model.type + '>>' + model.url + ' is not valid', theme, 'error'); } - return (React.createElement(ImageBackground, { url: model.url, flex: 1, onLoad: this.onImageLoad, onError: this.onError }, this.props.children)); + return (React.createElement(ImageBackground, { url: model.url, flex: 1, resizeMode: model.mode, onLoad: this.onImageLoad, onError: this.onError }, this.props.children)); } } diff --git a/src/Components/Basic/ImageBackground.tsx b/src/Components/Basic/ImageBackground.tsx index 4e10b35..4f76782 100644 --- a/src/Components/Basic/ImageBackground.tsx +++ b/src/Components/Basic/ImageBackground.tsx @@ -11,6 +11,7 @@ import { interface IProps { url: string; flex?: number; + resizeMode?: 'stretch' | 'repeat' | 'repeatHorizontally' | 'repeatVertically'; marginTop?: number; marginBottom?: number; marginLeft?: number; @@ -25,22 +26,56 @@ interface IProps { onError?: (error: any) => void; } -export class ImageBackground extends React.PureComponent { +interface IState { + ratio: number; +} + +export class ImageBackground extends React.Component { + constructor(props: IProps) { + super(props); + + this.state = { + ratio: 1, + }; + } + + public componentDidMount() { + const { url } = this.props; + + if (url) { + Image.getSize( + url, + (width, height) => { + if (width > 0 && height > 0) { + this.setState({ + ratio: width / height, + }); + } + }, + (error) => { + this.props.onError(error); + } + ); + } + } + public render() { return ( - { ]} onLoad={this.onLoad} onError={this.onError} + resizeMethod='auto' + resizeMode={this.resizeMethod} /> {this.props.children} @@ -67,4 +104,18 @@ export class ImageBackground extends React.PureComponent { this.props.onError(error); } } + + private get resizeMethod() { + switch (this.props.resizeMode) { + case 'repeat': + return 'repeat'; + case 'stretch': + default: + if (this.state.ratio > 1) { + return 'contain'; + } else { + return 'cover'; + } + } + } } diff --git a/src/Views/CardElements/BackgroundImage.tsx b/src/Views/CardElements/BackgroundImage.tsx index c16ba3b..2982c66 100644 --- a/src/Views/CardElements/BackgroundImage.tsx +++ b/src/Views/CardElements/BackgroundImage.tsx @@ -34,6 +34,7 @@ export class BackgroundImageView extends React.Component { diff --git a/tool/src/assets/AdaptiveCards/Assets/Images/Placeholders/avatar_default.png b/tool/src/assets/AdaptiveCards/Assets/Images/Placeholders/avatar_default.png index e50bfbc..bb5653e 100644 Binary files a/tool/src/assets/AdaptiveCards/Assets/Images/Placeholders/avatar_default.png and b/tool/src/assets/AdaptiveCards/Assets/Images/Placeholders/avatar_default.png differ diff --git a/tool/src/assets/AdaptiveCards/Components/Basic/ImageBackground.js b/tool/src/assets/AdaptiveCards/Components/Basic/ImageBackground.js index 5220f52..709f71d 100644 --- a/tool/src/assets/AdaptiveCards/Components/Basic/ImageBackground.js +++ b/tool/src/assets/AdaptiveCards/Components/Basic/ImageBackground.js @@ -1,8 +1,8 @@ import React from 'react'; import { Image, StyleSheet, View, } from 'react-native'; -export class ImageBackground extends React.PureComponent { - constructor() { - super(...arguments); +export class ImageBackground extends React.Component { + constructor(props) { + super(props); this.onLoad = (data) => { if (this.props.onLoad) { this.props.onLoad(data); @@ -13,9 +13,27 @@ export class ImageBackground extends React.PureComponent { this.props.onError(error); } }; + this.state = { + ratio: 1, + }; + } + componentDidMount() { + const { url } = this.props; + if (url) { + Image.getSize(url, (width, height) => { + if (width > 0 && height > 0) { + this.setState({ + ratio: width / height, + }); + } + }, (error) => { + this.props.onError(error); + }); + } } render() { - return (React.createElement(View, { style: [{ + return (React.createElement(View, { style: [ + { flex: this.props.flex, position: 'relative', marginTop: this.props.marginTop, @@ -26,11 +44,26 @@ export class ImageBackground extends React.PureComponent { paddingRight: this.props.paddingRight, paddingBottom: this.props.paddingBottom, paddingLeft: this.props.paddingLeft - }, this.props.containerStyle] }, + }, this.props.containerStyle + ] }, React.createElement(Image, { source: { uri: this.props.url }, style: [ StyleSheet.absoluteFill, this.props.imageStyle - ], onLoad: this.onLoad, onError: this.onError }), + ], onLoad: this.onLoad, onError: this.onError, resizeMethod: 'auto', resizeMode: this.resizeMethod }), this.props.children)); } + get resizeMethod() { + switch (this.props.resizeMode) { + case 'repeat': + return 'repeat'; + case 'stretch': + default: + if (this.state.ratio > 1) { + return 'contain'; + } + else { + return 'cover'; + } + } + } } diff --git a/tool/src/assets/AdaptiveCards/Views/CardElements/BackgroundImage.js b/tool/src/assets/AdaptiveCards/Views/CardElements/BackgroundImage.js index 9e2af1a..3a5e46b 100644 --- a/tool/src/assets/AdaptiveCards/Views/CardElements/BackgroundImage.js +++ b/tool/src/assets/AdaptiveCards/Views/CardElements/BackgroundImage.js @@ -39,6 +39,6 @@ export class BackgroundImageView extends React.Component { if (!model || !model.isSchemaCheckPassed) { return DebugOutputFactory.createDebugOutputBanner(model.type + '>>' + model.url + ' is not valid', theme, 'error'); } - return (React.createElement(ImageBackground, { url: model.url, flex: 1, onLoad: this.onImageLoad, onError: this.onError }, this.props.children)); + return (React.createElement(ImageBackground, { url: model.url, flex: 1, resizeMode: model.mode, onLoad: this.onImageLoad, onError: this.onError }, this.props.children)); } }