From 4b80ea27e9bf662d56bd3f4e9a2bc491dd99856a Mon Sep 17 00:00:00 2001
From: Paul Li <82799722+wmdev0808@users.noreply.github.com>
Date: Thu, 24 Feb 2022 11:37:54 +0800
Subject: [PATCH] fix: Some .jpg images don't load in the Image Widget (#11247)
---
.../DisplayWidgets/Image_spec.js | 16 ++++++++++++
app/client/src/ce/constants/messages.ts | 2 ++
.../widgets/ImageWidget/component/index.tsx | 26 +++++++++++++++----
3 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Image_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Image_spec.js
index 7257026a17..f3d2afe846 100644
--- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Image_spec.js
+++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Image_spec.js
@@ -65,6 +65,22 @@ describe("Image Widget Functionality", function() {
cy.PublishtheApp();
cy.get(publish.imageWidget).should("be.visible");
});
+
+ it("In case of an image loading error, show off the error message", () => {
+ cy.get(publish.backToEditor).click();
+ cy.openPropertyPane("imagewidget");
+ // Invalid image url
+ const invalidImageUrl = "https://www.example.com/does-not-exist.jpg";
+ cy.testCodeMirror(invalidImageUrl);
+
+ // Show off error message
+ cy.get(
+ `${viewWidgetsPage.imageWidget} div[data-testid=styledImage]`,
+ ).should("not.exist");
+ cy.get(
+ `${viewWidgetsPage.imageWidget} [data-testid="error-container"]`,
+ ).contains("Unable to display the image");
+ });
});
afterEach(() => {
// put your clean up code if any
diff --git a/app/client/src/ce/constants/messages.ts b/app/client/src/ce/constants/messages.ts
index 7d428af0c5..83570b4b15 100644
--- a/app/client/src/ce/constants/messages.ts
+++ b/app/client/src/ce/constants/messages.ts
@@ -1031,3 +1031,5 @@ export const CONTEXT_MOVE = () => "Move to page";
export const CONTEXT_COPY = () => "Copy to page";
export const CONTEXT_DELETE = () => "Delete";
export const CONTEXT_NO_PAGE = () => "No pages";
+
+export const IMAGE_LOAD_ERROR = () => "Unable to display the image";
diff --git a/app/client/src/widgets/ImageWidget/component/index.tsx b/app/client/src/widgets/ImageWidget/component/index.tsx
index 88e883bbbd..5b9c53235a 100644
--- a/app/client/src/widgets/ImageWidget/component/index.tsx
+++ b/app/client/src/widgets/ImageWidget/component/index.tsx
@@ -3,6 +3,7 @@ import { ComponentProps } from "widgets/BaseComponent";
import styled from "styled-components";
import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch";
import { Colors } from "constants/Colors";
+import { createMessage, IMAGE_LOAD_ERROR } from "ce/constants/messages";
export interface StyledImageProps {
defaultImageUrl: string;
@@ -26,8 +27,8 @@ export const StyledImage = styled.div<
cursor: ${(props) =>
props.showHoverPointer && props.onClick ? "pointer" : "inherit"};
background: ${(props) => props.backgroundColor};
- background-image: ${(props) =>
- `url(${props.imageError ? props.defaultImageUrl : props.imageUrl})`};
+ ${({ defaultImageUrl, imageError, imageUrl }) =>
+ !imageError && `background-image: url("${imageUrl || defaultImageUrl}")`};
background-position: center;
background-repeat: no-repeat;
height: 100%;
@@ -84,6 +85,12 @@ const ControlBtn = styled.div`
}
`;
+const ErrorContainer = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: center;
+`;
+
enum ZoomingState {
MAX_ZOOMED_OUT = "MAX_ZOOMED_OUT",
MAX_ZOOMED_IN = "MAX_ZOOMED_IN",
@@ -108,9 +115,10 @@ class ImageComponent extends React.Component<
zoomingState: ZoomingState.MAX_ZOOMED_OUT,
};
}
+
render() {
- const { maxZoomLevel } = this.props;
- const { imageRotation } = this.state;
+ const { imageUrl, maxZoomLevel } = this.props;
+ const { imageError, imageRotation } = this.state;
const zoomActive =
maxZoomLevel !== undefined && maxZoomLevel > 1 && !this.isPanning;
const isZoomingIn = this.state.zoomingState === ZoomingState.MAX_ZOOMED_OUT;
@@ -119,6 +127,14 @@ class ImageComponent extends React.Component<
cursor = isZoomingIn ? "zoom-in" : "zoom-out";
}
if (this.props.onClick) cursor = "pointer";
+
+ if (imageUrl && imageError)
+ return (
+
+ {createMessage(IMAGE_LOAD_ERROR)}
+
+ );
+
return (