MM-40530 Support SVG for markdown inline images (#5869)
* MM-40530 Support SVG for markdown inline images * Update app/components/markdown/markdown_image/markdown_image.js Co-authored-by: Daniel Espino García <larkox@gmail.com> Co-authored-by: Daniel Espino García <larkox@gmail.com>
This commit is contained in:
parent
1a58dd8a0d
commit
b7455853e5
4 changed files with 45 additions and 21 deletions
|
|
@ -13,6 +13,7 @@ import {
|
|||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import {SvgUri} from 'react-native-svg';
|
||||
import parseUrl from 'url-parse';
|
||||
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
|
|
@ -50,18 +51,19 @@ export default class MarkdownImage extends ImageViewPort {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const metadata = props.imagesMetadata?.[props.source] || Object.values(props.imagesMetadata || {})[0];
|
||||
const metadata = props.imagesMetadata?.[props.source] || Object.values(props.imagesMetadata || {})?.[0];
|
||||
this.fileId = generateId();
|
||||
this.state = {
|
||||
originalHeight: metadata?.height || 0,
|
||||
originalWidth: metadata?.width || 0,
|
||||
failed: isGifTooLarge(metadata),
|
||||
format: metadata?.format,
|
||||
uri: null,
|
||||
};
|
||||
}
|
||||
|
||||
getFileInfo = () => {
|
||||
const {originalHeight, originalWidth} = this.state;
|
||||
const {format, originalHeight, originalWidth} = this.state;
|
||||
const link = decodeURIComponent(this.getSource());
|
||||
let filename = parseUrl(link.substr(link.lastIndexOf('/'))).pathname.replace('/', '');
|
||||
let extension = filename.split('.').pop();
|
||||
|
|
@ -76,6 +78,7 @@ export default class MarkdownImage extends ImageViewPort {
|
|||
id: this.fileId,
|
||||
name: filename,
|
||||
extension,
|
||||
format,
|
||||
has_preview_image: true,
|
||||
post_id: this.props.postId,
|
||||
uri: link,
|
||||
|
|
@ -175,12 +178,12 @@ export default class MarkdownImage extends ImageViewPort {
|
|||
render() {
|
||||
let image = null;
|
||||
const fileInfo = this.getFileInfo();
|
||||
const {height, width} = calculateDimensions(fileInfo.height, fileInfo.width, getViewPortWidth(this.props.isReplyPost, this.hasPermanentSidebar()));
|
||||
const {height, width} = calculateDimensions(fileInfo?.height, fileInfo?.width, getViewPortWidth(this.props.isReplyPost, this.hasPermanentSidebar()));
|
||||
|
||||
if (this.state.failed) {
|
||||
image = (
|
||||
<CompassIcon
|
||||
name='jumbo-attachment-image-broken'
|
||||
name='file-image-broken-outline-large'
|
||||
size={24}
|
||||
/>
|
||||
);
|
||||
|
|
@ -204,11 +207,7 @@ export default class MarkdownImage extends ImageViewPort {
|
|||
);
|
||||
} else {
|
||||
// React Native complains if we try to pass resizeMode as a style
|
||||
let source = null;
|
||||
if (fileInfo.uri) {
|
||||
source = {uri: fileInfo.uri};
|
||||
}
|
||||
|
||||
const source = fileInfo.uri ? {uri: fileInfo.uri} : null;
|
||||
image = (
|
||||
<TouchableWithFeedback
|
||||
onLongPress={this.handleLinkLongPress}
|
||||
|
|
@ -224,6 +223,13 @@ export default class MarkdownImage extends ImageViewPort {
|
|||
</TouchableWithFeedback>
|
||||
);
|
||||
}
|
||||
} else if (fileInfo?.format === 'svg') {
|
||||
image = (
|
||||
<SvgUri
|
||||
uri={fileInfo.uri}
|
||||
style={{flex: 1}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (image && this.props.linkDestination) {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import React, {useCallback, useRef, useState} from 'react';
|
||||
import {StyleSheet, View} from 'react-native';
|
||||
import {SvgUri} from 'react-native-svg';
|
||||
import parseUrl from 'url-parse';
|
||||
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
|
|
@ -32,7 +33,7 @@ const styles = StyleSheet.create({
|
|||
});
|
||||
|
||||
const MarkTableImage = ({disable, imagesMetadata, postId, serverURL, source}: MarkdownTableImageProps) => {
|
||||
const metadata = imagesMetadata[source];
|
||||
const metadata = imagesMetadata[source] || Object.values(imagesMetadata || {})?.[0];
|
||||
const fileId = useRef(generateId()).current;
|
||||
const [failed, setFailed] = useState(isGifTooLarge(metadata));
|
||||
|
||||
|
|
@ -95,17 +96,24 @@ const MarkTableImage = ({disable, imagesMetadata, postId, serverURL, source}: Ma
|
|||
if (failed) {
|
||||
image = (
|
||||
<CompassIcon
|
||||
name='jumbo-attachment-image-broken'
|
||||
name='file-image-broken-outline-large'
|
||||
size={24}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
const {height, width} = calculateDimensions(metadata.height, metadata.width, 100, 100);
|
||||
image = (
|
||||
<TouchableWithFeedback
|
||||
onPress={handlePreviewImage}
|
||||
style={{width, height}}
|
||||
>
|
||||
const {height, width} = calculateDimensions(metadata?.height, metadata?.width, 100, 100);
|
||||
let imageComponent;
|
||||
if (metadata?.format === 'svg') {
|
||||
imageComponent = (
|
||||
<View style={{height: 100}}>
|
||||
<SvgUri
|
||||
uri={source}
|
||||
style={styles.container}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
} else {
|
||||
imageComponent = (
|
||||
<ProgressiveImage
|
||||
id={fileId}
|
||||
defaultSource={{uri: source}}
|
||||
|
|
@ -113,6 +121,16 @@ const MarkTableImage = ({disable, imagesMetadata, postId, serverURL, source}: Ma
|
|||
resizeMode='contain'
|
||||
style={{width, height}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
image = (
|
||||
<TouchableWithFeedback
|
||||
onPress={handlePreviewImage}
|
||||
style={{width, height}}
|
||||
>
|
||||
|
||||
{imageComponent}
|
||||
</TouchableWithFeedback>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ describe('Images calculateDimensions', () => {
|
|||
falsyHeights.forEach((falsyHeight) => {
|
||||
const {height, width} = calculateDimensions(falsyHeight as number, 20, PORTRAIT_VIEWPORT);
|
||||
expect(height).toEqual(0);
|
||||
expect(width).toEqual(0);
|
||||
expect(width).toEqual(PORTRAIT_VIEWPORT);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ describe('Images calculateDimensions', () => {
|
|||
falsyWidths.forEach((falsyWidth) => {
|
||||
const {height, width} = calculateDimensions(20, falsyWidth as number, PORTRAIT_VIEWPORT);
|
||||
expect(height).toEqual(0);
|
||||
expect(width).toEqual(0);
|
||||
expect(width).toEqual(PORTRAIT_VIEWPORT);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ import {PostImage} from '@mm-redux/types/posts';
|
|||
export const calculateDimensions = (height: number, width: number, viewPortWidth = 0, viewPortHeight = 0) => {
|
||||
if (!height || !width) {
|
||||
return {
|
||||
height: 0,
|
||||
width: 0,
|
||||
height: viewPortHeight,
|
||||
width: viewPortWidth,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue