Run Prettier on all wardrobe-2020 JS
Looks like the version of Prettier I just installed is v3, whereas our last run in the impress-2020 repo was with v2. I don't think we had any special config in that project, I think these are just changes to Prettier's defaults, and I'm comfortable accepting them! (Mostly seems like a lot of trailing commas.)
This commit is contained in:
parent
70d21e2815
commit
e300b2d342
39 changed files with 260 additions and 250 deletions
|
@ -9,5 +9,5 @@ ReactDOM.render(
|
|||
<AppProvider>
|
||||
<ItemPageOutfitPreview itemId={itemId} />
|
||||
</AppProvider>,
|
||||
rootNode
|
||||
rootNode,
|
||||
);
|
||||
|
|
|
@ -8,5 +8,5 @@ ReactDOM.render(
|
|||
<AppProvider>
|
||||
<WardrobePage />
|
||||
</AppProvider>,
|
||||
rootNode
|
||||
rootNode,
|
||||
);
|
||||
|
|
|
@ -55,7 +55,7 @@ function DTIApolloProvider({ children, additionalCacheState = {} }) {
|
|||
getAuth0: () => auth0Ref.current,
|
||||
initialCacheState,
|
||||
}),
|
||||
[initialCacheState]
|
||||
[initialCacheState],
|
||||
);
|
||||
|
||||
// When we get a new `additionalCacheState` object, merge it into the cache:
|
||||
|
@ -88,7 +88,7 @@ function DTIApolloProvider({ children, additionalCacheState = {} }) {
|
|||
console.debug(
|
||||
"Merging Apollo cache:",
|
||||
additionalCacheState,
|
||||
mergedCacheState
|
||||
mergedCacheState,
|
||||
);
|
||||
client.cache.restore(mergedCacheState);
|
||||
}, [client, additionalCacheState]);
|
||||
|
|
|
@ -91,7 +91,7 @@ export function ItemPageContent({ itemId, isEmbedded = false }) {
|
|||
}
|
||||
}
|
||||
`,
|
||||
{ variables: { itemId }, returnPartialData: true }
|
||||
{ variables: { itemId }, returnPartialData: true },
|
||||
);
|
||||
|
||||
if (error) {
|
||||
|
@ -296,7 +296,7 @@ const ItemPageOwnWantListsDropdownButton = React.forwardRef(
|
|||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
function ItemPageOwnWantListsDropdownContent({ closetLists, item }) {
|
||||
|
@ -330,7 +330,7 @@ function ItemPageOwnWantsListsDropdownRow({ closetList, item }) {
|
|||
}
|
||||
}
|
||||
`,
|
||||
{ context: { sendAuth: true } }
|
||||
{ context: { sendAuth: true } },
|
||||
);
|
||||
|
||||
const [sendRemoveFromListMutation] = useMutation(
|
||||
|
@ -346,7 +346,7 @@ function ItemPageOwnWantsListsDropdownRow({ closetList, item }) {
|
|||
}
|
||||
}
|
||||
`,
|
||||
{ context: { sendAuth: true } }
|
||||
{ context: { sendAuth: true } },
|
||||
);
|
||||
|
||||
const onChange = React.useCallback(
|
||||
|
@ -391,7 +391,13 @@ function ItemPageOwnWantsListsDropdownRow({ closetList, item }) {
|
|||
});
|
||||
}
|
||||
},
|
||||
[closetList, item, sendAddToListMutation, sendRemoveFromListMutation, toast]
|
||||
[
|
||||
closetList,
|
||||
item,
|
||||
sendAddToListMutation,
|
||||
sendRemoveFromListMutation,
|
||||
toast,
|
||||
],
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -439,7 +445,7 @@ function ItemPageOwnButton({ itemId, isChecked }) {
|
|||
context: { sendAuth: true },
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const [sendRemoveMutation] = useMutation(
|
||||
|
@ -470,7 +476,7 @@ function ItemPageOwnButton({ itemId, isChecked }) {
|
|||
context: { sendAuth: true },
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -565,7 +571,7 @@ function ItemPageWantButton({ itemId, isChecked }) {
|
|||
context: { sendAuth: true },
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const [sendRemoveMutation] = useMutation(
|
||||
|
@ -596,7 +602,7 @@ function ItemPageWantButton({ itemId, isChecked }) {
|
|||
context: { sendAuth: true },
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -670,7 +676,7 @@ function ItemPageTradeLinks({ itemId, isEmbedded }) {
|
|||
}
|
||||
}
|
||||
`,
|
||||
{ variables: { itemId } }
|
||||
{ variables: { itemId } },
|
||||
);
|
||||
|
||||
if (error) {
|
||||
|
@ -762,7 +768,7 @@ function IconCheckbox({ icon, isChecked, ...props }) {
|
|||
export function ItemPageOutfitPreview({ itemId }) {
|
||||
const idealPose = React.useMemo(
|
||||
() => (Math.random() > 0.5 ? "HAPPY_FEM" : "HAPPY_MASC"),
|
||||
[]
|
||||
[],
|
||||
);
|
||||
const [petState, setPetState] = React.useState({
|
||||
// We'll fill these in once the canonical appearance data arrives.
|
||||
|
@ -780,11 +786,11 @@ export function ItemPageOutfitPreview({ itemId }) {
|
|||
});
|
||||
const [preferredSpeciesId, setPreferredSpeciesId] = useLocalStorage(
|
||||
"DTIItemPreviewPreferredSpeciesId",
|
||||
null
|
||||
null,
|
||||
);
|
||||
const [preferredColorId, setPreferredColorId] = useLocalStorage(
|
||||
"DTIItemPreviewPreferredColorId",
|
||||
null
|
||||
null,
|
||||
);
|
||||
|
||||
const setPetStateFromUserAction = React.useCallback(
|
||||
|
@ -819,7 +825,7 @@ export function ItemPageOutfitPreview({ itemId }) {
|
|||
|
||||
return newPetState;
|
||||
}),
|
||||
[setPreferredColorId, setPreferredSpeciesId]
|
||||
[setPreferredColorId, setPreferredSpeciesId],
|
||||
);
|
||||
|
||||
// We don't need to reload this query when preferred species/color change, so
|
||||
|
@ -917,7 +923,7 @@ export function ItemPageOutfitPreview({ itemId }) {
|
|||
appearanceId: canonicalPetAppearance?.id,
|
||||
});
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const compatibleBodies =
|
||||
|
@ -933,7 +939,7 @@ export function ItemPageOutfitPreview({ itemId }) {
|
|||
compatibleBodies.length === 1 &&
|
||||
!compatibleBodies[0].representsAllBodies &&
|
||||
(data?.item?.name || "").includes(
|
||||
data?.item?.canonicalAppearance?.body?.canonicalAppearance?.species?.name
|
||||
data?.item?.canonicalAppearance?.body?.canonicalAppearance?.species?.name,
|
||||
);
|
||||
const couldProbablyModelMoreData = !isProbablySpeciesSpecific;
|
||||
|
||||
|
@ -979,7 +985,7 @@ export function ItemPageOutfitPreview({ itemId }) {
|
|||
appearanceId: null,
|
||||
});
|
||||
},
|
||||
[valids, idealPose, setPetStateFromUserAction]
|
||||
[valids, idealPose, setPetStateFromUserAction],
|
||||
);
|
||||
|
||||
const borderColor = useColorModeValue("green.700", "green.400");
|
||||
|
@ -1195,8 +1201,8 @@ function ExpandOnGroupHover({ children, ...props }) {
|
|||
// I don't think this is possible, but I'd like to know if it happens!
|
||||
logAndCapture(
|
||||
new Error(
|
||||
`Measurer node not ready during effect. Transition won't be smooth.`
|
||||
)
|
||||
`Measurer node not ready during effect. Transition won't be smooth.`,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -1277,8 +1283,8 @@ export function ItemZonesInfo({
|
|||
|
||||
const sortedZonesAndTheirBodies = [...zoneLabelsAndTheirBodies].sort((a, b) =>
|
||||
buildSortKeyForZoneLabelsAndTheirBodies(a).localeCompare(
|
||||
buildSortKeyForZoneLabelsAndTheirBodies(b)
|
||||
)
|
||||
buildSortKeyForZoneLabelsAndTheirBodies(b),
|
||||
),
|
||||
);
|
||||
|
||||
const restrictedZoneLabels = [
|
||||
|
@ -1290,8 +1296,8 @@ export function ItemZonesInfo({
|
|||
// preview available in the list has the zones listed here.
|
||||
const bodyGroups = new Set(
|
||||
zoneLabelsAndTheirBodies.map(({ bodies }) =>
|
||||
bodies.map((b) => b.id).join(",")
|
||||
)
|
||||
bodies.map((b) => b.id).join(","),
|
||||
),
|
||||
);
|
||||
const showBodyInfo = bodyGroups.size > 1;
|
||||
|
||||
|
|
|
@ -56,11 +56,11 @@ function SpeciesFacesPicker({
|
|||
variables: { selectedColorId },
|
||||
skip: selectedColorId == null || selectedColorIsBasic,
|
||||
onError: (e) => console.error(e),
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const allBodiesAreCompatible = compatibleBodies.some(
|
||||
(body) => body.representsAllBodies
|
||||
(body) => body.representsAllBodies,
|
||||
);
|
||||
const compatibleBodyIds = compatibleBodies.map((body) => body.id);
|
||||
|
||||
|
@ -68,7 +68,7 @@ function SpeciesFacesPicker({
|
|||
|
||||
const allSpeciesFaces = DEFAULT_SPECIES_FACES.map((defaultSpeciesFace) => {
|
||||
const providedSpeciesFace = speciesFacesFromData.find(
|
||||
(f) => f.species.id === defaultSpeciesFace.speciesId
|
||||
(f) => f.species.id === defaultSpeciesFace.speciesId,
|
||||
);
|
||||
if (providedSpeciesFace) {
|
||||
return {
|
||||
|
@ -250,7 +250,8 @@ const SpeciesFaceOption = React.memo(
|
|||
input:checked + & {
|
||||
background: ${selectedBackgroundColorValue};
|
||||
border-radius: 6px;
|
||||
box-shadow: ${xlShadow},
|
||||
box-shadow:
|
||||
${xlShadow},
|
||||
${selectedBorderColorValue} 0 0 2px 2px;
|
||||
transform: scale(1.2);
|
||||
z-index: 1;
|
||||
|
@ -258,7 +259,9 @@ const SpeciesFaceOption = React.memo(
|
|||
|
||||
input:focus + & {
|
||||
background: ${focusBackgroundColorValue};
|
||||
box-shadow: ${xlShadow}, ${focusBorderColorValue} 0 0 0 3px;
|
||||
box-shadow:
|
||||
${xlShadow},
|
||||
${focusBorderColorValue} 0 0 0 3px;
|
||||
}
|
||||
`}
|
||||
>
|
||||
|
@ -324,7 +327,7 @@ const SpeciesFaceOption = React.memo(
|
|||
)}
|
||||
</ClassNames>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
@ -364,7 +364,7 @@ const LinkBadge = React.forwardRef(
|
|||
}
|
||||
</Badge>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const fullDateFormatter = new Intl.DateTimeFormat("en-US", {
|
||||
|
|
|
@ -26,7 +26,7 @@ import useSupport from "./support/useSupport";
|
|||
|
||||
const LoadableItemPageDrawer = loadable(() => import("../ItemPageDrawer"));
|
||||
const LoadableItemSupportDrawer = loadable(() =>
|
||||
import("./support/ItemSupportDrawer")
|
||||
import("./support/ItemSupportDrawer"),
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -151,17 +151,17 @@ function ItemContainer({ children, isDisabled = false }) {
|
|||
|
||||
const focusBackgroundColor = useColorModeValue(
|
||||
theme.colors.gray["100"],
|
||||
theme.colors.gray["700"]
|
||||
theme.colors.gray["700"],
|
||||
);
|
||||
|
||||
const activeBorderColor = useColorModeValue(
|
||||
theme.colors.green["400"],
|
||||
theme.colors.green["500"]
|
||||
theme.colors.green["500"],
|
||||
);
|
||||
|
||||
const focusCheckedBorderColor = useColorModeValue(
|
||||
theme.colors.green["800"],
|
||||
theme.colors.green["300"]
|
||||
theme.colors.green["300"],
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -205,10 +205,10 @@ function ItemBadges({ item }) {
|
|||
const { isSupportUser } = useSupport();
|
||||
const occupiedZones = item.appearanceOn.layers.map((l) => l.zone);
|
||||
const restrictedZones = item.appearanceOn.restrictedZones.filter(
|
||||
(z) => z.isCommonlyUsedByItems
|
||||
(z) => z.isCommonlyUsedByItems,
|
||||
);
|
||||
const isMaybeAnimated = item.appearanceOn.layers.some(
|
||||
(l) => l.canvasMovieLibraryUrl
|
||||
(l) => l.canvasMovieLibraryUrl,
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -237,11 +237,11 @@ function ItemActionButton({ icon, label, to, onClick }) {
|
|||
|
||||
const focusBackgroundColor = useColorModeValue(
|
||||
theme.colors.gray["300"],
|
||||
theme.colors.gray["800"]
|
||||
theme.colors.gray["800"],
|
||||
);
|
||||
const focusColor = useColorModeValue(
|
||||
theme.colors.gray["700"],
|
||||
theme.colors.gray["200"]
|
||||
theme.colors.gray["200"],
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -35,7 +35,7 @@ function ItemsAndSearchPanels({
|
|||
const hasRoomForSearchFooter = useBreakpointValue({ base: false, md: true });
|
||||
const [canUseSearchFooter] = useLocalStorage(
|
||||
"DTIFeatureFlagCanUseSearchFooter",
|
||||
false
|
||||
false,
|
||||
);
|
||||
const isShowingSearchFooter = canUseSearchFooter && hasRoomForSearchFooter;
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ function ItemZoneGroup({
|
|||
(itemId) => {
|
||||
dispatchToOutfit({ type: "removeItem", itemId });
|
||||
},
|
||||
[dispatchToOutfit]
|
||||
[dispatchToOutfit],
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -472,7 +472,7 @@ function DeleteOutfitMenuItem({ outfitState }) {
|
|||
cache.evict(`Outfit:${id}`);
|
||||
cache.gc();
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -62,11 +62,11 @@ function OutfitControls({
|
|||
const [focusIsLocked, setFocusIsLocked] = React.useState(false);
|
||||
const onLockFocus = React.useCallback(
|
||||
() => setFocusIsLocked(true),
|
||||
[setFocusIsLocked]
|
||||
[setFocusIsLocked],
|
||||
);
|
||||
const onUnlockFocus = React.useCallback(
|
||||
() => setFocusIsLocked(false),
|
||||
[setFocusIsLocked]
|
||||
[setFocusIsLocked],
|
||||
);
|
||||
|
||||
// HACK: As of 1.0.0-rc.0, Chakra's `toast` function rebuilds unnecessarily,
|
||||
|
@ -97,7 +97,7 @@ function OutfitControls({
|
|||
});
|
||||
}
|
||||
},
|
||||
[dispatchToOutfit, toast]
|
||||
[dispatchToOutfit, toast],
|
||||
);
|
||||
|
||||
const maybeUnlockFocus = (e) => {
|
||||
|
@ -145,11 +145,11 @@ function OutfitControls({
|
|||
}
|
||||
}
|
||||
`,
|
||||
focusIsLocked && "focus-is-locked"
|
||||
focusIsLocked && "focus-is-locked",
|
||||
)}
|
||||
onClickCapture={(e) => {
|
||||
const opacity = parseFloat(
|
||||
getComputedStyle(e.currentTarget).opacity
|
||||
getComputedStyle(e.currentTarget).opacity,
|
||||
);
|
||||
if (opacity < 0.5) {
|
||||
// If the controls aren't visible right now, then clicks on them are
|
||||
|
@ -321,7 +321,7 @@ function OutfitHTML5Badge({ appearance }) {
|
|||
appearance.petAppearance?.layers.every(layerUsesHTML5);
|
||||
|
||||
const itemsNotUsingHTML5 = appearance.items.filter((item) =>
|
||||
item.appearance.layers.some((l) => !layerUsesHTML5(l))
|
||||
item.appearance.layers.some((l) => !layerUsesHTML5(l)),
|
||||
);
|
||||
itemsNotUsingHTML5.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
|
@ -448,7 +448,7 @@ function PlayPauseButton() {
|
|||
// We show an intro animation if this mounts while paused. Whereas if we're
|
||||
// not paused, we initialize as if we had already finished.
|
||||
const [blinkInState, setBlinkInState] = React.useState(
|
||||
isPaused ? { type: "ready" } : { type: "done" }
|
||||
isPaused ? { type: "ready" } : { type: "done" },
|
||||
);
|
||||
const buttonRef = React.useRef(null);
|
||||
|
||||
|
@ -532,7 +532,7 @@ const PlayPauseButtonContent = React.forwardRef(
|
|||
{isPaused ? <>Paused</> : <>Playing</>}
|
||||
</TranslucentButton>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
function SettingsButton({ onLockFocus, onUnlockFocus }) {
|
||||
|
@ -700,7 +700,7 @@ function useDownloadableImage(visibleLayers) {
|
|||
loadImage(getBestImageUrlForLayer(layer, { hiResMode }), {
|
||||
crossOrigin: "anonymous",
|
||||
preferArchive,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
let images;
|
||||
|
@ -729,7 +729,7 @@ function useDownloadableImage(visibleLayers) {
|
|||
console.debug(
|
||||
"Generated image for download",
|
||||
layerIds,
|
||||
canvas.toDataURL("image/png")
|
||||
canvas.toDataURL("image/png"),
|
||||
);
|
||||
setDownloadImageUrl(canvas.toDataURL("image/png"));
|
||||
setPreparedForLayerIds(layerIds);
|
||||
|
|
|
@ -36,7 +36,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
We're hiding the item art, which is outdated behavior, and we should
|
||||
instead be treating it as entirely incompatible. Fixing this is in
|
||||
our todo list, sorry for the confusing UI!
|
||||
</Box>
|
||||
</Box>,
|
||||
);
|
||||
} else if (compatibleItemLayers.length < allItemLayers.length) {
|
||||
glitchMessages.push(
|
||||
|
@ -45,7 +45,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
we believe this is how it looks: some zones are visible, and some
|
||||
zones are hidden. If this isn't quite right, please email me at
|
||||
matchu@openneo.net and let me know!
|
||||
</Box>
|
||||
</Box>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -54,12 +54,12 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
// Look for items with the OFFICIAL_SWF_IS_INCORRECT glitch.
|
||||
for (const item of items) {
|
||||
const itemHasBrokenOnNeopetsDotCom = item.appearance.layers.some((l) =>
|
||||
(l.knownGlitches || []).includes("OFFICIAL_SWF_IS_INCORRECT")
|
||||
(l.knownGlitches || []).includes("OFFICIAL_SWF_IS_INCORRECT"),
|
||||
);
|
||||
const itemHasBrokenUnconvertedLayers = item.appearance.layers.some(
|
||||
(l) =>
|
||||
(l.knownGlitches || []).includes("OFFICIAL_SWF_IS_INCORRECT") &&
|
||||
!layerUsesHTML5(l)
|
||||
!layerUsesHTML5(l),
|
||||
);
|
||||
if (itemHasBrokenOnNeopetsDotCom) {
|
||||
glitchMessages.push(
|
||||
|
@ -79,7 +79,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
know if it looks right, or still looks wrong! Thank you!
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
</Box>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
// Look for items with the OFFICIAL_MOVIE_IS_INCORRECT glitch.
|
||||
for (const item of items) {
|
||||
const itemHasGlitch = item.appearance.layers.some((l) =>
|
||||
(l.knownGlitches || []).includes("OFFICIAL_MOVIE_IS_INCORRECT")
|
||||
(l.knownGlitches || []).includes("OFFICIAL_MOVIE_IS_INCORRECT"),
|
||||
);
|
||||
if (itemHasGlitch) {
|
||||
glitchMessages.push(
|
||||
|
@ -96,7 +96,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
looks this way on-site, too. But our version might be out of date! If
|
||||
you've seen it look better on-site, please email me at
|
||||
matchu@openneo.net so we can fix it!
|
||||
</Box>
|
||||
</Box>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
if (hiResMode) {
|
||||
for (const item of items) {
|
||||
const itemHasOfficialSvgIsIncorrect = item.appearance.layers.some((l) =>
|
||||
(l.knownGlitches || []).includes("OFFICIAL_SVG_IS_INCORRECT")
|
||||
(l.knownGlitches || []).includes("OFFICIAL_SVG_IS_INCORRECT"),
|
||||
);
|
||||
if (itemHasOfficialSvgIsIncorrect) {
|
||||
glitchMessages.push(
|
||||
|
@ -114,7 +114,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
There's a glitch in the art for <i>{item.name}</i> that prevents us
|
||||
from showing the SVG image for Hi-Res Mode. Instead, we're showing a
|
||||
PNG, which might look a bit blurry on larger screens.
|
||||
</Box>
|
||||
</Box>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +123,9 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
// Look for items with the DISPLAYS_INCORRECTLY_BUT_CAUSE_UNKNOWN glitch.
|
||||
for (const item of items) {
|
||||
const itemHasGlitch = item.appearance.layers.some((l) =>
|
||||
(l.knownGlitches || []).includes("DISPLAYS_INCORRECTLY_BUT_CAUSE_UNKNOWN")
|
||||
(l.knownGlitches || []).includes(
|
||||
"DISPLAYS_INCORRECTLY_BUT_CAUSE_UNKNOWN",
|
||||
),
|
||||
);
|
||||
if (itemHasGlitch) {
|
||||
glitchMessages.push(
|
||||
|
@ -132,7 +134,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
display incorrectly—but we're not sure if it's on our end, or TNT's.
|
||||
If you own this item, please email me at matchu@openneo.net to let us
|
||||
know how it looks in the on-site customizer!
|
||||
</Box>
|
||||
</Box>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +142,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
// Look for items with the OFFICIAL_BODY_ID_IS_INCORRECT glitch.
|
||||
for (const item of items) {
|
||||
const itemHasOfficialBodyIdIsIncorrect = item.appearance.layers.some((l) =>
|
||||
(l.knownGlitches || []).includes("OFFICIAL_BODY_ID_IS_INCORRECT")
|
||||
(l.knownGlitches || []).includes("OFFICIAL_BODY_ID_IS_INCORRECT"),
|
||||
);
|
||||
if (itemHasOfficialBodyIdIsIncorrect) {
|
||||
glitchMessages.push(
|
||||
|
@ -148,7 +150,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
Last we checked, <i>{item.name}</i> actually is compatible with this
|
||||
pet, even though it seems like it shouldn't be. But TNT might change
|
||||
this at any time, so be careful!
|
||||
</Box>
|
||||
</Box>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +166,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
<i>{item.name}</i> isn't converted to HTML5 yet, and our Classic DTI
|
||||
code often shows old Dyeworks items in the wrong color. Once it's
|
||||
converted, we'll display it correctly!
|
||||
</Box>
|
||||
</Box>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +180,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
this pose looks incorrect, you can try another by clicking the emoji
|
||||
face next to the species/color picker. But be aware that Neopets.com
|
||||
might look different!
|
||||
</Box>
|
||||
</Box>,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -194,7 +196,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
horn with the feminine design, and the yellow horn with the masculine
|
||||
design—but the pet's gender does not actually affect which horn you'll
|
||||
get, and it will often change over time!
|
||||
</Box>
|
||||
</Box>,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -211,7 +213,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
correct data, we'll use that instead. For now, you could also try
|
||||
switching to another pose, by clicking the emoji face next to the
|
||||
species/color picker!
|
||||
</Box>
|
||||
</Box>,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -220,7 +222,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
// Look for pet layers with the OFFICIAL_SWF_IS_INCORRECT glitch.
|
||||
for (const layer of petLayers) {
|
||||
const layerHasGlitch = (layer.knownGlitches || []).includes(
|
||||
"OFFICIAL_SWF_IS_INCORRECT"
|
||||
"OFFICIAL_SWF_IS_INCORRECT",
|
||||
);
|
||||
if (layerHasGlitch) {
|
||||
glitchMessages.push(
|
||||
|
@ -230,7 +232,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
affected its appearance on Neopets.com, too. But our version might be
|
||||
out of date! If you've seen it look better on-site, please email me at
|
||||
matchu@openneo.net so we can fix it!
|
||||
</Box>
|
||||
</Box>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -248,7 +250,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
zone that prevents us from showing the SVG image for Hi-Res Mode.
|
||||
Instead, we're showing a PNG, which might look a bit blurry on
|
||||
larger screens.
|
||||
</Box>
|
||||
</Box>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -257,7 +259,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
// Look for pet layers with the DISPLAYS_INCORRECTLY_BUT_CAUSE_UNKNOWN glitch.
|
||||
for (const layer of petLayers) {
|
||||
const layerHasGlitch = (layer.knownGlitches || []).includes(
|
||||
"DISPLAYS_INCORRECTLY_BUT_CAUSE_UNKNOWN"
|
||||
"DISPLAYS_INCORRECTLY_BUT_CAUSE_UNKNOWN",
|
||||
);
|
||||
if (layerHasGlitch) {
|
||||
glitchMessages.push(
|
||||
|
@ -269,7 +271,7 @@ function OutfitKnownGlitchesBadge({ appearance }) {
|
|||
on our end, or TNT's. If you have this pet, please email me at
|
||||
matchu@openneo.net to let us know how it looks in the on-site
|
||||
customizer!
|
||||
</Box>
|
||||
</Box>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ import twemojiFem from "../images/twemoji/fem.svg";
|
|||
const PosePickerSupport = loadable(() => import("./support/PosePickerSupport"));
|
||||
|
||||
const PosePickerSupportSwitch = loadable(() =>
|
||||
import("./support/PosePickerSupport").then((m) => m.PosePickerSupportSwitch)
|
||||
import("./support/PosePickerSupport").then((m) => m.PosePickerSupportSwitch),
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -68,7 +68,7 @@ function PosePicker({
|
|||
const { loading, error, poseInfos } = usePoses(speciesId, colorId, pose);
|
||||
const [isInSupportMode, setIsInSupportMode] = useLocalStorage(
|
||||
"DTIPosePickerIsInSupportMode",
|
||||
false
|
||||
false,
|
||||
);
|
||||
const { isSupportUser } = useSupport();
|
||||
const toast = useToast();
|
||||
|
@ -87,10 +87,10 @@ function PosePicker({
|
|||
// can happen with direct URL navigation, or pet loading when modeling isn't
|
||||
// updated! Let's do some recovery.
|
||||
const selectedPoseIsAvailable = Object.values(poseInfos).some(
|
||||
(pi) => pi.isSelected && pi.isAvailable
|
||||
(pi) => pi.isSelected && pi.isAvailable,
|
||||
);
|
||||
const firstAvailablePose = Object.values(poseInfos).find(
|
||||
(pi) => pi.isAvailable
|
||||
(pi) => pi.isAvailable,
|
||||
)?.pose;
|
||||
React.useEffect(() => {
|
||||
if (loading) {
|
||||
|
@ -114,7 +114,7 @@ function PosePicker({
|
|||
|
||||
console.warn(
|
||||
`Pose ${pose} not found for speciesId=${speciesId}, ` +
|
||||
`colorId=${colorId}. Redirecting to pose ${firstAvailablePose}.`
|
||||
`colorId=${colorId}. Redirecting to pose ${firstAvailablePose}.`,
|
||||
);
|
||||
dispatchToOutfit({ type: "setPose", pose: firstAvailablePose });
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ function PosePicker({
|
|||
// (Unless we're Support, in which case we want the ability to pop it open to
|
||||
// inspect and label the Unknown poses!)
|
||||
const numAvailablePoses = Object.values(poseInfos).filter(
|
||||
(p) => p.isAvailable
|
||||
(p) => p.isAvailable,
|
||||
).length;
|
||||
if (numAvailablePoses <= 1 && !isSupportUser) {
|
||||
return null;
|
||||
|
@ -192,7 +192,7 @@ function PosePicker({
|
|||
border-width: 2px !important;
|
||||
}
|
||||
`,
|
||||
isOpen && "is-open"
|
||||
isOpen && "is-open",
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
|
@ -393,7 +393,7 @@ function PoseOption({
|
|||
|
||||
const borderColor = useColorModeValue(
|
||||
theme.colors.green["600"],
|
||||
theme.colors.green["300"]
|
||||
theme.colors.green["300"],
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -480,7 +480,7 @@ function PoseOption({
|
|||
border-width: 3px;
|
||||
}
|
||||
`,
|
||||
!poseInfo.isAvailable && "not-available"
|
||||
!poseInfo.isAvailable && "not-available",
|
||||
)}
|
||||
/>
|
||||
{poseInfo.isAvailable ? (
|
||||
|
@ -580,7 +580,7 @@ function usePoses(speciesId, colorId, selectedPose) {
|
|||
|
||||
${petAppearanceForPosePickerFragment}
|
||||
`,
|
||||
{ variables: { speciesId, colorId }, onError: (e) => console.error(e) }
|
||||
{ variables: { speciesId, colorId }, onError: (e) => console.error(e) },
|
||||
);
|
||||
|
||||
const poseInfos = {
|
||||
|
|
|
@ -13,13 +13,13 @@ import { useSearchResults } from "./useSearchResults";
|
|||
function SearchFooter({ searchQuery, onChangeSearchQuery, outfitState }) {
|
||||
const [canUseSearchFooter, setCanUseSearchFooter] = useLocalStorage(
|
||||
"DTIFeatureFlagCanUseSearchFooter",
|
||||
false
|
||||
false,
|
||||
);
|
||||
|
||||
const { items, numTotalPages } = useSearchResults(
|
||||
searchQuery,
|
||||
outfitState,
|
||||
1
|
||||
1,
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
|
|
|
@ -85,7 +85,7 @@ function SearchResults({
|
|||
const { loading, error, items, numTotalPages } = useSearchResults(
|
||||
query,
|
||||
outfitState,
|
||||
currentPageNumber
|
||||
currentPageNumber,
|
||||
);
|
||||
|
||||
// Preload the previous and next page of search results, with this quick
|
||||
|
@ -121,7 +121,7 @@ function SearchResults({
|
|||
onMoveFocusUpToQuery(e);
|
||||
}
|
||||
},
|
||||
[onMoveFocusUpToQuery]
|
||||
[onMoveFocusUpToQuery],
|
||||
);
|
||||
const goToNextItem = React.useCallback((e) => {
|
||||
const nextLabel = e.target.closest("label").nextSibling;
|
||||
|
@ -223,7 +223,7 @@ function SearchResultItem({
|
|||
itemId: item.id,
|
||||
itemIdsToReconsider,
|
||||
}),
|
||||
[item.id, itemIdsToReconsider, dispatchToOutfit]
|
||||
[item.id, itemIdsToReconsider, dispatchToOutfit],
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -111,7 +111,7 @@ function SearchToolbar({
|
|||
{text}
|
||||
</Box>
|
||||
),
|
||||
[suggestionBgColor, highlightedBgColor]
|
||||
[suggestionBgColor, highlightedBgColor],
|
||||
);
|
||||
|
||||
const renderSuggestionsContainer = React.useCallback(
|
||||
|
@ -133,7 +133,7 @@ function SearchToolbar({
|
|||
li {
|
||||
list-style: none;
|
||||
}
|
||||
`
|
||||
`,
|
||||
)}
|
||||
{...SUGGESTIONS_PLACEMENT_PROPS[suggestionsPlacement]}
|
||||
>
|
||||
|
@ -153,7 +153,7 @@ function SearchToolbar({
|
|||
</ClassNames>
|
||||
);
|
||||
},
|
||||
[advancedSearchIsOpen, suggestionsPlacement]
|
||||
[advancedSearchIsOpen, suggestionsPlacement],
|
||||
);
|
||||
|
||||
// When we change the query filters, clear out the suggestions.
|
||||
|
@ -205,7 +205,7 @@ function SearchToolbar({
|
|||
// always happened? Idk? Let's just, gate around it, I guess?
|
||||
if (typeof value === "string") {
|
||||
setSuggestions(
|
||||
getSuggestions(value, query, zoneLabels, isLoggedIn)
|
||||
getSuggestions(value, query, zoneLabels, isLoggedIn),
|
||||
);
|
||||
}
|
||||
}}
|
||||
|
@ -342,7 +342,7 @@ function getSuggestions(
|
|||
query,
|
||||
zoneLabels,
|
||||
isLoggedIn,
|
||||
{ showAll = false } = {}
|
||||
{ showAll = false } = {},
|
||||
) {
|
||||
if (!value && !showAll) {
|
||||
return [];
|
||||
|
@ -467,8 +467,8 @@ function removeLastWord(text) {
|
|||
logAndCapture(
|
||||
new Error(
|
||||
`Assertion failure: pattern should match any input text, ` +
|
||||
`but failed to match ${JSON.stringify(text)}`
|
||||
)
|
||||
`but failed to match ${JSON.stringify(text)}`,
|
||||
),
|
||||
);
|
||||
return text;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ function OutfitThumbnailIfCached({ outfitId }) {
|
|||
skip: outfitId == null,
|
||||
fetchPolicy: "cache-only",
|
||||
onError: (e) => console.error(e),
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (!data?.outfit) {
|
||||
|
|
|
@ -117,7 +117,7 @@ function WardrobePage() {
|
|||
*/
|
||||
function SavedOutfitMetaTags({ outfitState }) {
|
||||
const updatedAtTimestamp = Math.floor(
|
||||
new Date(outfitState.updatedAt).getTime() / 1000
|
||||
new Date(outfitState.updatedAt).getTime() / 1000,
|
||||
);
|
||||
const imageUrl =
|
||||
`https://impress-outfit-images.openneo.net/outfits` +
|
||||
|
|
|
@ -67,7 +67,7 @@ function AllItemLayersSupportModal({ item, isOpen, onClose }) {
|
|||
|
||||
function BulkAddBodySpecificAssetsForm({ bulkAddProposal, onSubmit }) {
|
||||
const [minAssetId, setMinAssetId] = React.useState(
|
||||
bulkAddProposal?.minAssetId
|
||||
bulkAddProposal?.minAssetId,
|
||||
);
|
||||
const [assetIdStepValue, setAssetIdStepValue] = React.useState(1);
|
||||
const [numSpecies, setNumSpecies] = React.useState(55);
|
||||
|
@ -136,7 +136,7 @@ function BulkAddBodySpecificAssetsForm({ bulkAddProposal, onSubmit }) {
|
|||
setMinAssetId(
|
||||
e.target.value
|
||||
? Number(e.target.value) - assetIdStepValue * (numSpecies - 1)
|
||||
: null
|
||||
: null,
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
@ -230,7 +230,7 @@ function AllItemLayersSupportModalContent({
|
|||
|
||||
${allAppearancesFragment}
|
||||
`,
|
||||
{ variables: { itemId: item.id } }
|
||||
{ variables: { itemId: item.id } },
|
||||
);
|
||||
|
||||
const {
|
||||
|
@ -293,14 +293,14 @@ function AllItemLayersSupportModalContent({
|
|||
? Array.from({ length: 54 }, (_, i) =>
|
||||
String(
|
||||
Number(bulkAddProposal.minAssetId) +
|
||||
i * bulkAddProposal.assetIdStepValue
|
||||
)
|
||||
i * bulkAddProposal.assetIdStepValue,
|
||||
),
|
||||
)
|
||||
: [],
|
||||
colorId: bulkAddProposal?.colorId,
|
||||
},
|
||||
skip: bulkAddProposal == null,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const [
|
||||
|
@ -341,7 +341,7 @@ function AllItemLayersSupportModalContent({
|
|||
itemAppearances = mergeBulkAddProposalIntoItemAppearances(
|
||||
itemAppearances,
|
||||
bulkAddProposal,
|
||||
bulkAddProposalData
|
||||
bulkAddProposalData,
|
||||
);
|
||||
itemAppearances = [...itemAppearances].sort((a, b) => {
|
||||
const aKey = getSortKeyForBody(a.body);
|
||||
|
@ -383,7 +383,7 @@ function AllItemLayersSupportModalContent({
|
|||
// that we use for body assignment in most of this tool.
|
||||
const entries = itemAppearances
|
||||
.map((a) =>
|
||||
a.layers.map((l) => ({ layerId: l.id, bodyId: a.body.id }))
|
||||
a.layers.map((l) => ({ layerId: l.id, bodyId: a.body.id })),
|
||||
)
|
||||
.flat();
|
||||
|
||||
|
@ -415,7 +415,7 @@ function ItemAppearanceCard({ item, itemAppearance }) {
|
|||
const petAppearance = itemAppearance.body.canonicalAppearance;
|
||||
const biologyLayers = petAppearance.layers;
|
||||
const itemLayers = [...itemAppearance.layers].sort(
|
||||
(a, b) => a.zone.depth - b.zone.depth
|
||||
(a, b) => a.zone.depth - b.zone.depth,
|
||||
);
|
||||
|
||||
const { brightBackground } = useCommonStyles();
|
||||
|
@ -494,7 +494,7 @@ function capitalize(str) {
|
|||
function mergeBulkAddProposalIntoItemAppearances(
|
||||
itemAppearances,
|
||||
bulkAddProposal,
|
||||
bulkAddProposalData
|
||||
bulkAddProposalData,
|
||||
) {
|
||||
if (!bulkAddProposalData) {
|
||||
return itemAppearances;
|
||||
|
@ -514,7 +514,7 @@ function mergeBulkAddProposalIntoItemAppearances(
|
|||
|
||||
// Set up the incoming data in convenient formats.
|
||||
const sortedSpeciesColorPairs = [...speciesColorPairsToInclude].sort((a, b) =>
|
||||
a.species.name.localeCompare(b.species.name)
|
||||
a.species.name.localeCompare(b.species.name),
|
||||
);
|
||||
const layersToAddByRemoteId = {};
|
||||
for (const layer of layersToAdd) {
|
||||
|
@ -527,7 +527,7 @@ function mergeBulkAddProposalIntoItemAppearances(
|
|||
// Find the existing item appearance to add to, or create a new one if it
|
||||
// doesn't exist yet.
|
||||
let itemAppearance = mergedItemAppearances.find(
|
||||
(a) => a.body.id === body.id && !a.body.representsAllBodies
|
||||
(a) => a.body.id === body.id && !a.body.representsAllBodies,
|
||||
);
|
||||
if (!itemAppearance) {
|
||||
itemAppearance = {
|
||||
|
@ -543,7 +543,7 @@ function mergeBulkAddProposalIntoItemAppearances(
|
|||
|
||||
const layerToAddRemoteId = String(
|
||||
Number(bulkAddProposal.minAssetId) +
|
||||
index * bulkAddProposal.assetIdStepValue
|
||||
index * bulkAddProposal.assetIdStepValue,
|
||||
);
|
||||
const layerToAdd = layersToAddByRemoteId[layerToAddRemoteId];
|
||||
if (!layerToAdd) {
|
||||
|
@ -554,7 +554,7 @@ function mergeBulkAddProposalIntoItemAppearances(
|
|||
// override its body ID), then add it to this new one.
|
||||
for (const otherItemAppearance of mergedItemAppearances) {
|
||||
const indexToDelete = otherItemAppearance.layers.findIndex(
|
||||
(l) => l.remoteId === layerToAddRemoteId
|
||||
(l) => l.remoteId === layerToAddRemoteId,
|
||||
);
|
||||
if (indexToDelete >= 0) {
|
||||
otherItemAppearance.layers.splice(indexToDelete, 1);
|
||||
|
|
|
@ -50,7 +50,7 @@ function AppearanceLayerSupportModal({
|
|||
}) {
|
||||
const [selectedBodyId, setSelectedBodyId] = React.useState(layer.bodyId);
|
||||
const [selectedKnownGlitches, setSelectedKnownGlitches] = React.useState(
|
||||
layer.knownGlitches
|
||||
layer.knownGlitches,
|
||||
);
|
||||
|
||||
const [previewBiology, setPreviewBiology] = React.useState({
|
||||
|
@ -140,7 +140,7 @@ function AppearanceLayerSupportModal({
|
|||
title: `Saved layer ${layer.id}: ${parentName}`,
|
||||
});
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// TODO: Would be nicer to just learn the correct URL from the server, but we
|
||||
|
@ -148,7 +148,7 @@ function AppearanceLayerSupportModal({
|
|||
// the GraphQL request for non-Support users. We could also just try
|
||||
// loading them, but, ehhh…
|
||||
const [newManifestUrl, oldManifestUrl] = convertSwfUrlToPossibleManifestUrls(
|
||||
layer.swfUrl
|
||||
layer.swfUrl,
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -553,7 +553,7 @@ function AppearanceLayerSupportModalRemoveButton({
|
|||
title: `Removed layer ${layer.id} from ${item.name}`,
|
||||
});
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -54,7 +54,7 @@ function AppearanceLayerSupportUploadModal({ item, layer, isOpen, onClose }) {
|
|||
mergeIntoImageWithAlpha(
|
||||
imageOnBlackUrl,
|
||||
imageOnWhiteUrl,
|
||||
conflictMode
|
||||
conflictMode,
|
||||
).then(([url, blob, numWarnings]) => {
|
||||
setImageWithAlphaUrl(url);
|
||||
setImageWithAlphaBlob(blob);
|
||||
|
@ -86,7 +86,7 @@ function AppearanceLayerSupportUploadModal({ item, layer, isOpen, onClose }) {
|
|||
};
|
||||
reader.readAsDataURL(file);
|
||||
},
|
||||
[step]
|
||||
[step],
|
||||
);
|
||||
|
||||
const onSubmitFinalImage = React.useCallback(async () => {
|
||||
|
@ -104,7 +104,7 @@ function AppearanceLayerSupportUploadModal({ item, layer, isOpen, onClose }) {
|
|||
if (!res.ok) {
|
||||
setIsUploading(false);
|
||||
setUploadError(
|
||||
new Error(`Network error: ${res.status} ${res.statusText}`)
|
||||
new Error(`Network error: ${res.status} ${res.statusText}`),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ function AppearanceLayerSupportFlashPlayer({ swfUrl, backgroundColor }) {
|
|||
async function mergeIntoImageWithAlpha(
|
||||
imageOnBlackUrl,
|
||||
imageOnWhiteUrl,
|
||||
conflictMode
|
||||
conflictMode,
|
||||
) {
|
||||
const [imageOnBlack, imageOnWhite] = await Promise.all([
|
||||
readImageDataFromUrl(imageOnBlackUrl),
|
||||
|
@ -442,7 +442,7 @@ async function mergeIntoImageWithAlpha(
|
|||
const [imageWithAlphaData, numWarnings] = mergeDataIntoImageWithAlpha(
|
||||
imageOnBlack,
|
||||
imageOnWhite,
|
||||
conflictMode
|
||||
conflictMode,
|
||||
);
|
||||
const [imageWithAlphaUrl, imageWithAlphaBlob] =
|
||||
await writeImageDataToUrlAndBlob(imageWithAlphaData);
|
||||
|
@ -474,14 +474,14 @@ function mergeDataIntoImageWithAlpha(imageOnBlack, imageOnWhite, conflictMode) {
|
|||
` vs ` +
|
||||
`#${rOnBlack.toString(16)}${bOnBlack.toString(16)}` +
|
||||
`${gOnWhite.toString(16)}. ` +
|
||||
`Using conflict mode ${conflictMode} to fall back.`
|
||||
`Using conflict mode ${conflictMode} to fall back.`,
|
||||
);
|
||||
}
|
||||
|
||||
const [r, g, b, a] = resolveConflict(
|
||||
[rOnBlack, gOnBlack, bOnBlack],
|
||||
[rOnWhite, gOnWhite, bOnWhite],
|
||||
conflictMode
|
||||
conflictMode,
|
||||
);
|
||||
imageWithAlpha.data[pixelIndex] = r;
|
||||
imageWithAlpha.data[pixelIndex + 1] = g;
|
||||
|
@ -513,14 +513,14 @@ function mergeDataIntoImageWithAlpha(imageOnBlack, imageOnWhite, conflictMode) {
|
|||
` vs ` +
|
||||
`#${rOnBlack.toString(16)}${bOnBlack.toString(16)}` +
|
||||
`${gOnWhite.toString(16)}. ` +
|
||||
`Using conflict mode ${conflictMode} to fall back.`
|
||||
`Using conflict mode ${conflictMode} to fall back.`,
|
||||
);
|
||||
}
|
||||
|
||||
const [r, g, b, a] = resolveConflict(
|
||||
[rOnBlack, gOnBlack, bOnBlack],
|
||||
[rOnWhite, gOnWhite, bOnWhite],
|
||||
conflictMode
|
||||
conflictMode,
|
||||
);
|
||||
imageWithAlpha.data[pixelIndex] = r;
|
||||
imageWithAlpha.data[pixelIndex + 1] = g;
|
||||
|
@ -585,7 +585,7 @@ async function writeImageDataToUrlAndBlob(imageData) {
|
|||
|
||||
const dataUrl = canvas.toDataURL("image/png");
|
||||
const blob = await new Promise((resolve) =>
|
||||
canvas.toBlob(resolve, "image/png")
|
||||
canvas.toBlob(resolve, "image/png"),
|
||||
);
|
||||
return [dataUrl, blob];
|
||||
}
|
||||
|
@ -593,7 +593,7 @@ async function writeImageDataToUrlAndBlob(imageData) {
|
|||
function resolveConflict(
|
||||
[rOnBlack, gOnBlack, bOnBlack],
|
||||
[rOnWhite, gOnWhite, bOnWhite],
|
||||
conflictMode
|
||||
conflictMode,
|
||||
) {
|
||||
if (conflictMode === "onBlack") {
|
||||
return [rOnBlack, gOnBlack, bOnBlack, 255];
|
||||
|
|
|
@ -114,7 +114,7 @@ function ItemSupportRestrictedZones({ item }) {
|
|||
}
|
||||
}
|
||||
`,
|
||||
{ variables: { itemId: item.id, speciesId, colorId } }
|
||||
{ variables: { itemId: item.id, speciesId, colorId } },
|
||||
);
|
||||
|
||||
if (loading) {
|
||||
|
@ -160,7 +160,7 @@ function ItemSupportFields({ item }) {
|
|||
// persuades Apollo that this is a different query, so it re-checks
|
||||
// its cache and finds the empty `manualSpecialColor`. Weird!
|
||||
displayName: `ItemSupportFields-${new Date()}`,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const errorColor = useColorModeValue("red.500", "red.300");
|
||||
|
@ -196,8 +196,7 @@ function ItemSupportSpecialColorFields({
|
|||
loading: colorsLoading,
|
||||
error: colorsError,
|
||||
data: colorsData,
|
||||
} = useQuery(
|
||||
gql`
|
||||
} = useQuery(gql`
|
||||
query ItemSupportDrawerAllColors {
|
||||
allColors {
|
||||
id
|
||||
|
@ -205,8 +204,7 @@ function ItemSupportSpecialColorFields({
|
|||
isStandard
|
||||
}
|
||||
}
|
||||
`
|
||||
);
|
||||
`);
|
||||
|
||||
const [
|
||||
mutate,
|
||||
|
@ -253,7 +251,7 @@ function ItemSupportSpecialColorFields({
|
|||
// Ignore errors from the promise, because we'll handle them on render!
|
||||
});
|
||||
},
|
||||
[item.id, mutate, supportSecret]
|
||||
[item.id, mutate, supportSecret],
|
||||
);
|
||||
|
||||
const nonStandardColors =
|
||||
|
@ -362,7 +360,7 @@ function ItemSupportPetCompatibilityRuleFields({
|
|||
// Ignore errors from the promise, because we'll handle them on render!
|
||||
});
|
||||
},
|
||||
[item.id, mutate, supportSecret]
|
||||
[item.id, mutate, supportSecret],
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -82,7 +82,7 @@ function PosePickerSupport({
|
|||
${canonicalPetAppearancesFragment}
|
||||
${petAppearanceForPosePickerFragment}
|
||||
`,
|
||||
{ variables: { speciesId, colorId } }
|
||||
{ variables: { speciesId, colorId } },
|
||||
);
|
||||
|
||||
// Resize the Popover when we toggle loading state, because it probably will
|
||||
|
@ -111,7 +111,7 @@ function PosePickerSupport({
|
|||
UNKNOWN: data?.unknown?.id,
|
||||
};
|
||||
const canonicalAppearanceIds = Object.values(
|
||||
canonicalAppearanceIdsByPose
|
||||
canonicalAppearanceIdsByPose,
|
||||
).filter((id) => id);
|
||||
|
||||
const providedAppearanceId = appearanceId;
|
||||
|
@ -149,7 +149,7 @@ function PosePickerSupport({
|
|||
}
|
||||
|
||||
const currentPetAppearance = data.petAppearances.find(
|
||||
(pa) => pa.id === appearanceId
|
||||
(pa) => pa.id === appearanceId,
|
||||
);
|
||||
if (!currentPetAppearance) {
|
||||
return (
|
||||
|
@ -353,7 +353,7 @@ function PosePickerSupportPoseFields({ petAppearance, speciesId, colorId }) {
|
|||
variables: { speciesId, colorId },
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const [mutateIsGlitched, isGlitchedMutation] = useMutation(
|
||||
|
@ -388,7 +388,7 @@ function PosePickerSupportPoseFields({ petAppearance, speciesId, colorId }) {
|
|||
variables: { speciesId, colorId },
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -21,7 +21,7 @@ function useSupport() {
|
|||
typeof localStorage !== "undefined"
|
||||
? localStorage.getItem("supportSecret")
|
||||
: null,
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
const isSupportUser = supportSecret != null;
|
||||
|
|
|
@ -27,14 +27,14 @@ function useOutfitSaving(outfitState, dispatchToOutfit) {
|
|||
outfitState.savedOutfitState &&
|
||||
outfitStatesAreEqual(
|
||||
outfitState.outfitStateWithoutExtras,
|
||||
outfitState.savedOutfitState
|
||||
outfitState.savedOutfitState,
|
||||
);
|
||||
React.useEffect(() => {
|
||||
console.debug(
|
||||
"[useOutfitSaving] Latest version is saved? %s\nCurrent: %o\nSaved: %o",
|
||||
latestVersionIsSaved,
|
||||
outfitState.outfitStateWithoutExtras,
|
||||
outfitState.savedOutfitState
|
||||
outfitState.savedOutfitState,
|
||||
);
|
||||
}, [
|
||||
latestVersionIsSaved,
|
||||
|
@ -107,7 +107,7 @@ function useOutfitSaving(outfitState, dispatchToOutfit) {
|
|||
fields: {
|
||||
outfits: (existingOutfitRefs = [], { readField }) => {
|
||||
const isAlreadyInList = existingOutfitRefs.some(
|
||||
(ref) => readField("id", ref) === outfit.id
|
||||
(ref) => readField("id", ref) === outfit.id,
|
||||
);
|
||||
if (isAlreadyInList) {
|
||||
return existingOutfitRefs;
|
||||
|
@ -139,7 +139,7 @@ function useOutfitSaving(outfitState, dispatchToOutfit) {
|
|||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const saveOutfitFromProvidedState = React.useCallback(
|
||||
|
@ -176,12 +176,12 @@ function useOutfitSaving(outfitState, dispatchToOutfit) {
|
|||
// It's important that this callback _doesn't_ change when the outfit
|
||||
// changes, so that the auto-save effect is only responding to the
|
||||
// debounced state!
|
||||
[sendSaveOutfitMutation, pathname, navigate, toast]
|
||||
[sendSaveOutfitMutation, pathname, navigate, toast],
|
||||
);
|
||||
|
||||
const saveOutfit = React.useCallback(
|
||||
() => saveOutfitFromProvidedState(outfitState.outfitStateWithoutExtras),
|
||||
[saveOutfitFromProvidedState, outfitState.outfitStateWithoutExtras]
|
||||
[saveOutfitFromProvidedState, outfitState.outfitStateWithoutExtras],
|
||||
);
|
||||
|
||||
// Auto-saving! First, debounce the outfit state. Use `outfitStateWithoutExtras`,
|
||||
|
@ -196,7 +196,7 @@ function useOutfitSaving(outfitState, dispatchToOutfit) {
|
|||
// When the outfit ID changes, update the debounced state immediately!
|
||||
forceReset: (debouncedOutfitState, newOutfitState) =>
|
||||
debouncedOutfitState.id !== newOutfitState.id,
|
||||
}
|
||||
},
|
||||
);
|
||||
// HACK: This prevents us from auto-saving the outfit state that's still
|
||||
// loading. I worry that this might not catch other loading scenarios
|
||||
|
@ -216,7 +216,7 @@ function useOutfitSaving(outfitState, dispatchToOutfit) {
|
|||
console.info(
|
||||
"[useOutfitSaving] Auto-saving outfit\nSaved: %o\nCurrent (debounced): %o",
|
||||
outfitState.savedOutfitState,
|
||||
debouncedOutfitState
|
||||
debouncedOutfitState,
|
||||
);
|
||||
saveOutfitFromProvidedState(debouncedOutfitState);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ function useOutfitState() {
|
|||
const urlOutfitState = useParseOutfitUrl();
|
||||
const [localOutfitState, dispatchToOutfit] = React.useReducer(
|
||||
outfitStateReducer(apolloClient),
|
||||
urlOutfitState
|
||||
urlOutfitState,
|
||||
);
|
||||
|
||||
// If there's an outfit ID (i.e. we're on /outfits/:id), load basic data
|
||||
|
@ -68,7 +68,7 @@ function useOutfitState() {
|
|||
savedOutfitData: outfitData.outfit,
|
||||
});
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const creator = outfitData?.outfit?.creator;
|
||||
|
@ -78,7 +78,7 @@ function useOutfitState() {
|
|||
// stable object!
|
||||
const savedOutfitState = React.useMemo(
|
||||
() => getOutfitStateFromOutfitData(outfitData?.outfit),
|
||||
[outfitData?.outfit]
|
||||
[outfitData?.outfit],
|
||||
);
|
||||
|
||||
// Choose which customization state to use. We want it to match the outfit in
|
||||
|
@ -182,7 +182,7 @@ function useOutfitState() {
|
|||
// have the species/color ID loaded yet because we're waiting on the
|
||||
// saved outfit to load.
|
||||
skip: allItemIds.length === 0 || speciesId == null || colorId == null,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const resultItems = itemsData?.items || [];
|
||||
|
@ -226,7 +226,7 @@ function useOutfitState() {
|
|||
const zonesAndItems = getZonesAndItems(
|
||||
itemsById,
|
||||
wornItemIds,
|
||||
closetedItemIds
|
||||
closetedItemIds,
|
||||
);
|
||||
const incompatibleItems = items
|
||||
.filter((i) => i.appearanceOn.layers.length === 0)
|
||||
|
@ -334,7 +334,7 @@ const outfitStateReducer = (apolloClient) => (baseState, action) => {
|
|||
// Don't include the unworn item in items to reconsider!
|
||||
itemIdsToReconsider.filter((x) => x !== itemId),
|
||||
state,
|
||||
apolloClient
|
||||
apolloClient,
|
||||
);
|
||||
});
|
||||
case "removeItem":
|
||||
|
@ -350,7 +350,7 @@ const outfitStateReducer = (apolloClient) => (baseState, action) => {
|
|||
// Don't include the removed item in items to reconsider!
|
||||
itemIdsToReconsider.filter((x) => x !== itemId),
|
||||
state,
|
||||
apolloClient
|
||||
apolloClient,
|
||||
);
|
||||
});
|
||||
case "setPose":
|
||||
|
@ -386,7 +386,7 @@ function useParseOutfitUrl() {
|
|||
// stable object!
|
||||
const memoizedOutfitState = React.useMemo(
|
||||
() => readOutfitStateFromSearchParams(searchParams),
|
||||
[searchParams]
|
||||
[searchParams],
|
||||
);
|
||||
|
||||
return memoizedOutfitState;
|
||||
|
@ -433,7 +433,7 @@ function getOutfitStateFromOutfitData(outfit) {
|
|||
// Whereas the items are more convenient to just leave as empty lists!
|
||||
wornItemIds: new Set((outfit.wornItems || []).map((item) => item.id)),
|
||||
closetedItemIds: new Set(
|
||||
(outfit.closetedItems || []).map((item) => item.id)
|
||||
(outfit.closetedItems || []).map((item) => item.id),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
@ -475,7 +475,7 @@ function findItemConflicts(itemIdToAdd, state, apolloClient) {
|
|||
return [];
|
||||
}
|
||||
const wornItems = Array.from(wornItemIds).map((id) =>
|
||||
items.find((i) => i.id === id)
|
||||
items.find((i) => i.id === id),
|
||||
);
|
||||
|
||||
const itemToAddZoneSets = getItemZones(itemToAdd);
|
||||
|
@ -491,11 +491,11 @@ function findItemConflicts(itemIdToAdd, state, apolloClient) {
|
|||
const itemsConflict =
|
||||
setsIntersect(
|
||||
itemToAddZoneSets.occupies,
|
||||
wornItemZoneSets.occupiesOrRestricts
|
||||
wornItemZoneSets.occupiesOrRestricts,
|
||||
) ||
|
||||
setsIntersect(
|
||||
wornItemZoneSets.occupies,
|
||||
itemToAddZoneSets.occupiesOrRestricts
|
||||
itemToAddZoneSets.occupiesOrRestricts,
|
||||
);
|
||||
|
||||
if (itemsConflict) {
|
||||
|
@ -536,7 +536,7 @@ function reconsiderItems(itemIdsToReconsider, state, apolloClient) {
|
|||
const conflictingIds = findItemConflicts(
|
||||
itemIdToReconsider,
|
||||
state,
|
||||
apolloClient
|
||||
apolloClient,
|
||||
);
|
||||
if (conflictingIds.length === 0) {
|
||||
state.wornItemIds.add(itemIdToReconsider);
|
||||
|
@ -576,19 +576,19 @@ function getZonesAndItems(itemsById, wornItemIds, closetedItemIds) {
|
|||
([zoneLabel, items]) => ({
|
||||
zoneLabel: zoneLabel,
|
||||
items: [...items].sort((a, b) => a.name.localeCompare(b.name)),
|
||||
})
|
||||
}),
|
||||
);
|
||||
zonesAndItems.sort((a, b) => a.zoneLabel.localeCompare(b.zoneLabel));
|
||||
|
||||
// As one last step, try to remove zone groups that aren't helpful.
|
||||
const groupsWithConflicts = zonesAndItems.filter(
|
||||
({ items }) => items.length > 1
|
||||
({ items }) => items.length > 1,
|
||||
);
|
||||
const itemIdsWithConflicts = new Set(
|
||||
groupsWithConflicts
|
||||
.map(({ items }) => items)
|
||||
.flat()
|
||||
.map((item) => item.id)
|
||||
.map((item) => item.id),
|
||||
);
|
||||
const itemIdsWeHaveSeen = new Set();
|
||||
zonesAndItems = zonesAndItems.filter(({ items }) => {
|
||||
|
|
|
@ -12,7 +12,7 @@ export function useSearchResults(
|
|||
query,
|
||||
outfitState,
|
||||
currentPageNumber,
|
||||
{ skip = false } = {}
|
||||
{ skip = false } = {},
|
||||
) {
|
||||
const { speciesId, colorId } = outfitState;
|
||||
|
||||
|
@ -125,7 +125,7 @@ export function useSearchResults(
|
|||
},
|
||||
// Return `numTotalItems` from the GQL cache while waiting for next page!
|
||||
returnPartialData: true,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const loading = debouncedQuery !== query || loadingGQL;
|
||||
|
|
|
@ -22,7 +22,7 @@ const typePolicies = {
|
|||
},
|
||||
items: (_, { args, toReference }) => {
|
||||
return args.ids.map((id) =>
|
||||
toReference({ __typename: "Item", id }, true)
|
||||
toReference({ __typename: "Item", id }, true),
|
||||
);
|
||||
},
|
||||
item: (_, { args, toReference }) => {
|
||||
|
@ -63,15 +63,15 @@ const typePolicies = {
|
|||
"[appearanceOn] seeking cached appearance",
|
||||
speciesId,
|
||||
colorId,
|
||||
readField("id")
|
||||
readField("id"),
|
||||
);
|
||||
const speciesStandardBodyId = readField(
|
||||
"standardBodyId",
|
||||
toReference({ __typename: "Species", id: speciesId })
|
||||
toReference({ __typename: "Species", id: speciesId }),
|
||||
);
|
||||
const colorIsStandard = readField(
|
||||
"isStandard",
|
||||
toReference({ __typename: "Color", id: colorId })
|
||||
toReference({ __typename: "Color", id: colorId }),
|
||||
);
|
||||
if (speciesStandardBodyId == null || colorIsStandard == null) {
|
||||
// We haven't loaded all the species/colors into cache yet. We might
|
||||
|
@ -86,7 +86,7 @@ const typePolicies = {
|
|||
const itemId = readField("id");
|
||||
console.debug(
|
||||
"[appearanceOn] standard color, will read:",
|
||||
`item-${itemId}-body-${speciesStandardBodyId}`
|
||||
`item-${itemId}-body-${speciesStandardBodyId}`,
|
||||
);
|
||||
return toReference({
|
||||
__typename: "ItemAppearance",
|
||||
|
@ -121,7 +121,7 @@ const typePolicies = {
|
|||
}
|
||||
|
||||
const theyOwnThisItem = itemsTheyOwn.some(
|
||||
(itemRef) => readField("id", itemRef) === thisItemId
|
||||
(itemRef) => readField("id", itemRef) === thisItemId,
|
||||
);
|
||||
return theyOwnThisItem;
|
||||
},
|
||||
|
@ -144,7 +144,7 @@ const typePolicies = {
|
|||
}
|
||||
|
||||
const theyWantThisItem = itemsTheyWant.some(
|
||||
(itemRef) => readField("id", itemRef) === thisItemId
|
||||
(itemRef) => readField("id", itemRef) === thisItemId,
|
||||
);
|
||||
return theyWantThisItem;
|
||||
},
|
||||
|
@ -218,7 +218,7 @@ const buildLink = (getAuth0) =>
|
|||
.concat(
|
||||
createPersistedQueryLink({
|
||||
useGETForHashedQueries: true,
|
||||
})
|
||||
}),
|
||||
)
|
||||
.concat(httpLink);
|
||||
|
||||
|
|
|
@ -140,7 +140,7 @@ export function layerUsesHTML5(layer) {
|
|||
layer.canvasMovieLibraryUrl ||
|
||||
// If this glitch is applied, then `svgUrl` will be null, but there's still
|
||||
// an HTML5 manifest that the official player can render.
|
||||
(layer.knownGlitches || []).includes("OFFICIAL_SVG_IS_INCORRECT")
|
||||
(layer.knownGlitches || []).includes("OFFICIAL_SVG_IS_INCORRECT"),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -109,12 +109,12 @@ export function ItemThumbnail({
|
|||
|
||||
const borderColor = useColorModeValue(
|
||||
theme.colors.green["700"],
|
||||
"transparent"
|
||||
"transparent",
|
||||
);
|
||||
|
||||
const focusBorderColor = useColorModeValue(
|
||||
theme.colors.green["600"],
|
||||
"transparent"
|
||||
"transparent",
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -233,7 +233,7 @@ export function ItemBadgeList({ children, ...props }) {
|
|||
<Wrap spacing="2" opacity="0.7" {...props}>
|
||||
{React.Children.map(
|
||||
children,
|
||||
(badge) => badge && <WrapItem>{badge}</WrapItem>
|
||||
(badge) => badge && <WrapItem>{badge}</WrapItem>,
|
||||
)}
|
||||
</Wrap>
|
||||
);
|
||||
|
@ -316,7 +316,7 @@ export const ItemKindBadge = React.forwardRef(
|
|||
} else {
|
||||
return <NpBadge ref={ref} isEditButton={isEditButton} {...props} />;
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export function YouOwnThisBadge({ variant = "long" }) {
|
||||
|
|
|
@ -209,7 +209,7 @@ function OutfitMovieLayer({
|
|||
const roundedFps = Math.round(fps * 100) / 100;
|
||||
|
||||
console.debug(
|
||||
`[OutfitMovieLayer] FPS: ${roundedFps} (Target: ${targetFps}) (${libraryUrl})`
|
||||
`[OutfitMovieLayer] FPS: ${roundedFps} (Target: ${targetFps}) (${libraryUrl})`,
|
||||
);
|
||||
|
||||
if (onLowFps && fps < 2) {
|
||||
|
@ -328,7 +328,7 @@ export function loadMovieLibrary(librarySrc, { preferArchive = false } = {}) {
|
|||
|
||||
// Then, load the script tag. (Make sure we set it up to be cancelable!)
|
||||
const scriptPromise = loadScriptTag(
|
||||
safeImageUrl(librarySrc, { preferArchive })
|
||||
safeImageUrl(librarySrc, { preferArchive }),
|
||||
);
|
||||
cancelableResourcePromises.push(scriptPromise);
|
||||
await scriptPromise;
|
||||
|
@ -350,16 +350,16 @@ export function loadMovieLibrary(librarySrc, { preferArchive = false } = {}) {
|
|||
// the race anymore? But fingers crossed!
|
||||
if (Object.keys(window.AdobeAn?.compositions || {}).length === 0) {
|
||||
throw new Error(
|
||||
`Movie library ${librarySrc} did not add a composition to window.AdobeAn.compositions.`
|
||||
`Movie library ${librarySrc} did not add a composition to window.AdobeAn.compositions.`,
|
||||
);
|
||||
}
|
||||
const [compositionId, composition] = Object.entries(
|
||||
window.AdobeAn.compositions
|
||||
window.AdobeAn.compositions,
|
||||
)[0];
|
||||
if (Object.keys(window.AdobeAn.compositions).length > 1) {
|
||||
console.warn(
|
||||
`Grabbing composition ${compositionId}, but there are >1 here: `,
|
||||
Object.keys(window.AdobeAn.compositions).length
|
||||
Object.keys(window.AdobeAn.compositions).length,
|
||||
);
|
||||
}
|
||||
delete window.AdobeAn.compositions[compositionId];
|
||||
|
@ -380,7 +380,7 @@ export function loadMovieLibrary(librarySrc, { preferArchive = false } = {}) {
|
|||
crossOrigin: "anonymous",
|
||||
preferArchive,
|
||||
}),
|
||||
])
|
||||
]),
|
||||
);
|
||||
|
||||
// Wait for the images, and make sure they're cancelable while we do.
|
||||
|
@ -440,8 +440,8 @@ export function buildMovieClip(library, libraryUrl) {
|
|||
} catch (e) {
|
||||
throw new Error(
|
||||
`Movie libraryUrl ${JSON.stringify(
|
||||
libraryUrl
|
||||
)} did not match expected format: ${e.message}`
|
||||
libraryUrl,
|
||||
)} did not match expected format: ${e.message}`,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -449,7 +449,7 @@ export function buildMovieClip(library, libraryUrl) {
|
|||
if (!LibraryMovieClipConstructor) {
|
||||
throw new Error(
|
||||
`Expected JS movie library ${libraryUrl} to contain a constructor ` +
|
||||
`named ${constructorName}, but it did not: ${Object.keys(library)}`
|
||||
`named ${constructorName}, but it did not: ${Object.keys(library)}`,
|
||||
);
|
||||
}
|
||||
const movieClip = new LibraryMovieClipConstructor();
|
||||
|
|
|
@ -111,7 +111,7 @@ export function useOutfitPreview({
|
|||
});
|
||||
}
|
||||
},
|
||||
[setIsPaused, toast]
|
||||
[setIsPaused, toast],
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
|
@ -184,7 +184,7 @@ export function OutfitLayers({
|
|||
setLoadingDelayHasPassed(false);
|
||||
const t = setTimeout(
|
||||
() => setLoadingDelayHasPassed(true),
|
||||
loadingDelayMs
|
||||
loadingDelayMs,
|
||||
);
|
||||
return () => clearTimeout(t);
|
||||
}
|
||||
|
@ -203,8 +203,8 @@ export function OutfitLayers({
|
|||
Math.min(
|
||||
containerRef.current.offsetWidth,
|
||||
containerRef.current.offsetHeight,
|
||||
600
|
||||
)
|
||||
600,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -283,7 +283,7 @@ export function OutfitLayers({
|
|||
as="img"
|
||||
src={safeImageUrl(
|
||||
getBestImageUrlForLayer(layer, { hiResMode }),
|
||||
{ preferArchive }
|
||||
{ preferArchive },
|
||||
)}
|
||||
alt=""
|
||||
objectFit="contain"
|
||||
|
@ -397,7 +397,7 @@ export function usePreloadLayers(layers) {
|
|||
for (const layer of layers) {
|
||||
const imageAssetPromise = loadImage(
|
||||
getBestImageUrlForLayer(layer, { hiResMode }),
|
||||
{ preferArchive }
|
||||
{ preferArchive },
|
||||
);
|
||||
imageAssetPromises.push(imageAssetPromise);
|
||||
|
||||
|
@ -407,7 +407,7 @@ export function usePreloadLayers(layers) {
|
|||
// placeholder, which should usually be noticeably faster!
|
||||
const movieLibraryPromise = loadMovieLibrary(
|
||||
layer.canvasMovieLibraryUrl,
|
||||
{ preferArchive }
|
||||
{ preferArchive },
|
||||
);
|
||||
const movieAssetPromise = movieLibraryPromise.then((library) => ({
|
||||
library,
|
||||
|
@ -420,7 +420,7 @@ export function usePreloadLayers(layers) {
|
|||
// The minimal asset for the movie case is *either* the image *or*
|
||||
// the movie, because we can start rendering when either is ready.
|
||||
minimalAssetPromises.push(
|
||||
Promise.any([imageAssetPromise, movieAssetPromise])
|
||||
Promise.any([imageAssetPromise, movieAssetPromise]),
|
||||
);
|
||||
} else {
|
||||
minimalAssetPromises.push(imageAssetPromise);
|
||||
|
@ -458,13 +458,13 @@ export function usePreloadLayers(layers) {
|
|||
}
|
||||
|
||||
setLayersHaveAnimations(
|
||||
(alreadyHasAnimations) => alreadyHasAnimations || assetHasAnimations
|
||||
(alreadyHasAnimations) => alreadyHasAnimations || assetHasAnimations,
|
||||
);
|
||||
};
|
||||
movieAssetPromises.forEach((p) =>
|
||||
p.then(checkHasAnimations).catch((e) => {
|
||||
console.error(`Error preloading movie library ${p.libraryUrl}:`, e);
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
return () => {
|
||||
|
|
|
@ -89,14 +89,14 @@ export function useRouterPagination(totalCount, numPerPage) {
|
|||
return newParams;
|
||||
});
|
||||
},
|
||||
[query, numPerPage]
|
||||
[query, numPerPage],
|
||||
);
|
||||
|
||||
const goToPageNumber = React.useCallback(
|
||||
(newPageNumber) => {
|
||||
pushHistory(buildPageUrl(newPageNumber));
|
||||
},
|
||||
[buildPageUrl, pushHistory]
|
||||
[buildPageUrl, pushHistory],
|
||||
);
|
||||
|
||||
return {
|
||||
|
@ -125,7 +125,7 @@ function PageNumberSelect({
|
|||
|
||||
const handleChange = React.useCallback(
|
||||
(e) => onChange(Number(e.target.value)),
|
||||
[onChange]
|
||||
[onChange],
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -110,8 +110,8 @@ function SpeciesColorPicker({
|
|||
new Error(
|
||||
`Assertion error in SpeciesColorPicker: Entered an invalid state, ` +
|
||||
`with prop stateMustAlwaysBeValid: speciesId=${speciesId}, ` +
|
||||
`colorId=${newColorId}.`
|
||||
)
|
||||
`colorId=${newColorId}.`,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -146,8 +146,8 @@ function SpeciesColorPicker({
|
|||
new Error(
|
||||
`Assertion error in SpeciesColorPicker: species not found. ` +
|
||||
`speciesId=${speciesId}, newSpeciesId=${newSpeciesId}, ` +
|
||||
`colorId=${colorId}.`
|
||||
)
|
||||
`colorId=${colorId}.`,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -187,7 +187,8 @@ function SpeciesColorPicker({
|
|||
let visibleColors = allColors;
|
||||
if (stateMustAlwaysBeValid && valids && speciesId) {
|
||||
visibleColors = visibleColors.filter(
|
||||
(c) => getValidPoses(valids, speciesId, c.id).size > 0 || c.id === colorId
|
||||
(c) =>
|
||||
getValidPoses(valids, speciesId, c.id).size > 0 || c.id === colorId,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -350,7 +351,7 @@ export function useAllValidPetPoses() {
|
|||
responseType: "arrayBuffer",
|
||||
// If we already have globally-cached valids, skip the request.
|
||||
skip: cachedResponseForAllValidPetPoses != null,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Use the globally-cached response if we have one, or await the network
|
||||
|
@ -360,7 +361,7 @@ export function useAllValidPetPoses() {
|
|||
|
||||
const valids = React.useMemo(
|
||||
() => validsBuffer && new DataView(validsBuffer),
|
||||
[validsBuffer]
|
||||
[validsBuffer],
|
||||
);
|
||||
|
||||
// Once a network response comes in, save it as the globally-cached response.
|
||||
|
@ -388,8 +389,8 @@ function getPairByte(valids, speciesId, colorId) {
|
|||
} catch (e) {
|
||||
logAndCapture(
|
||||
new Error(
|
||||
`Error loading valid poses for species=${speciesId}, color=${colorId}: ${e.message}`
|
||||
)
|
||||
`Error loading valid poses for species=${speciesId}, color=${colorId}: ${e.message}`,
|
||||
),
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -185,7 +185,7 @@ function ItemThumbnail({ item, tradeMatchingMode }) {
|
|||
|
||||
const thumbnailShadowColor = useColorModeValue(
|
||||
`${kindColorScheme}.200`,
|
||||
`${kindColorScheme}.600`
|
||||
`${kindColorScheme}.600`,
|
||||
);
|
||||
const thumbnailShadowColorValue = useToken("colors", thumbnailShadowColor);
|
||||
const mdRadiusValue = useToken("radii", "md");
|
||||
|
@ -318,11 +318,11 @@ function ItemThumbnail({ item, tradeMatchingMode }) {
|
|||
function ItemOwnsWantsBadge({ colorScheme, children, label }) {
|
||||
const badgeBackground = useColorModeValue(
|
||||
`${colorScheme}.100`,
|
||||
`${colorScheme}.500`
|
||||
`${colorScheme}.500`,
|
||||
);
|
||||
const badgeColor = useColorModeValue(
|
||||
`${colorScheme}.500`,
|
||||
`${colorScheme}.100`
|
||||
`${colorScheme}.100`,
|
||||
);
|
||||
|
||||
const [badgeBackgroundValue, badgeColorValue] = useToken("colors", [
|
||||
|
@ -369,11 +369,11 @@ function ItemOwnsWantsBadge({ colorScheme, children, label }) {
|
|||
function ItemThumbnailKindBadge({ colorScheme, children }) {
|
||||
const badgeBackground = useColorModeValue(
|
||||
`${colorScheme}.100`,
|
||||
`${colorScheme}.500`
|
||||
`${colorScheme}.500`,
|
||||
);
|
||||
const badgeColor = useColorModeValue(
|
||||
`${colorScheme}.500`,
|
||||
`${colorScheme}.100`
|
||||
`${colorScheme}.100`,
|
||||
);
|
||||
|
||||
const [badgeBackgroundValue, badgeColorValue] = useToken("colors", [
|
||||
|
|
|
@ -20,10 +20,10 @@ function getVisibleLayers(petAppearance, itemAppearances) {
|
|||
validItemAppearances
|
||||
.map((a) => a.restrictedZones)
|
||||
.flat()
|
||||
.map((z) => z.id)
|
||||
.map((z) => z.id),
|
||||
);
|
||||
const petRestrictedZoneIds = new Set(
|
||||
petAppearance.restrictedZones.map((z) => z.id)
|
||||
petAppearance.restrictedZones.map((z) => z.id),
|
||||
);
|
||||
|
||||
const visibleLayers = allLayers.filter((layer) => {
|
||||
|
|
|
@ -96,7 +96,7 @@ function useCurrentUserViaDb({ isEnabled }) {
|
|||
// something is wrong and they need to reach out.
|
||||
console.error("[useCurrentUser] Couldn't get current user:", error);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (!isEnabled) {
|
||||
|
@ -159,7 +159,7 @@ export function useLogout() {
|
|||
}
|
||||
cache.gc();
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const logoutWithDb = () => {
|
||||
|
@ -191,13 +191,13 @@ export function useAuthModeFeatureFlag() {
|
|||
// setting this override value to auth0 on everyone's devices 😅)
|
||||
let [savedValue, setSavedValue] = useLocalStorage(
|
||||
"DTIAuthModeFeatureFlag",
|
||||
null
|
||||
null,
|
||||
);
|
||||
|
||||
if (!["auth0", "db", null].includes(savedValue)) {
|
||||
console.warn(
|
||||
`Unexpected DTIAuthModeFeatureFlag value: %o. Ignoring.`,
|
||||
savedValue
|
||||
savedValue,
|
||||
);
|
||||
savedValue = null;
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ export function getAuthModeFeatureFlag() {
|
|||
if (!["auth0", "db", null].includes(savedValue)) {
|
||||
console.warn(
|
||||
`Unexpected DTIAuthModeFeatureFlag value: %o. Ignoring.`,
|
||||
savedValue
|
||||
savedValue,
|
||||
);
|
||||
savedValue = null;
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ export default function useOutfitAppearance(outfitState) {
|
|||
speciesId == null ||
|
||||
colorId == null ||
|
||||
(pose == null && appearanceId == null),
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const {
|
||||
|
@ -99,18 +99,18 @@ export default function useOutfitAppearance(outfitState) {
|
|||
wornItemIds,
|
||||
},
|
||||
skip: speciesId == null || colorId == null || wornItemIds.length === 0,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const petAppearance = data1?.petAppearance;
|
||||
const items = data2?.items;
|
||||
const itemAppearances = React.useMemo(
|
||||
() => (items || []).map((i) => i.appearance),
|
||||
[items]
|
||||
[items],
|
||||
);
|
||||
const visibleLayers = React.useMemo(
|
||||
() => getVisibleLayers(petAppearance, itemAppearances),
|
||||
[petAppearance, itemAppearances]
|
||||
[petAppearance, itemAppearances],
|
||||
);
|
||||
|
||||
const bodyId = petAppearance?.bodyId;
|
||||
|
|
|
@ -7,7 +7,7 @@ import { useLocalStorage } from "../util";
|
|||
function usePreferArchive() {
|
||||
const [preferArchiveSavedValue, setPreferArchive] = useLocalStorage(
|
||||
"DTIPreferArchive",
|
||||
null
|
||||
null,
|
||||
);
|
||||
|
||||
// Oct 13 2022: I might default this back to on again if the lag gets
|
||||
|
|
|
@ -117,7 +117,7 @@ export function useCommonStyles() {
|
|||
*/
|
||||
export function safeImageUrl(
|
||||
urlString,
|
||||
{ crossOrigin = null, preferArchive = false } = {}
|
||||
{ crossOrigin = null, preferArchive = false } = {},
|
||||
) {
|
||||
if (urlString == null) {
|
||||
return urlString;
|
||||
|
@ -133,13 +133,13 @@ export function safeImageUrl(
|
|||
// So, we provide "http://images.neopets.com" as the base URL when
|
||||
// parsing. Most URLs are absolute and will ignore it, but relative URLs
|
||||
// will resolve relative to that base.
|
||||
"http://images.neopets.com"
|
||||
"http://images.neopets.com",
|
||||
);
|
||||
} catch (e) {
|
||||
logAndCapture(
|
||||
new Error(
|
||||
`safeImageUrl could not parse URL: ${urlString}. Returning a placeholder.`
|
||||
)
|
||||
`safeImageUrl could not parse URL: ${urlString}. Returning a placeholder.`,
|
||||
),
|
||||
);
|
||||
return "https://impress-2020.openneo.net/__error__URL-was-not-parseable__";
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ export function safeImageUrl(
|
|||
if (preferArchive) {
|
||||
const archiveUrl = new URL(
|
||||
`/api/readFromArchive`,
|
||||
window.location.origin
|
||||
window.location.origin,
|
||||
);
|
||||
archiveUrl.search = new URLSearchParams({ url: url.toString() });
|
||||
url = archiveUrl;
|
||||
|
@ -175,8 +175,8 @@ export function safeImageUrl(
|
|||
logAndCapture(
|
||||
new Error(
|
||||
`safeImageUrl was provided an unsafe URL, but we don't know how to ` +
|
||||
`upgrade it to HTTPS: ${urlString}. Returning a placeholder.`
|
||||
)
|
||||
`upgrade it to HTTPS: ${urlString}. Returning a placeholder.`,
|
||||
),
|
||||
);
|
||||
return "https://impress-2020.openneo.net/__error__URL-was-not-HTTPS__";
|
||||
}
|
||||
|
@ -197,11 +197,11 @@ export function safeImageUrl(
|
|||
export function useDebounce(
|
||||
value,
|
||||
delay,
|
||||
{ waitForFirstPause = false, initialValue = null, forceReset = null } = {}
|
||||
{ waitForFirstPause = false, initialValue = null, forceReset = null } = {},
|
||||
) {
|
||||
// State and setters for debounced value
|
||||
const [debouncedValue, setDebouncedValue] = React.useState(
|
||||
waitForFirstPause ? initialValue : value
|
||||
waitForFirstPause ? initialValue : value,
|
||||
);
|
||||
|
||||
React.useEffect(
|
||||
|
@ -218,7 +218,7 @@ export function useDebounce(
|
|||
clearTimeout(handler);
|
||||
};
|
||||
},
|
||||
[value, delay] // Only re-call effect if value or delay changes
|
||||
[value, delay], // Only re-call effect if value or delay changes
|
||||
);
|
||||
|
||||
// The `forceReset` option helps us decide whether to set the value
|
||||
|
@ -322,7 +322,7 @@ export function useLocalStorage(key, initialValue) {
|
|||
console.error(error);
|
||||
}
|
||||
},
|
||||
[key]
|
||||
[key],
|
||||
);
|
||||
|
||||
const reloadValue = React.useCallback(() => {
|
||||
|
@ -349,7 +349,7 @@ export function useLocalStorage(key, initialValue) {
|
|||
|
||||
export function loadImage(
|
||||
rawSrc,
|
||||
{ crossOrigin = null, preferArchive = false } = {}
|
||||
{ crossOrigin = null, preferArchive = false } = {},
|
||||
) {
|
||||
const src = safeImageUrl(rawSrc, { crossOrigin, preferArchive });
|
||||
const image = new Image();
|
||||
|
@ -403,7 +403,7 @@ export function loadable(load, options) {
|
|||
// Return a component that renders nothing, while we reload!
|
||||
return () => null;
|
||||
}),
|
||||
options
|
||||
options,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue