@@ -39,6 +39,8 @@ export default class extends Controller {
3939 "uploadProgress" ,
4040 "uploadProgressText" ,
4141 "uploadProcessing" ,
42+ "uploadProcessingMessage" ,
43+ "uploadRefreshActions" ,
4244 "uploadError" ,
4345 "uploadSuccess" ,
4446 ] ;
@@ -71,6 +73,10 @@ export default class extends Controller {
7173 declare readonly uploadProgressTextTarget : HTMLElement ;
7274 declare readonly hasUploadProcessingTarget : boolean ;
7375 declare readonly uploadProcessingTarget : HTMLElement ;
76+ declare readonly hasUploadProcessingMessageTarget : boolean ;
77+ declare readonly uploadProcessingMessageTarget : HTMLElement ;
78+ declare readonly hasUploadRefreshActionsTarget : boolean ;
79+ declare readonly uploadRefreshActionsTarget : HTMLElement ;
7480 declare readonly hasUploadErrorTarget : boolean ;
7581 declare readonly uploadErrorTarget : HTMLElement ;
7682 declare readonly hasUploadSuccessTarget : boolean ;
@@ -82,6 +88,8 @@ export default class extends Controller {
8288 private isLoading : boolean = false ;
8389 private isUploading : boolean = false ;
8490 private isConnected : boolean = false ;
91+ private hasPendingRefresh : boolean = false ;
92+ private uploadProcessingMode : "processing" | "refreshPrompt" = "processing" ;
8593 private backgroundSyncTimeoutId : ReturnType < typeof setTimeout > | null = null ;
8694 private latestManifestRevision : string | null = null ;
8795 private isBackgroundSyncEnabled : boolean = false ;
@@ -243,9 +251,7 @@ export default class extends Controller {
243251 this . showUploadStatus ( "processing" ) ;
244252 const waitSucceeded = await this . waitForManifestAvailability ( uploadedUrls ) ;
245253 if ( waitSucceeded ) {
246- await this . fetchAssets ( ) ;
247- this . showUploadStatus ( "success" ) ;
248- setTimeout ( ( ) => this . showUploadStatus ( "none" ) , 3000 ) ;
254+ this . markRefreshAvailable ( ) ;
249255 } else {
250256 this . showUploadError ( "Upload completed. New images are still processing. Please try again shortly." ) ;
251257 }
@@ -258,6 +264,7 @@ export default class extends Controller {
258264 }
259265
260266 this . isUploading = false ;
267+ this . showRefreshPromptIfPending ( ) ;
261268 }
262269
263270 /**
@@ -313,6 +320,7 @@ export default class extends Controller {
313320 if ( this . hasUploadProcessingTarget ) {
314321 this . uploadProcessingTarget . classList . toggle ( "hidden" , which !== "processing" ) ;
315322 }
323+ this . renderUploadProcessingState ( ) ;
316324 if ( this . hasUploadSuccessTarget ) {
317325 this . uploadSuccessTarget . classList . toggle ( "hidden" , which !== "success" ) ;
318326 }
@@ -333,7 +341,27 @@ export default class extends Controller {
333341 }
334342 this . showUploadStatus ( "error" ) ;
335343 // Auto-hide error message after 5 seconds
336- setTimeout ( ( ) => this . showUploadStatus ( "none" ) , 5000 ) ;
344+ setTimeout ( ( ) => {
345+ this . showUploadStatus ( "none" ) ;
346+ this . showRefreshPromptIfPending ( ) ;
347+ } , 5000 ) ;
348+ }
349+
350+ confirmRefresh ( ) : void {
351+ if ( ! this . hasPendingRefresh ) {
352+ return ;
353+ }
354+
355+ this . hasPendingRefresh = false ;
356+ this . uploadProcessingMode = "processing" ;
357+ this . showUploadStatus ( "none" ) ;
358+ void this . reloadAssetsAfterConfirmation ( ) ;
359+ }
360+
361+ dismissRefresh ( ) : void {
362+ this . hasPendingRefresh = false ;
363+ this . uploadProcessingMode = "processing" ;
364+ this . showUploadStatus ( "none" ) ;
337365 }
338366
339367 private async fetchAssets ( ) : Promise < { urls : string [ ] ; revision : string } | null > {
@@ -485,10 +513,47 @@ export default class extends Controller {
485513 }
486514
487515 if ( currentRevision === null || manifestData . revision !== currentRevision ) {
488- await this . fetchAssets ( ) ;
516+ this . latestManifestRevision = manifestData . revision ;
517+ this . markRefreshAvailable ( ) ;
489518 }
490519 }
491520
521+ private markRefreshAvailable ( ) : void {
522+ this . hasPendingRefresh = true ;
523+ this . uploadProcessingMode = "refreshPrompt" ;
524+ this . showRefreshPromptIfPending ( ) ;
525+ }
526+
527+ private showRefreshPromptIfPending ( ) : void {
528+ if ( ! this . hasPendingRefresh || this . isUploading || this . isUploadErrorVisible ( ) ) {
529+ return ;
530+ }
531+ this . showUploadStatus ( "processing" ) ;
532+ }
533+
534+ private isUploadErrorVisible ( ) : boolean {
535+ return this . hasUploadErrorTarget && ! this . uploadErrorTarget . classList . contains ( "hidden" ) ;
536+ }
537+
538+ private renderUploadProcessingState ( ) : void {
539+ if ( this . hasUploadProcessingMessageTarget ) {
540+ this . uploadProcessingMessageTarget . textContent =
541+ this . uploadProcessingMode === "refreshPrompt"
542+ ? "Neue Bilder sind verfügbar. Bildliste jetzt aktualisieren?"
543+ : "Neue Bilder werden verarbeitet..." ;
544+ }
545+
546+ if ( this . hasUploadRefreshActionsTarget ) {
547+ this . uploadRefreshActionsTarget . classList . toggle ( "hidden" , this . uploadProcessingMode !== "refreshPrompt" ) ;
548+ }
549+ }
550+
551+ private async reloadAssetsAfterConfirmation ( ) : Promise < void > {
552+ await this . fetchAssets ( ) ;
553+ this . showUploadStatus ( "success" ) ;
554+ setTimeout ( ( ) => this . showUploadStatus ( "none" ) , 3000 ) ;
555+ }
556+
492557 private normalizeManifestData ( data : { urls ?: string [ ] ; revision ?: string } ) : { urls : string [ ] ; revision : string } {
493558 const urls = data . urls ?? [ ] ;
494559 const revision = data . revision ?? this . computeManifestRevision ( urls ) ;
0 commit comments