Skip to content

Commit

Permalink
fix(preview): fix issue sometimes causing hotspot menu to stay a gray…
Browse files Browse the repository at this point in the history
… box after uploading (#8076)
  • Loading branch information
bjoerge authored Dec 17, 2024
1 parent 1fa5db6 commit 3d5f1d3
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 46 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {type ProgressEvent, type SanityAssetDocument, type SanityClient} from '@sanity/client'
import {type FileAsset, type ImageAsset} from '@sanity/types'
import {Observable, of as observableOf, of} from 'rxjs'
import {catchError, map, mergeMap, retry, switchMap} from 'rxjs/operators'
import {Observable, of as observableOf} from 'rxjs'
import {catchError, map, mergeMap} from 'rxjs/operators'

import {type DocumentPreviewStore} from '../../../../preview'
import {type UploadOptions} from '../../uploads/types'
Expand Down Expand Up @@ -84,43 +84,17 @@ export const uploadFileAsset = (client: SanityClient, file: File | Blob, options
*/
// note: there's currently 100% overlap between the ImageAsset document and the FileAsset documents as per interface required by the image and file input
function observeAssetDoc(documentPreviewStore: DocumentPreviewStore, id: string) {
return documentPreviewStore
.observePaths({_type: 'reference', _ref: id}, [
'originalFilename',
'url',
'metadata',
'label',
'title',
'description',
'creditLine',
'source',
'size',
])
.pipe(
/**
* In some cases when uploading large media file we are getting an stale `null` response from content lake when fetching the reference that was just uploaded,
* making the UI not to react as it should.
* This retry logic is added to handle the case where the asset is not found in the initial fetch to the documentPreviewStore but it will eventually be found,
* because the asset has been just added.
* It has the downside that if this is being used to check if an asset exists, it will retry 5 times before returning null.
*/
switchMap((result) => {
// If the result is null, throw an error to trigger retry
if (result === null) {
throw new Error(`No asset found in documentPreviewStore with id: ${id}`)
}
// If the result is not null, return the result
return of(result)
}),
retry({
count: 5,
delay: 1000,
}),
catchError((err) => {
console.error('Final error after retries, asset not found in documentPreviewStore:', err)
return of(null) // Return null if the asset is not found
}),
)
return documentPreviewStore.observePaths({_type: 'reference', _ref: id}, [
'originalFilename',
'url',
'metadata',
'label',
'title',
'description',
'creditLine',
'source',
'size',
])
}

export function observeImageAsset(documentPreviewStore: DocumentPreviewStore, id: string) {
Expand Down
14 changes: 7 additions & 7 deletions packages/sanity/src/core/preview/observeFields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
fromEvent,
merge,
type Observable,
of as observableOf,
of,
timer,
} from 'rxjs'
import {
Expand Down Expand Up @@ -100,20 +100,20 @@ export function createObserveFields(options: {
return listen(id).pipe(
switchMap((event) => {
if (event.type === 'connected' || event.visibility === 'query') {
return fetchDocumentPathsFast(id, fields as any).pipe(
return fetchDocumentPathsFast(id, fields).pipe(
mergeMap((result) => {
return concat(
observableOf(result),
result === undefined // hack: if we get undefined as result here it can be because the document has
of(result),
result === null // hack: if we get undefined as result here it can be because the document has
? // just been created and is not yet indexed. We therefore need to wait a bit
// and then re-fetch.
fetchDocumentPathsSlow(id, fields as any)
fetchDocumentPathsSlow(id, fields)
: [],
)
}),
)
}
return fetchDocumentPathsSlow(id, fields as any)
return fetchDocumentPathsSlow(id, fields)
}),
)
}
Expand Down Expand Up @@ -157,7 +157,7 @@ export function createObserveFields(options: {
// Note: `undefined` means the memo has not been set, while `null` means the memo is explicitly set to null (e.g. we did fetch, but got null back)
let latest: T | undefined | null = undefined
const changes$ = merge(
defer(() => (latest === undefined ? EMPTY : observableOf(latest))),
defer(() => (latest === undefined ? EMPTY : of(latest))),
(apiConfig
? (crossDatasetListenFields(id, fields, apiConfig) as any)
: currentDatasetListenFields(id, fields)) as Observable<T>,
Expand Down

0 comments on commit 3d5f1d3

Please sign in to comment.