add real timestamp to trades page

This commit is contained in:
Emi Matchu 2020-11-24 14:43:43 -08:00
parent d275c96396
commit c23243fcb7
3 changed files with 64 additions and 6 deletions

View file

@ -29,7 +29,7 @@ export function ItemTradesOfferingPage() {
user { user {
id id
username username
# lastUpdatedAnyTrade lastTradeActivity
} }
closetList { closetList {
id id
@ -58,7 +58,7 @@ export function ItemTradesSeekingPage() {
user { user {
id id
username username
# lastUpdatedAnyTrade lastTradeActivity
} }
closetList { closetList {
id id
@ -155,7 +155,7 @@ function ItemTradesTable({
<ItemTradesTableCell as="th" width={{ base: "23%", md: "18ex" }}> <ItemTradesTableCell as="th" width={{ base: "23%", md: "18ex" }}>
{/* A small wording tweak to fit better on the xsmall screens! */} {/* A small wording tweak to fit better on the xsmall screens! */}
<Box display={{ base: "none", sm: "block" }}>Last active</Box> <Box display={{ base: "none", sm: "block" }}>Last active</Box>
<Box display={{ base: "block", sm: "none" }}>Updated</Box> <Box display={{ base: "block", sm: "none" }}>Active at</Box>
</ItemTradesTableCell> </ItemTradesTableCell>
<ItemTradesTableCell as="th" width={{ base: "23%", md: "18ex" }}> <ItemTradesTableCell as="th" width={{ base: "23%", md: "18ex" }}>
Compare Compare
@ -181,6 +181,7 @@ function ItemTradesTable({
href={`/user/${trade.user.id}/items#list-${trade.closetList.id}`} href={`/user/${trade.user.id}/items#list-${trade.closetList.id}`}
username={trade.user.username} username={trade.user.username}
listName={trade.closetList.name} listName={trade.closetList.name}
lastTradeActivity={trade.user.lastTradeActivity}
/> />
))} ))}
{!loading && data.item.trades.length === 0 && ( {!loading && data.item.trades.length === 0 && (
@ -199,7 +200,13 @@ function ItemTradesTable({
); );
} }
function ItemTradesTableRow({ compareListHeading, href, username, listName }) { function ItemTradesTableRow({
compareListHeading,
href,
username,
listName,
lastTradeActivity,
}) {
const history = useHistory(); const history = useHistory();
const onClick = React.useCallback(() => history.push(href), [history, href]); const onClick = React.useCallback(() => history.push(href), [history, href]);
const focusBackground = useColorModeValue("gray.100", "gray.600"); const focusBackground = useColorModeValue("gray.100", "gray.600");
@ -232,8 +239,10 @@ function ItemTradesTableRow({ compareListHeading, href, username, listName }) {
{username} {username}
</ItemTradesTableCell> </ItemTradesTableCell>
<ItemTradesTableCell fontSize="xs"> <ItemTradesTableCell fontSize="xs">
<Box display={{ base: "block", sm: "none" }}>&lt;1 week</Box> {new Intl.DateTimeFormat("en", {
<Box display={{ base: "none", sm: "block" }}>This week</Box> month: "short",
year: "numeric",
}).format(new Date(lastTradeActivity))}
</ItemTradesTableCell> </ItemTradesTableCell>
<ItemTradesTableCell fontSize="xs"> <ItemTradesTableCell fontSize="xs">
<Tooltip <Tooltip
@ -249,6 +258,7 @@ function ItemTradesTableRow({ compareListHeading, href, username, listName }) {
Constellation Dress Constellation Dress
</Box> </Box>
</Box> </Box>
<Box>(WIP: This is placeholder data!)</Box>
</Box> </Box>
} }
> >

View file

@ -919,6 +919,44 @@ const buildUserClosetListsLoader = (db, loaders) =>
); );
}); });
const buildUserLastTradeActivityLoader = (db) =>
new DataLoader(async (userIds) => {
const qs = userIds.map((_) => "?").join(",");
const [rows, _] = await db.execute(
`
SELECT
closet_hangers.user_id AS user_id,
MAX(closet_hangers.updated_at) AS last_trade_activity
FROM closet_hangers
INNER JOIN users ON users.id = closet_hangers.user_id
LEFT JOIN closet_lists ON closet_lists.id = closet_hangers.list_id
WHERE (
closet_hangers.user_id IN (${qs})
AND (
(closet_hangers.list_id IS NOT NULL AND closet_lists.visibility >= 2)
OR (
closet_hangers.list_id IS NULL AND closet_hangers.owned = 1
AND users.owned_closet_hangers_visibility >= 2
)
OR (
closet_hangers.list_id IS NULL AND closet_hangers.owned = 0
AND users.wanted_closet_hangers_visibility >= 2
)
)
)
GROUP BY closet_hangers.user_id
`,
userIds
);
const entities = rows.map(normalizeRow);
return userIds.map((userId) => {
const entity = entities.find((e) => e.userId === String(userId));
return entity ? entity.lastTradeActivity : null;
});
});
const buildZoneLoader = (db) => { const buildZoneLoader = (db) => {
const zoneLoader = new DataLoader(async (ids) => { const zoneLoader = new DataLoader(async (ids) => {
const qs = ids.map((_) => "?").join(","); const qs = ids.map((_) => "?").join(",");
@ -1022,6 +1060,7 @@ function buildLoaders(db) {
loaders.userByEmailLoader = buildUserByEmailLoader(db); loaders.userByEmailLoader = buildUserByEmailLoader(db);
loaders.userClosetHangersLoader = buildUserClosetHangersLoader(db); loaders.userClosetHangersLoader = buildUserClosetHangersLoader(db);
loaders.userClosetListsLoader = buildUserClosetListsLoader(db, loaders); loaders.userClosetListsLoader = buildUserClosetListsLoader(db, loaders);
loaders.userLastTradeActivityLoader = buildUserLastTradeActivityLoader(db);
loaders.zoneLoader = buildZoneLoader(db); loaders.zoneLoader = buildZoneLoader(db);
loaders.zoneTranslationLoader = buildZoneTranslationLoader(db); loaders.zoneTranslationLoader = buildZoneTranslationLoader(db);

View file

@ -10,6 +10,10 @@ const typeDefs = gql`
itemsTheyOwn: [Item!]! itemsTheyOwn: [Item!]!
itemsTheyWant: [Item!]! itemsTheyWant: [Item!]!
# When this user last updated any of their trade lists, as an ISO 8601
# timestamp.
lastTradeActivity: String!
} }
extend type Query { extend type Query {
@ -166,6 +170,11 @@ const resolvers = {
return closetListNodes; return closetListNodes;
}, },
lastTradeActivity: async ({ id }, _, { userLastTradeActivityLoader }) => {
const lastTradeActivity = await userLastTradeActivityLoader.load(id);
return lastTradeActivity.toISOString();
},
}, },
Query: { Query: {