diff --git a/explorer/src/img/logos-solana/dark-solana-logo.svg b/explorer/src/img/logos-solana/dark-solana-logo.svg
new file mode 100644
index 000000000..4ae077d11
--- /dev/null
+++ b/explorer/src/img/logos-solana/dark-solana-logo.svg
@@ -0,0 +1,15 @@
+
diff --git a/explorer/src/metaplex/Art/Art.tsx b/explorer/src/metaplex/Art/Art.tsx
index 367a5a0c3..a9d2351a7 100644
--- a/explorer/src/metaplex/Art/Art.tsx
+++ b/explorer/src/metaplex/Art/Art.tsx
@@ -1,4 +1,4 @@
-import React, { Ref, useCallback, useEffect, useState } from "react";
+import { useCallback, useEffect, useState } from "react";
import { MetadataCategory, MetadataFile } from "../types";
import { pubkeyToString } from "../utils";
import { useCachedImage, useExtendedArt } from "./useArt";
@@ -7,8 +7,11 @@ import { PublicKey } from "@solana/web3.js";
import { getLast } from "../utils";
import { Metadata } from "metaplex/classes";
import ContentLoader from "react-content-loader";
+import ErrorLogo from "img/logos-solana/dark-solana-logo.svg";
-const Placeholder = () => (
+const MAX_TIME_LOADING_IMAGE = 5000; /* 5 seconds */
+
+const LoadingPlaceholder = () => (
(
);
-const CachedImageContent = ({
- uri,
-}: {
- uri?: string;
- className?: string;
- preview?: boolean;
- style?: React.CSSProperties;
-}) => {
- const [loaded, setLoaded] = useState
(false);
+const ErrorPlaceHolder = () => (
+
+);
+
+const CachedImageContent = ({ uri }: { uri?: string }) => {
+ const [isLoading, setIsLoading] = useState(true);
+ const [showError, setShowError] = useState(false);
+ const [timeout, setTimeout] = useState(undefined);
+
+ useEffect(() => {
+ // Set the timeout if we don't have a valid uri
+ if (!uri && !timeout) {
+ setTimeout(setInterval(() => setShowError(true), MAX_TIME_LOADING_IMAGE));
+ }
+
+ // We have a uri - clear the timeout
+ if (uri && timeout) {
+ clearInterval(timeout);
+ }
+
+ return () => {
+ if (timeout) {
+ clearInterval(timeout);
+ }
+ };
+ }, [uri, setShowError, timeout, setTimeout]);
+
const { cachedBlob } = useCachedImage(uri || "");
return (
<>
- {!loaded && }
- {
- setLoaded(true);
- }}
- onError={() => {
- setLoaded(true);
- }}
- />
+ {showError ? (
+
+
+
Error Loading Image
+
+ ) : (
+ <>
+ {isLoading && }
+ {
+ setIsLoading(false);
+ }}
+ onError={() => {
+ setShowError(true);
+ }}
+ />
+ >
+ )}
>
);
};
const VideoArtContent = ({
- className,
- style,
files,
uri,
animationURL,
active,
}: {
- className?: string;
- style?: React.CSSProperties;
files?: (MetadataFile | string)[];
uri?: string;
animationURL?: string;
@@ -97,7 +122,7 @@ const VideoArtContent = ({
const content =
likelyVideo &&
likelyVideo.startsWith("https://watch.videodelivery.net/") ? (
-
+
playerRef(e)}
src={likelyVideo.replace("https://watch.videodelivery.net/", "")}
@@ -116,26 +141,21 @@ const VideoArtContent = ({
) : (
);
@@ -145,13 +165,9 @@ const VideoArtContent = ({
const HTMLContent = ({
animationUrl,
- className,
- style,
files,
}: {
animationUrl?: string;
- className?: string;
- style?: React.CSSProperties;
files?: (MetadataFile | string)[];
}) => {
const [loaded, setLoaded] = useState
(false);
@@ -162,15 +178,15 @@ const HTMLContent = ({
return (
<>
- {!loaded && }
+ {!loaded && }