Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate ThumbnailImage.js to function component #20892

Merged
merged 20 commits into from
Aug 9, 2023
Merged
Changes from 8 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
996c245
pushing a draft PR to change component to function for thumbnail images
kadiealexander Jun 16, 2023
5523aa2
syntax changes and debugging completed with puneet
kadiealexander Jun 26, 2023
a942097
cleaned up code with prettier
kadiealexander Jun 26, 2023
f220bd5
added display name
kadiealexander Jun 26, 2023
07a46ee
changes to clean up the lint failures
kadiealexander Jun 27, 2023
2e1f803
ran prettier to tidy code changes
kadiealexander Jul 5, 2023
220fc1e
Update src/components/ThumbnailImage.js
kadiealexander Jul 5, 2023
6d28dcf
Updating the arguments for the onMeasure function
kadiealexander Jul 7, 2023
fd8f613
update updateImageSize to use callback function
kadiealexander Jul 10, 2023
241714e
update onMeasure to pass updateImageSize function directly
kadiealexander Jul 10, 2023
967d521
use useWindowDimensions hook instead of HOC prop
kadiealexander Jul 10, 2023
b5b09a8
update variables to factor in undefined states
kadiealexander Jul 10, 2023
926ab9f
fix lint
kadiealexander Jul 13, 2023
7238565
fix prettier
kadiealexander Jul 13, 2023
51c08ad
fix potential undefined value error
kadiealexander Jul 24, 2023
75e884b
make it prettier
kadiealexander Jul 24, 2023
d80e0aa
Merge branch 'main' into kadie-thumbnail-component-change
kadiealexander Jul 31, 2023
65b14c4
adding new function argument to JSDocs description
kadiealexander Jul 31, 2023
09872e5
adding new JSDocs parameter for new function argument
kadiealexander Jul 31, 2023
2ea290c
remove check for invalid image height/width since we'll always pass a…
kadiealexander Jul 31, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 47 additions & 53 deletions src/components/ThumbnailImage.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import lodashClamp from 'lodash/clamp';
import React, {PureComponent} from 'react';
import React, {useState} from 'react';
import {View} from 'react-native';
import PropTypes from 'prop-types';
import ImageWithSizeCalculation from './ImageWithSizeCalculation';
Expand Down Expand Up @@ -33,73 +33,67 @@ const defaultProps = {
imageHeight: 200,
};

class ThumbnailImage extends PureComponent {
constructor(props) {
super(props);
/**
* Compute the thumbnails width and height given original image dimensions.
*
* @param {Number} width - Width of the original image.
* @param {Number} height - Height of the original image.
kadiealexander marked this conversation as resolved.
Show resolved Hide resolved
* @returns {Object} - Object containing thumbnails width and height.
*/

this.updateImageSize = this.updateImageSize.bind(this);
const {thumbnailWidth, thumbnailHeight} = this.calculateThumbnailImageSize(props.imageWidth, props.imageHeight);
this.state = {
thumbnailWidth,
thumbnailHeight,
};
function calculateThumbnailImageSize(width, height, windowHeight) {
if (!width || !height) {
return {};
}

/**
* Compute the thumbnails width and height given original image dimensions.
*
* @param {Number} width - Width of the original image.
* @param {Number} height - Height of the original image.
* @returns {Object} - Object containing thumbnails width and height.
*/
calculateThumbnailImageSize(width, height) {
if (!width || !height) {
return {};
}
// Width of the thumbnail works better as a constant than it does
// a percentage of the screen width since it is relative to each screen
// Note: Clamp minimum width 40px to support touch device
let thumbnailScreenWidth = lodashClamp(width, 40, 250);
const imageHeight = height / (width / thumbnailScreenWidth);
let thumbnailScreenHeight = lodashClamp(imageHeight, 40, windowHeight * 0.4);
const aspectRatio = height / width;

// Width of the thumbnail works better as a constant than it does
// a percentage of the screen width since it is relative to each screen
// Note: Clamp minimum width 40px to support touch device
let thumbnailScreenWidth = lodashClamp(width, 40, 250);
const imageHeight = height / (width / thumbnailScreenWidth);
let thumbnailScreenHeight = lodashClamp(imageHeight, 40, this.props.windowHeight * 0.4);
const aspectRatio = height / width;

// If thumbnail height is greater than its width, then the image is portrait otherwise landscape.
// For portrait images, we need to adjust the width of the image to keep the aspect ratio and vice-versa.
if (thumbnailScreenHeight > thumbnailScreenWidth) {
thumbnailScreenWidth = Math.round(thumbnailScreenHeight * (1 / aspectRatio));
} else {
thumbnailScreenHeight = Math.round(thumbnailScreenWidth * aspectRatio);
}
return {thumbnailWidth: Math.max(40, thumbnailScreenWidth), thumbnailHeight: Math.max(40, thumbnailScreenHeight)};
// If thumbnail height is greater than its width, then the image is portrait otherwise landscape.
// For portrait images, we need to adjust the width of the image to keep the aspect ratio and vice-versa.
if (thumbnailScreenHeight > thumbnailScreenWidth) {
thumbnailScreenWidth = Math.round(thumbnailScreenHeight * (1 / aspectRatio));
} else {
thumbnailScreenHeight = Math.round(thumbnailScreenWidth * aspectRatio);
}
return {thumbnailWidth: Math.max(40, thumbnailScreenWidth), thumbnailHeight: Math.max(40, thumbnailScreenHeight)};
}

function ThumbnailImage(props) {
const {initialWidth, initialHeight} = calculateThumbnailImageSize(props.imageWidth, props.imageHeight, props.windowHeight);
const [imageWidth, setImageWidth] = useState(initialWidth);
const [imageHeight, setImageHeight] = useState(initialHeight);

/**
* Update the state with the computed thumbnail sizes.
*
* @param {{ width: number, height: number }} Params - width and height of the original image.
*/
updateImageSize({width, height}) {
const {thumbnailWidth, thumbnailHeight} = this.calculateThumbnailImageSize(width, height);
this.setState({thumbnailWidth, thumbnailHeight});
}

render() {
return (
<View style={[this.props.style, styles.overflowHidden]}>
<View style={[StyleUtils.getWidthAndHeightStyle(this.state.thumbnailWidth, this.state.thumbnailHeight), styles.alignItemsCenter, styles.justifyContentCenter]}>
<ImageWithSizeCalculation
url={this.props.previewSourceURL}
onMeasure={this.updateImageSize}
isAuthTokenRequired={this.props.isAuthTokenRequired}
/>
</View>
</View>
);
function updateImageSize({width, height}) {
const {thumbnailWidth, thumbnailHeight} = calculateThumbnailImageSize(width, height, props.windowHeight);
setImageWidth(thumbnailWidth);
setImageHeight(thumbnailHeight);
}
kadiealexander marked this conversation as resolved.
Show resolved Hide resolved
return (
<View style={[props.style, styles.overflowHidden]}>
<View style={[StyleUtils.getWidthAndHeightStyle(imageWidth, imageHeight), styles.alignItemsCenter, styles.justifyContentCenter]}>
<ImageWithSizeCalculation
url={props.previewSourceURL}
onMeasure={(measurements) => updateImageSize(measurements)}
kadiealexander marked this conversation as resolved.
Show resolved Hide resolved
isAuthTokenRequired={props.isAuthTokenRequired}
/>
</View>
</View>
);
}

ThumbnailImage.propTypes = propTypes;
ThumbnailImage.defaultProps = defaultProps;
ThumbnailImage.displayName = 'ThumbnailImage';
export default withWindowDimensions(ThumbnailImage);
kadiealexander marked this conversation as resolved.
Show resolved Hide resolved
kadiealexander marked this conversation as resolved.
Show resolved Hide resolved