add own/want badges to items in wardrobe

This commit is contained in:
Emi Matchu 2020-09-12 20:02:56 -07:00
parent dcf2ec6a26
commit 0b724f7509
6 changed files with 133 additions and 8 deletions

View file

@ -25,6 +25,8 @@ import {
ItemBadgeTooltip, ItemBadgeTooltip,
NcBadge, NcBadge,
NpBadge, NpBadge,
YouOwnThisBadge,
YouWantThisBadge,
} from "../components/ItemCard"; } from "../components/ItemCard";
import SupportOnly from "./support/SupportOnly"; import SupportOnly from "./support/SupportOnly";
@ -222,6 +224,8 @@ function ItemBadges({ item }) {
// than try to line things up like a table. // than try to line things up like a table.
<NpBadge /> <NpBadge />
)} )}
{item.currentUserOwnsThis && <YouOwnThisBadge variant="short" />}
{item.currentUserWantsThis && <YouWantThisBadge variant="short" />}
{occupiedZoneLabels.map((zoneLabel) => ( {occupiedZoneLabels.map((zoneLabel) => (
<ZoneBadge key={zoneLabel} variant="occupies" zoneLabel={zoneLabel} /> <ZoneBadge key={zoneLabel} variant="occupies" zoneLabel={zoneLabel} />
))} ))}

View file

@ -274,6 +274,8 @@ function useSearchResults(query, outfitState) {
name name
thumbnailUrl thumbnailUrl
isNc isNc
currentUserOwnsThis
currentUserWantsThis
appearanceOn(speciesId: $speciesId, colorId: $colorId) { appearanceOn(speciesId: $speciesId, colorId: $colorId) {
# This enables us to quickly show the item when the user clicks it! # This enables us to quickly show the item when the user clicks it!

View file

@ -38,6 +38,8 @@ function useOutfitState() {
name name
thumbnailUrl thumbnailUrl
isNc isNc
currentUserOwnsThis
currentUserWantsThis
appearanceOn(speciesId: $speciesId, colorId: $colorId) { appearanceOn(speciesId: $speciesId, colorId: $colorId) {
# This enables us to quickly show the item when the user clicks it! # This enables us to quickly show the item when the user clicks it!

View file

@ -9,7 +9,7 @@ import {
useColorModeValue, useColorModeValue,
useTheme, useTheme,
} from "@chakra-ui/core"; } from "@chakra-ui/core";
import { StarIcon } from "@chakra-ui/icons"; import { CheckIcon, StarIcon } from "@chakra-ui/icons";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { safeImageUrl } from "../util"; import { safeImageUrl } from "../util";
@ -238,20 +238,22 @@ export function NpBadge() {
); );
} }
export function YouOwnThisBadge() { export function YouOwnThisBadge({ variant = "long" }) {
return ( return (
<Badge colorScheme="yellow" display="flex" alignItems="center"> <Badge colorScheme="green" display="flex" alignItems="center">
<StarIcon aria-label="Star" marginRight="1" /> <CheckIcon aria-label="Star" marginRight="1" />
You own this! {variant === "long" && <>You own this!</>}
{variant === "short" && <>Own</>}
</Badge> </Badge>
); );
} }
export function YouWantThisBadge() { export function YouWantThisBadge({ variant = "long" }) {
return ( return (
<Badge colorScheme="blue" display="flex" alignItems="center"> <Badge colorScheme="blue" display="flex" alignItems="center">
<StarIcon aria-label="Star" marginRight="1" /> <StarIcon aria-label="Star" marginRight="1" />
You want this! {variant === "long" && <>You want this!</>}
{variant === "short" && <>Want</>}
</Badge> </Badge>
); );
} }

View file

@ -1,5 +1,5 @@
const gql = require("graphql-tag"); const gql = require("graphql-tag");
const { query, getDbCalls } = require("./setup.js"); const { query, getDbCalls, logInAsTestUser } = require("./setup.js");
describe("Item", () => { describe("Item", () => {
it("loads metadata", async () => { it("loads metadata", async () => {
@ -288,6 +288,98 @@ describe("Item", () => {
`); `);
}); });
it("loads whether we own/want items", async () => {
await logInAsTestUser();
const res = await query({
query: gql`
query {
items(ids: ["38913", "39945", "39948"]) {
id
currentUserOwnsThis
currentUserWantsThis
}
}
`,
});
expect(res).toHaveNoErrors();
expect(res.data).toMatchInlineSnapshot(`
Object {
"items": Array [
Object {
"currentUserOwnsThis": false,
"currentUserWantsThis": false,
"id": "38913",
},
Object {
"currentUserOwnsThis": false,
"currentUserWantsThis": true,
"id": "39945",
},
Object {
"currentUserOwnsThis": true,
"currentUserWantsThis": false,
"id": "39948",
},
],
}
`);
expect(getDbCalls()).toMatchInlineSnapshot(`
Array [
Array [
"SELECT closet_hangers.*, item_translations.name as item_name FROM closet_hangers
INNER JOIN items ON items.id = closet_hangers.item_id
INNER JOIN item_translations ON
item_translations.item_id = items.id AND locale = \\"en\\"
WHERE user_id IN (?)
ORDER BY item_name",
Array [
"44743",
],
],
]
`);
});
it("does not own/want items if not logged in", async () => {
const res = await query({
query: gql`
query {
items(ids: ["38913", "39945", "39948"]) {
id
currentUserOwnsThis
currentUserWantsThis
}
}
`,
});
expect(res).toHaveNoErrors();
expect(res.data).toMatchInlineSnapshot(`
Object {
"items": Array [
Object {
"currentUserOwnsThis": false,
"currentUserWantsThis": false,
"id": "38913",
},
Object {
"currentUserOwnsThis": false,
"currentUserWantsThis": false,
"id": "39945",
},
Object {
"currentUserOwnsThis": false,
"currentUserWantsThis": false,
"id": "39948",
},
],
}
`);
expect(getDbCalls()).toMatchInlineSnapshot(`Array []`);
});
it("loads items that need models", async () => { it("loads items that need models", async () => {
jest.setTimeout(20000); jest.setTimeout(20000);

View file

@ -10,6 +10,9 @@ const typeDefs = gql`
rarityIndex: Int! rarityIndex: Int!
isNc: Boolean! isNc: Boolean!
currentUserOwnsThis: Boolean!
currentUserWantsThis: Boolean!
# How this item appears on the given species/color combo. If it does not # How this item appears on the given species/color combo. If it does not
# fit the pet, we'll return an empty ItemAppearance with no layers. # fit the pet, we'll return an empty ItemAppearance with no layers.
appearanceOn(speciesId: ID!, colorId: ID!): ItemAppearance! appearanceOn(speciesId: ID!, colorId: ID!): ItemAppearance!
@ -91,6 +94,26 @@ const resolvers = {
const item = await itemLoader.load(id); const item = await itemLoader.load(id);
return item.rarityIndex === 500 || item.rarityIndex === 0; return item.rarityIndex === 500 || item.rarityIndex === 0;
}, },
currentUserOwnsThis: async (
{ id },
_,
{ currentUserId, userClosetHangersLoader }
) => {
if (currentUserId == null) return false;
const closetHangers = await userClosetHangersLoader.load(currentUserId);
return closetHangers.some((h) => h.itemId === id && h.owned);
},
currentUserWantsThis: async (
{ id },
_,
{ currentUserId, userClosetHangersLoader }
) => {
if (currentUserId == null) return false;
const closetHangers = await userClosetHangersLoader.load(currentUserId);
return closetHangers.some((h) => h.itemId === id && !h.owned);
},
appearanceOn: async ( appearanceOn: async (
{ id }, { id },
{ speciesId, colorId }, { speciesId, colorId },