diff --git a/src/app/ItemsPage.js b/src/app/ItemsPage.js
index d8c508a..d6e101c 100644
--- a/src/app/ItemsPage.js
+++ b/src/app/ItemsPage.js
@@ -24,12 +24,20 @@ function ItemsPage() {
user(id: $userId) {
id
username
+
itemsTheyOwn {
id
isNc
name
thumbnailUrl
}
+
+ itemsTheyWant {
+ id
+ isNc
+ name
+ thumbnailUrl
+ }
}
}
`,
@@ -66,6 +74,23 @@ function ItemsPage() {
/>
))}
+
+
+ {isCurrentUser ? "Items you want" : `Items ${data.user.username} wants`}
+
+
+ {data.user.itemsTheyWant.map((item) => (
+
+ {item.isNc ? : }
+
+ }
+ />
+ ))}
+
);
}
diff --git a/src/server/loaders.js b/src/server/loaders.js
index 7c1bce4..471de7a 100644
--- a/src/server/loaders.js
+++ b/src/server/loaders.js
@@ -488,7 +488,7 @@ const buildUserLoader = (db) =>
);
});
-const buildUserOwnedClosetHangersLoader = (db) =>
+const buildUserClosetHangersLoader = (db) =>
new DataLoader(async (userIds) => {
const qs = userIds.map((_) => "?").join(",");
const [rows, _] = await db.execute(
@@ -496,7 +496,7 @@ const buildUserOwnedClosetHangersLoader = (db) =>
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 (${qs}) AND owned = 1
+ WHERE user_id IN (${qs})
ORDER BY item_name`,
userIds
);
@@ -604,7 +604,7 @@ function buildLoaders(db) {
loaders.speciesLoader = buildSpeciesLoader(db);
loaders.speciesTranslationLoader = buildSpeciesTranslationLoader(db);
loaders.userLoader = buildUserLoader(db);
- loaders.userOwnedClosetHangersLoader = buildUserOwnedClosetHangersLoader(db);
+ loaders.userClosetHangersLoader = buildUserClosetHangersLoader(db);
loaders.userClosetListsLoader = buildUserClosetListsLoader(db);
loaders.zoneLoader = buildZoneLoader(db);
loaders.zoneTranslationLoader = buildZoneTranslationLoader(db);
diff --git a/src/server/query-tests/User.test.js b/src/server/query-tests/User.test.js
index 48c91f7..a248a60 100644
--- a/src/server/query-tests/User.test.js
+++ b/src/server/query-tests/User.test.js
@@ -178,7 +178,7 @@ describe("User", () => {
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
+ WHERE user_id IN (?)
ORDER BY item_name",
Array [
"44743",
@@ -240,7 +240,141 @@ describe("User", () => {
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
+ WHERE user_id IN (?)
+ ORDER BY item_name",
+ Array [
+ "44743",
+ ],
+ ],
+ Array [
+ "SELECT * FROM closet_lists
+ WHERE user_id IN (?)
+ ORDER BY name",
+ Array [
+ "44743",
+ ],
+ ],
+ ]
+ `);
+ });
+
+ it("gets private items they want for current user", async () => {
+ await logInAsTestUser();
+
+ const res = await query({
+ query: gql`
+ query {
+ user(id: "44743") {
+ id
+ username
+ itemsTheyWant {
+ id
+ name
+ }
+ }
+ }
+ `,
+ });
+
+ expect(res).toHaveNoErrors();
+ expect(res.data).toMatchInlineSnapshot(`
+ Object {
+ "user": Object {
+ "id": "44743",
+ "itemsTheyWant": Array [
+ Object {
+ "id": "39945",
+ "name": "Altador Cup Background - Haunted Woods",
+ },
+ Object {
+ "id": "39956",
+ "name": "Altador Cup Background - Kreludor",
+ },
+ Object {
+ "id": "39947",
+ "name": "Altador Cup Background - Shenkuu",
+ },
+ ],
+ "username": "dti-test",
+ },
+ }
+ `);
+ expect(getDbCalls()).toMatchInlineSnapshot(`
+ Array [
+ Array [
+ "SELECT * FROM users WHERE id IN (?)",
+ Array [
+ "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 (?)
+ ORDER BY item_name",
+ Array [
+ "44743",
+ ],
+ ],
+ Array [
+ "SELECT * FROM closet_lists
+ WHERE user_id IN (?)
+ ORDER BY name",
+ Array [
+ "44743",
+ ],
+ ],
+ ]
+ `);
+ });
+
+ it("hides private items they want from other users", async () => {
+ const res = await query({
+ query: gql`
+ query {
+ user(id: "44743") {
+ id
+ username
+ itemsTheyWant {
+ id
+ name
+ }
+ }
+ }
+ `,
+ });
+
+ expect(res).toHaveNoErrors();
+ expect(res.data).toMatchInlineSnapshot(`
+ Object {
+ "user": Object {
+ "id": "44743",
+ "itemsTheyWant": Array [
+ Object {
+ "id": "39947",
+ "name": "Altador Cup Background - Shenkuu",
+ },
+ ],
+ "username": "dti-test",
+ },
+ }
+ `);
+ expect(getDbCalls()).toMatchInlineSnapshot(`
+ Array [
+ Array [
+ "SELECT * FROM users WHERE id IN (?)",
+ Array [
+ "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 (?)
ORDER BY item_name",
Array [
"44743",
diff --git a/src/server/types/User.js b/src/server/types/User.js
index 5f05803..dc16286 100644
--- a/src/server/types/User.js
+++ b/src/server/types/User.js
@@ -5,6 +5,7 @@ const typeDefs = gql`
id: ID!
username: String!
itemsTheyOwn: [Item!]!
+ itemsTheyWant: [Item!]!
}
extend type Query {
@@ -19,6 +20,7 @@ const resolvers = {
const user = await userLoader.load(id);
return user.name;
},
+
itemsTheyOwn: async (
{ id },
_,
@@ -26,23 +28,61 @@ const resolvers = {
currentUserId,
userClosetListsLoader,
userLoader,
- userOwnedClosetHangersLoader,
+ userClosetHangersLoader,
}
) => {
const [allClosetHangers, closetLists, user] = await Promise.all([
- userOwnedClosetHangersLoader.load(id),
+ userClosetHangersLoader.load(id),
userClosetListsLoader.load(id),
userLoader.load(id),
]);
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 visibleClosetHangers = allClosetHangers
+ .filter((h) => h.owned)
+ .filter(
+ (h) =>
+ user.id === currentUserId ||
+ (h.listId == null && user.ownedClosetHangersVisibility >= 1) ||
+ (h.listId != null && closetListsById.get(h.listId).visibility >= 1)
+ );
+
+ 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!
+ name: h.itemName,
+ }));
+ return items;
+ },
+
+ itemsTheyWant: async (
+ { id },
+ _,
+ {
+ currentUserId,
+ userClosetListsLoader,
+ userLoader,
+ userClosetHangersLoader,
+ }
+ ) => {
+ const [allClosetHangers, closetLists, user] = await Promise.all([
+ userClosetHangersLoader.load(id),
+ userClosetListsLoader.load(id),
+ userLoader.load(id),
+ ]);
+
+ const closetListsById = new Map(closetLists.map((l) => [l.id, l]));
+
+ const visibleClosetHangers = allClosetHangers
+ .filter((h) => !h.owned)
+ .filter(
+ (h) =>
+ user.id === currentUserId ||
+ (h.listId == null && user.wantedClosetHangersVisibility >= 1) ||
+ (h.listId != null && closetListsById.get(h.listId).visibility >= 1)
+ );
const items = visibleClosetHangers.map((h) => ({
id: h.itemId,