Add extra flair to trade matches

I refactor the hide-badge thing into 3 "trade matching modes". Then, the logic for whether to hide specific badges moves into the component, and we use that same flag to decide whether to show the big word "match"!
This commit is contained in:
Emi Matchu 2021-06-08 01:23:31 -07:00
parent b762e11331
commit a0be9942fb
2 changed files with 89 additions and 23 deletions

View file

@ -514,6 +514,20 @@ function ClosetList({ closetList, isCurrentUser, showHeading }) {
}); });
}; };
let tradeMatchingMode;
if (isCurrentUser) {
// On your own item list, it's not helpful to show your own trade matches!
tradeMatchingMode = "hide-all";
} else if (closetList.ownsOrWantsItems === "OWNS") {
tradeMatchingMode = "offering";
} else if (closetList.ownsOrWantsItems === "WANTS") {
tradeMatchingMode = "seeking";
} else {
throw new Error(
`unexpected ownsOrWantsItems value: ${closetList.ownsOrWantsItems}`
);
}
return ( return (
<Box id={anchorId}> <Box id={anchorId}>
<Flex align="center" wrap="wrap" marginBottom="2"> <Flex align="center" wrap="wrap" marginBottom="2">
@ -605,12 +619,7 @@ function ClosetList({ closetList, isCurrentUser, showHeading }) {
<ItemCard <ItemCard
item={item} item={item}
variant="grid" variant="grid"
// Owns/wants badges are great for trade list comparison... but tradeMatchingMode={tradeMatchingMode}
// we only show the relevant one for trade matching, and we
// hide them on your own list (because that would just be
// annoying!)
hideOwnsBadge={closetList.ownsOrWantsItems === "OWNS" || isCurrentUser}
hideWantsBadge={closetList.ownsOrWantsItems === "WANTS" || isCurrentUser}
/> />
</WrapItem> </WrapItem>
))} ))}

View file

@ -11,12 +11,7 @@ import { Link } from "react-router-dom";
import { safeImageUrl, useCommonStyles } from "../util"; import { safeImageUrl, useCommonStyles } from "../util";
import { CheckIcon, StarIcon } from "@chakra-ui/icons"; import { CheckIcon, StarIcon } from "@chakra-ui/icons";
function SquareItemCard({ function SquareItemCard({ item, tradeMatchingMode = null, ...props }) {
item,
hideOwnsBadge = false,
hideWantsBadge = false,
...props
}) {
const outlineShadowValue = useToken("shadows", "outline"); const outlineShadowValue = useToken("shadows", "outline");
return ( return (
@ -45,8 +40,7 @@ function SquareItemCard({
thumbnailImage={ thumbnailImage={
<ItemThumbnail <ItemThumbnail
item={item} item={item}
hideOwnsBadge={hideOwnsBadge} tradeMatchingMode={tradeMatchingMode}
hideWantsBadge={hideWantsBadge}
/> />
} }
/> />
@ -104,7 +98,7 @@ function SquareItemCardLayout({ name, thumbnailImage, minHeightNumLines = 2 }) {
); );
} }
function ItemThumbnail({ item, hideOwnsBadge, hideWantsBadge }) { function ItemThumbnail({ item, tradeMatchingMode }) {
const kindColorScheme = item.isNc ? "purple" : item.isPb ? "orange" : "gray"; const kindColorScheme = item.isNc ? "purple" : item.isPb ? "orange" : "gray";
const thumbnailShadowColor = useColorModeValue( const thumbnailShadowColor = useColorModeValue(
@ -114,6 +108,33 @@ function ItemThumbnail({ item, hideOwnsBadge, hideWantsBadge }) {
const thumbnailShadowColorValue = useToken("colors", thumbnailShadowColor); const thumbnailShadowColorValue = useToken("colors", thumbnailShadowColor);
const mdRadiusValue = useToken("radii", "md"); const mdRadiusValue = useToken("radii", "md");
// Normally, we just show the owns/wants badges depending on whether the
// current user owns/wants it. But, in a trade list, we use trade-matching
// mode instead: only show the badge if it represents a viable trade, and add
// some extra flair to it, too!
let showOwnsBadge;
let showWantsBadge;
let showTradeMatchFlair;
if (tradeMatchingMode == null) {
showOwnsBadge = item.currentUserOwnsThis;
showWantsBadge = item.currentUserWantsThis;
showTradeMatchFlair = false;
} else if (tradeMatchingMode === "offering") {
showOwnsBadge = false;
showWantsBadge = item.currentUserWantsThis;
showTradeMatchFlair = true;
} else if (tradeMatchingMode === "seeking") {
showOwnsBadge = item.currentUserOwnsThis;
showWantsBadge = false;
showTradeMatchFlair = true;
} else if (tradeMatchingMode === "hide-all") {
showOwnsBadge = false;
showWantsBadge = false;
showTradeMatchFlair = false;
} else {
throw new Error(`unexpected tradeMatchingMode ${tradeMatchingMode}`);
}
return ( return (
<ClassNames> <ClassNames>
{({ css }) => ( {({ css }) => (
@ -148,14 +169,48 @@ function ItemThumbnail({ item, hideOwnsBadge, hideWantsBadge }) {
gap: 2px; gap: 2px;
`} `}
> >
{!hideOwnsBadge && item.currentUserOwnsThis && ( {showOwnsBadge && (
<ItemOwnsWantsBadge colorScheme="green" label="You own this"> <ItemOwnsWantsBadge
colorScheme="green"
label={
showTradeMatchFlair
? "You own this, and they want it!"
: "You own this"
}
>
<CheckIcon /> <CheckIcon />
{showTradeMatchFlair && (
<div
className={css`
margin-left: 0.25em;
margin-right: 0.125rem;
`}
>
Match
</div>
)}
</ItemOwnsWantsBadge> </ItemOwnsWantsBadge>
)} )}
{!hideWantsBadge && item.currentUserWantsThis && ( {showWantsBadge && (
<ItemOwnsWantsBadge colorScheme="blue" label="You want this"> <ItemOwnsWantsBadge
colorScheme="blue"
label={
showTradeMatchFlair
? "You want this, and they own it!"
: "You want this"
}
>
<StarIcon /> <StarIcon />
{showTradeMatchFlair && (
<div
className={css`
margin-left: 0.25em;
margin-right: 0.125rem;
`}
>
Match
</div>
)}
</ItemOwnsWantsBadge> </ItemOwnsWantsBadge>
)} )}
</div> </div>
@ -200,19 +255,21 @@ function ItemOwnsWantsBadge({ colorScheme, children, label }) {
aria-label={label} aria-label={label}
title={label} title={label}
className={css` className={css`
border-radius: 100%; border-radius: 999px;
height: 16px; height: 16px;
width: 16px; min-width: 16px;
font-size: 14px; font-size: 14px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
box-shadow: 0 0 2px ${badgeBackgroundValue}; box-shadow: 0 0 2px ${badgeBackgroundValue};
/* Decrease the padding: I don't want to hit the edges, but I want
* to be a circle when possible! */
padding-left: 0.125rem;
padding-right: 0.125rem;
/* Copied from Chakra <Badge> */ /* Copied from Chakra <Badge> */
white-space: nowrap; white-space: nowrap;
vertical-align: middle; vertical-align: middle;
padding-left: 0.25rem;
padding-right: 0.25rem;
text-transform: uppercase; text-transform: uppercase;
font-size: 0.65rem; font-size: 0.65rem;
font-weight: 700; font-weight: 700;