@@ -5,7 +5,11 @@ import OneBlinkAppsError from './services/errors/oneBlinkAppsError'
55import { isOffline } from './offline-service'
66import { getUsername } from './services/cognito'
77import { getFormsKeyId , getCurrentFormsAppUser } from './auth-service'
8- import { getFormSubmissionDrafts , uploadDraftData } from './services/api/drafts'
8+ import {
9+ DRAFT_DATA_UNAVAILABLE_ERROR_TITLE ,
10+ getFormSubmissionDrafts ,
11+ uploadDraftData ,
12+ } from './services/api/drafts'
913import {
1014 getPendingQueueSubmissions ,
1115 deletePendingQueueSubmission ,
@@ -92,6 +96,7 @@ function generateLocalFormSubmissionDraftsFromDraftSubmissions(
9296 taskActionId : draftSubmission . taskCompletion ?. taskAction . taskActionId ,
9397 draftSubmission,
9498 versions : undefined ,
99+ downloadStatus : 'SUCCESS' ,
95100 } )
96101 }
97102 }
@@ -125,7 +130,9 @@ async function generatePublicLocalFormSubmissionDraftsFromStorage(
125130 )
126131
127132 return _orderBy ( localFormSubmissionDrafts , ( localFormSubmissionDraft ) => {
128- return localFormSubmissionDraft . draftSubmission ?. createdAt
133+ return localFormSubmissionDraft . downloadStatus === 'SUCCESS'
134+ ? localFormSubmissionDraft . draftSubmission ?. createdAt
135+ : undefined
129136 } )
130137}
131138
@@ -144,6 +151,22 @@ async function generateLocalFormSubmissionDraftsFromStorage(
144151 deletedDraftIds ,
145152 )
146153
154+ async function broadcastUpdate ( ) {
155+ const draftsToBroadcast = Array . from ( localFormSubmissionDraftsMap . values ( ) )
156+
157+ const orderedDrafts = _orderBy (
158+ draftsToBroadcast ,
159+ ( localFormSubmissionDraft ) =>
160+ getLatestFormSubmissionDraftVersion ( localFormSubmissionDraft . versions )
161+ ?. createdAt ,
162+ )
163+
164+ await executeDraftsListeners ( orderedDrafts )
165+ }
166+
167+ // At this point we need to store the state of the drafts in localForage
168+ const draftsToDownload : SubmissionTypes . FormSubmissionDraft [ ] = [ ]
169+
147170 for ( const formSubmissionDraft of localDraftsStorage . syncedFormSubmissionDrafts ) {
148171 if (
149172 // Unsycned version of draft takes priority over the synced version
@@ -153,33 +176,79 @@ async function generateLocalFormSubmissionDraftsFromStorage(
153176 // Remove any drafts deleted while offline
154177 ! deletedDraftIds . has ( formSubmissionDraft . id )
155178 ) {
179+ draftsToDownload . push ( formSubmissionDraft )
180+ localFormSubmissionDraftsMap . set ( formSubmissionDraft . id , {
181+ ...formSubmissionDraft ,
182+ downloadStatus : 'PENDING' ,
183+ } )
184+ }
185+ }
186+
187+ await broadcastUpdate ( )
188+
189+ // TODO Batch the downloads instead of sequentially
190+ if ( draftsToDownload . length ) {
191+ for ( const formSubmissionDraft of draftsToDownload ) {
192+ const currentValue = localFormSubmissionDraftsMap . get (
193+ formSubmissionDraft . id ,
194+ )
195+ if ( currentValue ) {
196+ localFormSubmissionDraftsMap . set ( formSubmissionDraft . id , {
197+ ...currentValue ,
198+ downloadStatus : 'DOWNLOADING' ,
199+ } )
200+ }
201+ await broadcastUpdate ( )
202+
156203 const draftSubmission = await getDraftSubmission (
157204 formSubmissionDraft ,
158205 ) . catch ( ( err ) => {
159206 console . warn (
160207 `Could not fetch draft submission for draft: ${ formSubmissionDraft . id } ` ,
161208 err ,
162209 )
210+
211+ if (
212+ err instanceof OneBlinkAppsError &&
213+ err . title === DRAFT_DATA_UNAVAILABLE_ERROR_TITLE
214+ ) {
215+ localFormSubmissionDraftsMap . set ( formSubmissionDraft . id , {
216+ ...formSubmissionDraft ,
217+ downloadStatus : 'NOT_AVAILABLE' ,
218+ } )
219+ return
220+ }
221+
222+ localFormSubmissionDraftsMap . set ( formSubmissionDraft . id , {
223+ ...formSubmissionDraft ,
224+ downloadStatus : 'ERROR' ,
225+ downloadError : err . message ,
226+ } )
227+
163228 return undefined
164229 } )
165- localFormSubmissionDraftsMap . set ( formSubmissionDraft . id , {
166- ...formSubmissionDraft ,
167- draftSubmission,
168- } )
230+ if ( draftSubmission ) {
231+ localFormSubmissionDraftsMap . set ( formSubmissionDraft . id , {
232+ ...formSubmissionDraft ,
233+ draftSubmission : draftSubmission ,
234+ downloadStatus : 'SUCCESS' ,
235+ } )
236+ }
237+
238+ await broadcastUpdate ( )
169239 }
170240 }
171241
172242 const localFormSubmissionDrafts = Array . from (
173243 localFormSubmissionDraftsMap . values ( ) ,
174244 )
175245
176- return _orderBy ( localFormSubmissionDrafts , ( localFormSubmissionDraft ) => {
177- return (
178- localFormSubmissionDraft . draftSubmission ?. createdAt ||
246+ return _orderBy (
247+ localFormSubmissionDrafts ,
248+ ( localFormSubmissionDraft ) =>
179249 getLatestFormSubmissionDraftVersion ( localFormSubmissionDraft . versions )
180- ?. createdAt
181- )
182- } )
250+ ?. createdAt ,
251+ )
183252}
184253
185254function errorHandler ( error : Error ) : Error {
@@ -800,24 +869,29 @@ async function syncDrafts({
800869 localDraftsStorage . syncedFormSubmissionDrafts = formSubmissionDrafts
801870 }
802871
803- await setAndBroadcastDrafts ( localDraftsStorage )
804-
805- if ( localDraftsStorage . syncedFormSubmissionDrafts . length ) {
806- console . log (
807- 'Ensuring all draft data is available for offline use for synced drafts' ,
808- localDraftsStorage . syncedFormSubmissionDrafts ,
809- )
810- for ( const formSubmissionDraft of localDraftsStorage . syncedFormSubmissionDrafts ) {
811- await getDraftSubmission ( formSubmissionDraft , abortSignal ) . catch (
812- ( error ) => {
813- console . warn ( 'Could not download Draft Data as JSON' , error )
814- } ,
872+ console . log ( 'Downloading drafts in the background' )
873+ setAndBroadcastDrafts ( localDraftsStorage )
874+ . then ( async ( ) => {
875+ console . log ( 'Finished syncing drafts.' )
876+ } )
877+ . catch ( ( error ) => {
878+ if ( abortSignal ?. aborted ) {
879+ console . log ( 'Syncing drafts has been aborted' )
880+ return
881+ }
882+ console . warn (
883+ 'Error while attempting download drafts in the background' ,
884+ error ,
815885 )
816- }
817- }
886+ if ( ! ( error instanceof OneBlinkAppsError ) ) {
887+ Sentry . captureException ( error )
888+ }
889+ } )
890+ . finally ( ( ) => {
891+ _isSyncingDrafts = false
892+ } )
818893
819- console . log ( 'Finished syncing drafts.' )
820- _isSyncingDrafts = false
894+ // broadcast the drafts and download the draft data in the background
821895 } catch ( error ) {
822896 _isSyncingDrafts = false
823897 if ( abortSignal ?. aborted ) {
0 commit comments