@@ -100,6 +100,18 @@ function scoreSubmission(submission: { votes: Array<{ value: number }> }) {
100100 return submission . votes . reduce ( ( total , vote ) => total + vote . value , 0 ) ;
101101}
102102
103+ function canonicalPixels ( pixels : QuiltPixel [ ] ) {
104+ return JSON . stringify (
105+ pixels
106+ . map ( ( pixel ) => ( {
107+ x : pixel . x ,
108+ y : pixel . y ,
109+ color : pixel . color ,
110+ } ) )
111+ . sort ( ( a , b ) => a . y - b . y || a . x - b . x ) ,
112+ ) ;
113+ }
114+
103115function serializeSubmission (
104116 submission : QuiltSubmissionWithRelations ,
105117 viewerId ?: number ,
@@ -303,32 +315,39 @@ export async function submitQuiltPixels({
303315 if ( quilt . endsAt . getTime ( ) <= Date . now ( ) ) {
304316 throw new BadRequestError ( "This quilt has ended." ) ;
305317 }
306- const existingPending = await db . quiltSubmission . findFirst ( {
318+ const unique = new Map < string , QuiltPixel > ( ) ;
319+ for ( const pixel of input . pixels ) {
320+ if ( pixel . x >= quilt . width || pixel . y >= quilt . height ) {
321+ throw new BadRequestError ( "Pixel is outside the quilt bounds." ) ;
322+ }
323+ unique . set ( `${ pixel . x } :${ pixel . y } ` , pixel ) ;
324+ }
325+
326+ const normalizedPixels = Array . from ( unique . values ( ) ) ;
327+ const existingPending = await db . quiltSubmission . findMany ( {
307328 where : {
308329 quiltId : quilt . id ,
309330 authorId : actor . id ,
310331 status : QuiltSubmissionStatus . PENDING ,
311332 } ,
312- select : { id : true } ,
333+ select : { pixels : true } ,
313334 } ) ;
314- if ( existingPending ) {
335+ const normalized = canonicalPixels ( normalizedPixels ) ;
336+ if (
337+ existingPending . some (
338+ ( submission ) => canonicalPixels ( parsePixels ( submission . pixels ) ) === normalized ,
339+ )
340+ ) {
315341 throw new BadRequestError (
316- "You already have a pending quilt change. Edit it instead of submitting another one ." ,
342+ "You already submitted this quilt change. Edit the existing submission to update it ." ,
317343 ) ;
318344 }
319- const unique = new Map < string , QuiltPixel > ( ) ;
320- for ( const pixel of input . pixels ) {
321- if ( pixel . x >= quilt . width || pixel . y >= quilt . height ) {
322- throw new BadRequestError ( "Pixel is outside the quilt bounds." ) ;
323- }
324- unique . set ( `${ pixel . x } :${ pixel . y } ` , pixel ) ;
325- }
326345 const now = new Date ( ) ;
327346 const submission = await db . quiltSubmission . create ( {
328347 data : {
329348 quiltId : quilt . id ,
330349 authorId : actor . id ,
331- pixels : Array . from ( unique . values ( ) ) ,
350+ pixels : normalizedPixels ,
332351 resolvesAt : new Date ( now . getTime ( ) + REVIEW_WINDOW_MS ) ,
333352 } ,
334353 } ) ;
0 commit comments