-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add user seen artworks mutation #6443
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { mutationWithClientMutationId } from "graphql-relay" | ||
import { | ||
GraphQLNonNull, | ||
GraphQLObjectType, | ||
GraphQLString, | ||
GraphQLUnionType, | ||
} from "graphql" | ||
import { ResolverContext } from "types/graphql" | ||
import { | ||
formatGravityError, | ||
GravityMutationErrorType, | ||
} from "lib/gravityErrorHandler" | ||
import { snakeCase } from "lodash" | ||
|
||
interface Input { | ||
artworkId: string | ||
} | ||
|
||
const inputFields = { | ||
artworkId: { type: new GraphQLNonNull(GraphQLString) }, | ||
} | ||
|
||
interface GravityInput { | ||
artwork_id: string | ||
} | ||
|
||
const SuccessType = new GraphQLObjectType<any, ResolverContext>({ | ||
name: "CreateUserSeenArtworkSuccess", | ||
isTypeOf: (data) => data.artwork_id, | ||
fields: { | ||
artworkId: { | ||
type: GraphQLString, | ||
resolve: ({ artwork_id }) => artwork_id, | ||
}, | ||
}, | ||
}) | ||
|
||
const FailureType = new GraphQLObjectType<any, ResolverContext>({ | ||
name: "CreateUserSeenArtworkFailure", | ||
isTypeOf: (data) => data._type === "GravityMutationError", | ||
fields: () => ({ | ||
mutationError: { | ||
type: GravityMutationErrorType, | ||
resolve: (err) => err, | ||
}, | ||
}), | ||
}) | ||
|
||
const ResponseOrErrorType = new GraphQLUnionType({ | ||
name: "CreateUserSeenArtworkSuccessResponseOrError", | ||
types: [SuccessType, FailureType], | ||
}) | ||
|
||
export const createUserSeenArtworkMutation = mutationWithClientMutationId< | ||
Input, | ||
any, | ||
ResolverContext | ||
>({ | ||
name: "CreateUserSeenArtwork", | ||
description: | ||
"Marks an artwork as seen when a user swipes through Infinite Discovery.", | ||
inputFields, | ||
outputFields: { | ||
userSeenArtworkOrError: { | ||
type: ResponseOrErrorType, | ||
description: "On success: the created User Seen Artwork.", | ||
resolve: (result) => result, | ||
}, | ||
}, | ||
mutateAndGetPayload: async (args, { createUserSeenArtworkLoader }) => { | ||
if (!createUserSeenArtworkLoader) { | ||
throw new Error( | ||
"You need to pass a X-Access-Token header to perform this action" | ||
) | ||
} | ||
|
||
const createUserSeenArtworkLoaderPayload = Object.keys(args) | ||
.filter((key) => key !== "id") | ||
.reduce( | ||
(acc, key) => ({ ...acc, [snakeCase(key)]: args[key] }), | ||
{} as GravityInput | ||
) | ||
|
||
try { | ||
return await createUserSeenArtworkLoader( | ||
createUserSeenArtworkLoaderPayload | ||
) | ||
} catch (error) { | ||
const formattedErr = formatGravityError(error) | ||
|
||
if (formattedErr) { | ||
return { ...formattedErr, _type: "GravityMutationError" } | ||
} else { | ||
throw new Error(error) | ||
} | ||
} | ||
}, | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ import { | |
GraphQLInt, | ||
GraphQLFloat, | ||
GraphQLList, | ||
GraphQLBoolean, | ||
} from "graphql" | ||
import { ResolverContext } from "types/graphql" | ||
import { artworkConnection } from "../artwork" | ||
|
@@ -18,6 +19,11 @@ export const DiscoverArtworks: GraphQLFieldConfig<void, ResolverContext> = { | |
type: new GraphQLList(GraphQLString), | ||
description: "Exclude these artworks from the response", | ||
}, | ||
useInternalTracking: { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @egdbear sudden idea — let's instead of this param use an ENV var in line number 61? This way backend will be able to control behavior without frontend changes There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think that is necessary if we add this change to Eigen? |
||
type: GraphQLBoolean, | ||
description: "Internal Redis tracking for the user seen artworks", | ||
defaultValue: false, | ||
}, | ||
mltFields: { | ||
type: new GraphQLList(GraphQLString), | ||
description: "These fields are used for More Like This query", | ||
|
@@ -52,6 +58,7 @@ export const DiscoverArtworks: GraphQLFieldConfig<void, ResolverContext> = { | |
os_weights: args.osWeights, | ||
curated_picks_size: args.curatedPicksSize, | ||
user_id: userID, | ||
use_internal_tracking: args.useInternalTracking, | ||
} | ||
|
||
const gravityResponse = await artworksDiscoveryLoader(gravityArgs) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: not sure if I understand what it does. Could we just call
createUserSeenArtworkLoader({ artwork_id: args.artworkId})
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It simply converts non-ID parameters to snake_case. Since it's used in other mutations, I thought it would be good to follow this utility for consistency