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

Expose a prop allowing users to specify a custom fallback image #88

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from

Conversation

jingdid
Copy link

@jingdid jingdid commented May 3, 2023

This change allows a user to specify a custom fallback image by setting a placeholderImg prop to a url like so:
<Carousel images={images} placeholderImg="https://placekitten.com/400/230" />

If the placeholder image url provided is invalid, the repository's default placeholder image is used instead.

Addresses issue #86

@yifaneye
Copy link
Owner

yifaneye commented May 9, 2023

Hi @jingdid ! Thank you very much! I will review it today!

Copy link
Owner

@yifaneye yifaneye left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution! Your code looks good. But I left some comments.

yarn.lock Outdated
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you like to tell me what is the reason for the changes here? Could you please keep the yarn lockfile unchanged?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies, I did not notice I had changed the yarn lockfile. I think this is just a consequence of my trying to get the demo to run locally. I don't think any of my changes should actually require updates to the lockfile - I will remove this when I next update this pull request.

const [isLoading, setIsLoading] = useState(true);
const [isValidFallback, setIsValidFallback] = useState(false);
useEffect(() => {
fetch(props.placeholderImg).then(res => {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this implementation support local file paths?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested it with a local file and it should support them.

@@ -48,6 +48,7 @@ export const propTypes = {
hasDotButtonsAtMax: largeWidgetPositions,
hasCaptionsAtMax: largeWidgetPositions,
hasThumbnailsAtMax: PropTypes.bool,
placeholderImg: PropTypes.string,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest renaming it to fallbackImg.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And also in other props.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

fetch(props.placeholderImg).then(res => {
setIsValidFallback(res.status === 200);
setIsLoading(false);
}).catch((_reason) => {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, finally statement can be used to combine setIsLoading(false);.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block has now been moved out of this file, and is used in such a way now that finally should no longer be needed.

}).catch((_reason) => {
setIsLoading(false);
})
}, []);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is an error message:

ESLint: React Hook useEffect has a missing dependency: 'props.placeholderImg'. Either include it or remove the dependency array.(react-hooks/exhaustive-deps)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

const [isValidFallback, setIsValidFallback] = useState(false);
useEffect(() => {
fetch(props.placeholderImg).then(res => {
setIsValidFallback(res.status === 200);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it be "HTTP 304 Not Modified" in some cases?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed it to check for res.ok instead now, which should address this issue.

}).catch((_reason) => {
setIsLoading(false);
})
}, []);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is an error message:
ESLint: React Hook useEffect has a missing dependency: 'props.placeholderImg'. Either include it or remove the dependency array.(react-hooks/exhaustive-deps)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -33,15 +33,27 @@ const LazyLoadedImage = (props) => {
// the low quality image (props.image.thumbnail) will be hidden
};

// This block checks whether the user specified fallback image actually works or not
const [isLoading, setIsLoading] = useState(true);
const [isValidFallback, setIsValidFallback] = useState(false);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for handling the error of the fallback image? The fallback image is likely to be a static image, which is quite stable. The user can handle it using their code if they want to, isn't it?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can simply assign the fallback image in the handleError function.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was intended to catch cases where a user provides an invalid/broken url for the fallback image - in that event, I wanted to make sure that the carousel would end up falling back onto the built-in placeholder again.

Copy link
Owner

@yifaneye yifaneye left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution! Your code looks good. But I left some comments.

@yifaneye yifaneye changed the base branch from master to dev May 10, 2023 12:00
- Refactor so that fallback image validity is only check once rather
than making a request for every image in the carousel
- Allow thumbnails to also use fallback image
- Gracefully use default placeholder if fallback image prop is not
specified
@jingdid jingdid requested a review from yifaneye July 4, 2023 08:27
@jingdid
Copy link
Author

jingdid commented Nov 15, 2024

@yifaneye Welcome back! Apologies for the bother, but any chance you could re-review this pull request? I've since addressed your comments while also improving the changed behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants