@@ -144,73 +144,76 @@ const ScreenReaderOnly = styled.span`
144
144
overflow: hidden;
145
145
` ;
146
146
147
- // ============================================================================
148
- // UTILITY HOOKS
149
- // ============================================================================
150
-
151
-
152
- const useFileSrc = ( file : File | undefined ) => {
153
- const [ src , setSrc ] = useState < string | undefined > ( ) ;
154
- const lastFileRef = useRef < File > ( ) ;
155
-
156
- useEffect ( ( ) => {
157
- if ( ! file || file === lastFileRef . current ) return ;
158
-
159
- const objectUrl = URL . createObjectURL ( file ) ;
160
- setSrc ( objectUrl ) ;
161
- lastFileRef . current = file ;
162
-
163
- return ( ) => {
164
- URL . revokeObjectURL ( objectUrl ) ;
165
- } ;
166
- } , [ file ] ) ;
167
-
168
- return src ;
169
- } ;
170
-
171
-
172
147
173
148
const useAttachmentSrc = ( ) => {
149
+ // Listen only to image-type attachments
174
150
const attachment = useAttachment (
175
- useCallback ( ( a : any ) => {
176
- if ( a . type !== "image" ) return undefined ;
177
- return a ;
178
- } , [ ] )
151
+ useCallback ( ( a : any ) => ( a . type === "image" ? a : undefined ) , [ ] )
179
152
) ;
180
153
181
154
const [ src , setSrc ] = useState < string | undefined > ( ) ;
182
- const lastAttachmentRef = useRef < any > ( ) ;
183
155
184
- useEffect ( ( ) => {
185
- if ( ! attachment || attachment === lastAttachmentRef . current ) return ;
156
+ // Keep track of the last generated object URL so that we can revoke it
157
+ const objectUrlRef = useRef < string | undefined > ( ) ;
158
+ const lastAttachmentIdRef = useRef < string | undefined > ( ) ;
186
159
187
- // Handle new/pending attachments with File objects
188
- if ( attachment . file && attachment . file instanceof File ) {
189
- const objectUrl = URL . createObjectURL ( attachment . file ) ;
190
- setSrc ( objectUrl ) ;
191
- lastAttachmentRef . current = attachment ;
160
+ useEffect ( ( ) => {
161
+ // If the same attachment is rendered again, do nothing
162
+ if ( ! attachment || attachment . id === lastAttachmentIdRef . current ) return ;
163
+
164
+ // Clean up any previous object URL
165
+ if ( objectUrlRef . current ) {
166
+ try {
167
+ URL . revokeObjectURL ( objectUrlRef . current ) ;
168
+ } catch {
169
+ /* ignore */
170
+ }
171
+ objectUrlRef . current = undefined ;
172
+ }
192
173
193
- return ( ) => {
194
- URL . revokeObjectURL ( objectUrl ) ;
195
- } ;
174
+ // ------------------------------------------------------------------
175
+ // 1. New (local) File object – generate a temporary ObjectURL
176
+ // ------------------------------------------------------------------
177
+ if ( attachment . file instanceof File ) {
178
+ const url = URL . createObjectURL ( attachment . file ) ;
179
+ objectUrlRef . current = url ;
180
+ setSrc ( url ) ;
181
+ lastAttachmentIdRef . current = attachment . id ;
182
+ return ;
196
183
}
197
184
198
- // Handle saved attachments with base64 data
199
- const imageContent = attachment . content ?. find ( ( c : any ) => c . type === "image" ) ;
200
- if ( imageContent ?. image ) {
201
- setSrc ( imageContent . image ) ;
202
- lastAttachmentRef . current = attachment ;
185
+ // ------------------------------------------------------------------
186
+ // 2. Restored attachment coming from storage – use stored base64 image
187
+ // ------------------------------------------------------------------
188
+ const imgPart = attachment . content ?. find ( ( p : any ) => p . type === "image" ) ;
189
+ if ( imgPart ?. image ) {
190
+ setSrc ( imgPart . image as string ) ;
191
+ lastAttachmentIdRef . current = attachment . id ;
203
192
return ;
204
193
}
205
194
206
- // If no valid source found, clear the src
195
+ // ------------------------------------------------------------------
196
+ // 3. No usable preview – clear src
197
+ // ------------------------------------------------------------------
207
198
setSrc ( undefined ) ;
208
- lastAttachmentRef . current = attachment ;
199
+ lastAttachmentIdRef . current = attachment . id ;
209
200
} , [ attachment ] ) ;
210
201
202
+ /* Cleanup when the component using this hook unmounts */
203
+ useEffect ( ( ) => {
204
+ return ( ) => {
205
+ if ( objectUrlRef . current ) {
206
+ try {
207
+ URL . revokeObjectURL ( objectUrlRef . current ) ;
208
+ } catch {
209
+ /* ignore */
210
+ }
211
+ }
212
+ } ;
213
+ } , [ ] ) ;
214
+
211
215
return src ;
212
216
} ;
213
-
214
217
// ============================================================================
215
218
// ATTACHMENT COMPONENTS
216
219
// ============================================================================
0 commit comments