@@ -58,6 +58,12 @@ function imageHasFile(
58
58
return Boolean ( image . file ?. size && image . file ?. size > 0 )
59
59
}
60
60
61
+ function imageHasId (
62
+ image : ImageFieldset ,
63
+ ) : image is ImageFieldset & { id : NonNullable < ImageFieldset [ 'id' ] > } {
64
+ return image . id != null
65
+ }
66
+
61
67
const NoteEditorSchema = z . object ( {
62
68
id : z . string ( ) . optional ( ) ,
63
69
title : z . string ( ) . min ( titleMinLength ) . max ( titleMaxLength ) ,
@@ -90,20 +96,34 @@ export async function action({ request }: DataFunctionArgs) {
90
96
} ) . transform ( async ( { images = [ ] , ...data } ) => {
91
97
return {
92
98
...data ,
93
- imageIds : images . map ( i => i . id ) . filter ( Boolean ) ,
94
- imageUpdates : images
95
- . filter ( i => i . id && ! imageHasFile ( i ) )
96
- . map ( i => ( {
97
- id : i . id ,
98
- altText : i . altText ,
99
- } ) ) ,
100
- imageUploads : await Promise . all (
101
- images . filter ( imageHasFile ) . map ( async image => ( {
102
- id : image . id ,
103
- altText : image . altText ,
104
- contentType : image . file . type ,
105
- blob : Buffer . from ( await image . file . arrayBuffer ( ) ) ,
106
- } ) ) ,
99
+ imageUpdates : await Promise . all (
100
+ images . filter ( imageHasId ) . map ( async i => {
101
+ if ( imageHasFile ( i ) ) {
102
+ return {
103
+ id : i . id ,
104
+ altText : i . altText ,
105
+ contentType : i . file . type ,
106
+ blob : Buffer . from ( await i . file . arrayBuffer ( ) ) ,
107
+ }
108
+ } else {
109
+ return {
110
+ id : i . id ,
111
+ altText : i . altText ,
112
+ }
113
+ }
114
+ } ) ,
115
+ ) ,
116
+ newImages : await Promise . all (
117
+ images
118
+ . filter ( imageHasFile )
119
+ . filter ( i => ! i . id )
120
+ . map ( async image => {
121
+ return {
122
+ altText : image . altText ,
123
+ contentType : image . file . type ,
124
+ blob : Buffer . from ( await image . file . arrayBuffer ( ) ) ,
125
+ }
126
+ } ) ,
107
127
) ,
108
128
}
109
129
} ) ,
@@ -122,48 +142,30 @@ export async function action({ request }: DataFunctionArgs) {
122
142
id : noteId ,
123
143
title,
124
144
content,
125
- imageUploads = [ ] ,
126
145
imageUpdates = [ ] ,
127
- imageIds ,
146
+ newImages = [ ] ,
128
147
} = submission . value
129
148
130
- const updatedNote = await prisma . $transaction ( async $prisma => {
131
- const note = await $prisma . note . upsert ( {
132
- select : { id : true , owner : { select : { username : true } } } ,
133
- where : { id : noteId ?? '__new_note__' } ,
134
- create : {
135
- ownerId : userId ,
136
- title,
137
- content,
138
- } ,
139
- update : {
140
- title,
141
- content,
142
- images : {
143
- deleteMany : { id : { notIn : imageIds } } ,
144
- updateMany : imageUpdates . map ( updates => ( {
145
- where : { id : updates . id } ,
146
- data : updates ,
147
- } ) ) ,
148
- } ,
149
+ const updatedNote = await prisma . note . upsert ( {
150
+ select : { id : true , owner : { select : { username : true } } } ,
151
+ where : { id : noteId ?? '__new_note__' } ,
152
+ create : {
153
+ ownerId : userId ,
154
+ title,
155
+ content,
156
+ } ,
157
+ update : {
158
+ title,
159
+ content,
160
+ images : {
161
+ deleteMany : { id : { notIn : imageUpdates . map ( i => i . id ) } } ,
162
+ updateMany : imageUpdates . map ( updates => ( {
163
+ where : { id : updates . id } ,
164
+ data : { ...updates , id : updates . blob ? cuid ( ) : updates . id } ,
165
+ } ) ) ,
166
+ create : newImages ,
149
167
} ,
150
- } )
151
-
152
- for ( const image of imageUploads ) {
153
- await $prisma . noteImage . upsert ( {
154
- select : { id : true } ,
155
- where : { id : image . id ?? '__new_image__' } ,
156
- create : { ...image , noteId : note . id } ,
157
- update : {
158
- ...image ,
159
- // update the id since it is used for caching
160
- id : cuid ( ) ,
161
- noteId : note . id ,
162
- } ,
163
- } )
164
- }
165
-
166
- return note
168
+ } ,
167
169
} )
168
170
169
171
return redirect (
0 commit comments