add own/want badges to items in wardrobe
This commit is contained in:
parent
dcf2ec6a26
commit
0b724f7509
6 changed files with 133 additions and 8 deletions
|
@ -25,6 +25,8 @@ import {
|
|||
ItemBadgeTooltip,
|
||||
NcBadge,
|
||||
NpBadge,
|
||||
YouOwnThisBadge,
|
||||
YouWantThisBadge,
|
||||
} from "../components/ItemCard";
|
||||
import SupportOnly from "./support/SupportOnly";
|
||||
|
||||
|
@ -222,6 +224,8 @@ function ItemBadges({ item }) {
|
|||
// than try to line things up like a table.
|
||||
<NpBadge />
|
||||
)}
|
||||
{item.currentUserOwnsThis && <YouOwnThisBadge variant="short" />}
|
||||
{item.currentUserWantsThis && <YouWantThisBadge variant="short" />}
|
||||
{occupiedZoneLabels.map((zoneLabel) => (
|
||||
<ZoneBadge key={zoneLabel} variant="occupies" zoneLabel={zoneLabel} />
|
||||
))}
|
||||
|
|
|
@ -274,6 +274,8 @@ function useSearchResults(query, outfitState) {
|
|||
name
|
||||
thumbnailUrl
|
||||
isNc
|
||||
currentUserOwnsThis
|
||||
currentUserWantsThis
|
||||
|
||||
appearanceOn(speciesId: $speciesId, colorId: $colorId) {
|
||||
# This enables us to quickly show the item when the user clicks it!
|
||||
|
|
|
@ -38,6 +38,8 @@ function useOutfitState() {
|
|||
name
|
||||
thumbnailUrl
|
||||
isNc
|
||||
currentUserOwnsThis
|
||||
currentUserWantsThis
|
||||
|
||||
appearanceOn(speciesId: $speciesId, colorId: $colorId) {
|
||||
# This enables us to quickly show the item when the user clicks it!
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
useColorModeValue,
|
||||
useTheme,
|
||||
} from "@chakra-ui/core";
|
||||
import { StarIcon } from "@chakra-ui/icons";
|
||||
import { CheckIcon, StarIcon } from "@chakra-ui/icons";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { safeImageUrl } from "../util";
|
||||
|
@ -238,20 +238,22 @@ export function NpBadge() {
|
|||
);
|
||||
}
|
||||
|
||||
export function YouOwnThisBadge() {
|
||||
export function YouOwnThisBadge({ variant = "long" }) {
|
||||
return (
|
||||
<Badge colorScheme="yellow" display="flex" alignItems="center">
|
||||
<StarIcon aria-label="Star" marginRight="1" />
|
||||
You own this!
|
||||
<Badge colorScheme="green" display="flex" alignItems="center">
|
||||
<CheckIcon aria-label="Star" marginRight="1" />
|
||||
{variant === "long" && <>You own this!</>}
|
||||
{variant === "short" && <>Own</>}
|
||||
</Badge>
|
||||
);
|
||||
}
|
||||
|
||||
export function YouWantThisBadge() {
|
||||
export function YouWantThisBadge({ variant = "long" }) {
|
||||
return (
|
||||
<Badge colorScheme="blue" display="flex" alignItems="center">
|
||||
<StarIcon aria-label="Star" marginRight="1" />
|
||||
You want this!
|
||||
{variant === "long" && <>You want this!</>}
|
||||
{variant === "short" && <>Want</>}
|
||||
</Badge>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const gql = require("graphql-tag");
|
||||
const { query, getDbCalls } = require("./setup.js");
|
||||
const { query, getDbCalls, logInAsTestUser } = require("./setup.js");
|
||||
|
||||
describe("Item", () => {
|
||||
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 () => {
|
||||
jest.setTimeout(20000);
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@ const typeDefs = gql`
|
|||
rarityIndex: Int!
|
||||
isNc: Boolean!
|
||||
|
||||
currentUserOwnsThis: Boolean!
|
||||
currentUserWantsThis: Boolean!
|
||||
|
||||
# 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.
|
||||
appearanceOn(speciesId: ID!, colorId: ID!): ItemAppearance!
|
||||
|
@ -91,6 +94,26 @@ const resolvers = {
|
|||
const item = await itemLoader.load(id);
|
||||
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 (
|
||||
{ id },
|
||||
{ speciesId, colorId },
|
||||
|
|
Loading…
Reference in a new issue