diff --git a/src/app/ItemPage.js b/src/app/ItemPage.js
index 5ede8a0..a80d4e4 100644
--- a/src/app/ItemPage.js
+++ b/src/app/ItemPage.js
@@ -38,6 +38,7 @@ import { Link, useParams } from "react-router-dom";
import ItemPageLayout, { SubtleSkeleton } from "./ItemPageLayout";
import { Delay, logAndCapture, usePageTitle } from "./util";
+import HTML5Badge from "./components/HTML5Badge";
import {
itemAppearanceFragment,
petAppearanceFragment,
@@ -895,127 +896,6 @@ function ExpandOnGroupHover({ children, ...props }) {
);
}
-function HTML5Badge({ usesHTML5, isLoading }) {
- const greenBackground = useColorModeValue("green.100", "green.900");
- const greenBorderColor = useColorModeValue("green.600", "green.500");
- const greenTextColor = useColorModeValue("green.700", "white");
-
- const yellowBackground = useColorModeValue("yellow.100", "yellow.900");
- const yellowBorderColor = useColorModeValue("yellow.600", "yellow.500");
- const yellowTextColor = useColorModeValue("yellow.700", "white");
-
- // `delayedUsesHTML5` stores the last known value of `usesHTML5`, when
- // `isLoading` was `false`. This enables us to keep showing the badge, even
- // when loading a new appearance - because it's unlikely the badge will
- // change between different appearances for the same item, and the flicker is
- // annoying!
- const [delayedUsesHTML5, setDelayedUsesHTML5] = React.useState(null);
- React.useEffect(() => {
- if (!isLoading) {
- setDelayedUsesHTML5(usesHTML5);
- }
- }, [usesHTML5, isLoading]);
-
- if (delayedUsesHTML5 === true) {
- return (
-
-
-
- {/* From Twemoji Keycap 5 */}
-
-
-
- );
- } else if (delayedUsesHTML5 === false) {
- return (
-
- This item isn't converted to HTML5 yet, so it might not appear in
- Neopets.com customization yet. Once it's ready, it could look a bit
- different than our temporary preview here. It might even be
- animated!
- >
- }
- >
-
-
- {/* From Twemoji Keycap 5 */}
-
-
- {/* From Twemoji Not Allowed */}
-
-
-
- );
- } else {
- // If no `usesHTML5` value has been provided yet, we're empty for now!
- return null;
- }
-}
-
-function HTML5BadgeLayout({ children, tooltipLabel, ...props }) {
- const [isHovered, setIsHovered] = React.useState(false);
- const [isFocused, setIsFocused] = React.useState(false);
-
- return (
-
- setIsHovered(true)}
- onMouseLeave={() => setIsHovered(false)}
- onFocus={() => setIsFocused(true)}
- onBlur={() => setIsFocused(false)}
- {...props}
- >
- {children}
-
-
- );
-}
-
function PlayPauseButton({ isPaused, onClick }) {
return (
setFocusIsLocked(true), [
@@ -84,6 +86,11 @@ function OutfitControls({
}
};
+ const itemLayers = appearance.itemAppearances.map((a) => a.layers).flat();
+ const usesHTML5 = itemLayers.every(
+ (l) => l.svgUrl || l.canvasMovieLibraryUrl
+ );
+
return (
{({ css, cx }) => (
@@ -173,7 +180,32 @@ function OutfitControls({
* We try to center the species/color picker, but the left spacer will
* shrink more than the pose picker container if we run out of space!
*/}
-
+
+
+ This outfit is converted to HTML5, and ready to use on
+ Neopets.com!
+ >
+ ) : (
+ <>
+ This outfit isn't converted to HTML5 yet, so it might
+ not appear in Neopets.com customization yet. Once it's
+ ready, it could look a bit different than our temporary
+ preview here. It might even be animated!
+ >
+ )
+ }
+ />
+
{
diff --git a/src/app/WardrobePage/WardrobePreviewAndControls.js b/src/app/WardrobePage/WardrobePreviewAndControls.js
index c0f27da..a5804bc 100644
--- a/src/app/WardrobePage/WardrobePreviewAndControls.js
+++ b/src/app/WardrobePage/WardrobePreviewAndControls.js
@@ -7,7 +7,7 @@ import OutfitThumbnail, {
outfitThumbnailFragment,
getOutfitThumbnailRenderSize,
} from "../components/OutfitThumbnail";
-import OutfitPreview from "../components/OutfitPreview";
+import OutfitPreview, { useOutfitPreview } from "../components/OutfitPreview";
import { loadable } from "../util";
const OutfitControls = loadable(() => import("./OutfitControls"));
@@ -21,27 +21,28 @@ function WardrobePreviewAndControls({
// show the play/pause button.
const [hasAnimations, setHasAnimations] = React.useState(false);
+ const { appearance, preview } = useOutfitPreview({
+ isLoading: isLoading,
+ speciesId: outfitState.speciesId,
+ colorId: outfitState.colorId,
+ pose: outfitState.pose,
+ appearanceId: outfitState.appearanceId,
+ wornItemIds: outfitState.wornItemIds,
+ onChangeHasAnimations: setHasAnimations,
+ backdrop: ,
+ });
+
return (
<>
-
- }
- />
-
+ {preview}
>
diff --git a/src/app/components/HTML5Badge.js b/src/app/components/HTML5Badge.js
new file mode 100644
index 0000000..2124a13
--- /dev/null
+++ b/src/app/components/HTML5Badge.js
@@ -0,0 +1,131 @@
+import React from "react";
+import { Tooltip, useColorModeValue, Flex, Icon } from "@chakra-ui/react";
+import { CheckCircleIcon, WarningTwoIcon } from "@chakra-ui/icons";
+
+function HTML5Badge({ usesHTML5, isLoading, tooltipLabel }) {
+ const greenBackground = useColorModeValue("green.100", "green.900");
+ const greenBorderColor = useColorModeValue("green.600", "green.500");
+ const greenTextColor = useColorModeValue("green.700", "white");
+
+ const yellowBackground = useColorModeValue("yellow.100", "yellow.900");
+ const yellowBorderColor = useColorModeValue("yellow.600", "yellow.500");
+ const yellowTextColor = useColorModeValue("yellow.700", "white");
+
+ // `delayedUsesHTML5` stores the last known value of `usesHTML5`, when
+ // `isLoading` was `false`. This enables us to keep showing the badge, even
+ // when loading a new appearance - because it's unlikely the badge will
+ // change between different appearances for the same item, and the flicker is
+ // annoying!
+ const [delayedUsesHTML5, setDelayedUsesHTML5] = React.useState(null);
+ React.useEffect(() => {
+ if (!isLoading) {
+ setDelayedUsesHTML5(usesHTML5);
+ }
+ }, [usesHTML5, isLoading]);
+
+ if (delayedUsesHTML5 === true) {
+ return (
+
+
+
+ {/* From Twemoji Keycap 5 */}
+
+
+
+ );
+ } else if (delayedUsesHTML5 === false) {
+ return (
+
+ This item isn't converted to HTML5 yet, so it might not appear in
+ Neopets.com customization yet. Once it's ready, it could look a
+ bit different than our temporary preview here. It might even be
+ animated!
+ >
+ )
+ }
+ >
+
+
+ {/* From Twemoji Keycap 5 */}
+
+
+ {/* From Twemoji Not Allowed */}
+
+
+
+ );
+ } else {
+ // If no `usesHTML5` value has been provided yet, we're empty for now!
+ return null;
+ }
+}
+
+function HTML5BadgeLayout({ children, tooltipLabel, ...props }) {
+ const [isHovered, setIsHovered] = React.useState(false);
+ const [isFocused, setIsFocused] = React.useState(false);
+
+ return (
+
+ setIsHovered(true)}
+ onMouseLeave={() => setIsHovered(false)}
+ onFocus={() => setIsFocused(true)}
+ onBlur={() => setIsFocused(false)}
+ {...props}
+ >
+ {children}
+
+
+ );
+}
+
+export default HTML5Badge;