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,
|
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} />
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -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!
|
||||||
|
|
|
@ -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!
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 },
|
||||||
|
|
Loading…
Reference in a new issue