include item lists in itemsTheyOwn

This adds the owned items to the user items page, and also means that owned items in lists will be tagged for the modeling page
This commit is contained in:
Emi Matchu 2020-09-11 21:23:14 -07:00
parent 0df57818e3
commit c0f0e5688c
4 changed files with 78 additions and 12 deletions

View file

@ -22,6 +22,7 @@ GRANT UPDATE ON swf_assets TO impress2020;
-- User data tables
GRANT SELECT ON closet_hangers TO impress2020;
GRANT SELECT ON closet_lists TO impress2020;
GRANT SELECT ON item_outfit_relationships TO impress2020;
GRANT SELECT ON outfits TO impress2020;
GRANT SELECT ON users TO impress2020;

View file

@ -507,6 +507,22 @@ const buildUserOwnedClosetHangersLoader = (db) =>
);
});
const buildUserClosetListsLoader = (db) =>
new DataLoader(async (userIds) => {
const qs = userIds.map((_) => "?").join(",");
const [rows, _] = await db.execute(
`SELECT * FROM closet_lists
WHERE user_id IN (${qs})
ORDER BY name`,
userIds
);
const entities = rows.map(normalizeRow);
return userIds.map((userId) =>
entities.filter((e) => e.userId === String(userId))
);
});
const buildZoneLoader = (db) => {
const zoneLoader = new DataLoader(async (ids) => {
const qs = ids.map((_) => "?").join(",");
@ -589,6 +605,7 @@ function buildLoaders(db) {
loaders.speciesTranslationLoader = buildSpeciesTranslationLoader(db);
loaders.userLoader = buildUserLoader(db);
loaders.userOwnedClosetHangersLoader = buildUserOwnedClosetHangersLoader(db);
loaders.userClosetListsLoader = buildUserClosetListsLoader(db);
loaders.zoneLoader = buildZoneLoader(db);
loaders.zoneTranslationLoader = buildZoneTranslationLoader(db);

View file

@ -148,6 +148,14 @@ describe("User", () => {
"id": "49026",
"name": "Abominable Snowman Hat",
},
Object {
"id": "39948",
"name": "Altador Cup Background - Lost Desert",
},
Object {
"id": "39955",
"name": "Altador Cup Background - Virtupets",
},
Object {
"id": "40319",
"name": "Blue Jelly Tiara",
@ -176,6 +184,14 @@ describe("User", () => {
"44743",
],
],
Array [
"SELECT * FROM closet_lists
WHERE user_id IN (?)
ORDER BY name",
Array [
"44743",
],
],
]
`);
});
@ -201,7 +217,12 @@ describe("User", () => {
Object {
"user": Object {
"id": "44743",
"itemsTheyOwn": Array [],
"itemsTheyOwn": Array [
Object {
"id": "39955",
"name": "Altador Cup Background - Virtupets",
},
],
"username": "dti-test",
},
}
@ -214,6 +235,25 @@ describe("User", () => {
"44743",
],
],
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 (?) AND owned = 1
ORDER BY item_name",
Array [
"44743",
],
],
Array [
"SELECT * FROM closet_lists
WHERE user_id IN (?)
ORDER BY name",
Array [
"44743",
],
],
]
`);
});

View file

@ -22,21 +22,29 @@ const resolvers = {
itemsTheyOwn: async (
{ id },
_,
{ currentUserId, userLoader, userOwnedClosetHangersLoader }
) => {
const user = await userLoader.load(id);
const hangersAreVisible =
user.ownedClosetHangersVisibility >= 2 || user.id === currentUserId;
if (!hangersAreVisible) {
return [];
{
currentUserId,
userClosetListsLoader,
userLoader,
userOwnedClosetHangersLoader,
}
) => {
const [allClosetHangers, closetLists, user] = await Promise.all([
userOwnedClosetHangersLoader.load(id),
userClosetListsLoader.load(id),
userLoader.load(id),
]);
const allClosetHangers = await userOwnedClosetHangersLoader.load(id);
const closetHangersWithNoList = allClosetHangers.filter(
(h) => h.listId == null
const closetListsById = new Map(closetLists.map((l) => [l.id, l]));
const visibleClosetHangers = allClosetHangers.filter(
(h) =>
user.id === currentUserId ||
(h.listId == null && user.ownedClosetHangersVisibility >= 1) ||
(h.listId != null && closetListsById.get(h.listId).visibility >= 1)
);
const items = closetHangersWithNoList.map((h) => ({
const items = visibleClosetHangers.map((h) => ({
id: h.itemId,
// We get this for the ORDER BY clause anyway - may as well include it
// here to avoid an extra lookup!