@@ -121,8 +121,9 @@ export default function NewEntry(props: NewEntryProps): ReactElement {
121121 resetNewEntry ( ) ;
122122 setSubmitting ( false ) ;
123123 setVernOpen ( false ) ;
124- focus ( FocusTarget . Vernacular ) ;
125- } , [ focus , resetNewEntry ] ) ;
124+ // Do not use focus(FocusTarget.Vernacular) here.
125+ // That allows typing atop the previous vernacular.
126+ } , [ resetNewEntry ] ) ;
126127
127128 /** Reset when tree opens, except for the first time it is open. */
128129 useEffect ( ( ) => {
@@ -136,14 +137,15 @@ export default function NewEntry(props: NewEntryProps): ReactElement {
136137 }
137138 } , [ isTreeOpen , resetState , wasTreeClosed ] ) ;
138139
139- /** When the vern dialog is closed, focus needs to return to text fields.
140- * The following sets a flag (shouldFocus) to be triggered by conditionalFocus(),
140+ /** When the vern dialog is closed or submission completed,
141+ * focus needs to return to text fields.
142+ * This sets a flag (shouldFocus) to be triggered by conditionalFocus(),
141143 * which is passed to each input component to call on update. */
142144 useEffect ( ( ) => {
143- if ( ! vernOpen ) {
145+ if ( ! submitting && ! vernOpen ) {
144146 setShouldFocus ( selectedDup ? FocusTarget . Gloss : FocusTarget . Vernacular ) ;
145147 }
146- } , [ selectedDup , vernOpen ] ) ;
148+ } , [ selectedDup , submitting , vernOpen ] ) ;
147149
148150 /** This function is for a child input component to call on update
149151 * to move focus to itself, if shouldFocus says it should. */
@@ -159,42 +161,40 @@ export default function NewEntry(props: NewEntryProps): ReactElement {
159161 setVernOpen ( ! ! openVernDialog ) ;
160162 } ;
161163
162- const addNewEntryAndReset = async ( ) : Promise < void > => {
163- // Prevent double-submission
164- if ( submitting ) {
165- return ;
166- }
167- setSubmitting ( true ) ;
168- await addNewEntry ( ) ;
169- resetState ( ) ;
170- } ;
171-
172164 const addOrUpdateWord = async ( ) : Promise < void > => {
173165 if ( suggestedDups . length ) {
174166 // Case 1: Duplicate vern is typed
175167 if ( ! selectedDup ) {
176- // Case 1a: User hasn't made a selection
168+ // Case 1a: User hasn't made a selection (should never happen,
169+ // since submission is only triggered from the gloss field,
170+ // but left here in case that changes)
177171 setVernOpen ( true ) ;
172+ setSubmitting ( false ) ;
173+ return ;
178174 } else if ( selectedDup . id ) {
179175 // Case 1b: User has selected an entry to modify
180176 await updateWordWithNewGloss ( ) ;
181- resetState ( ) ;
182177 } else {
183178 // Case 1c: User has selected new entry
184- await addNewEntryAndReset ( ) ;
179+ await addNewEntry ( ) ;
185180 }
186181 } else {
187182 // Case 2: New vern is typed
188- await addNewEntryAndReset ( ) ;
183+ await addNewEntry ( ) ;
189184 }
185+ resetState ( ) ;
190186 } ;
191187
192188 const handleGlossEnter = async ( ) : Promise < void > => {
193189 // The user can never submit a new entry without a vernacular
194190 if ( newVern ) {
191+ // Blur to prevent double-submission or extending submitted gloss.
192+ glossInput . current ?. blur ( ) ;
193+ setSubmitting ( true ) ;
195194 await addOrUpdateWord ( ) ;
195+ } else {
196+ focus ( FocusTarget . Vernacular ) ;
196197 }
197- focus ( FocusTarget . Vernacular ) ;
198198 } ;
199199
200200 /** Clear the duplicate selection if user returns to the vernacular field. */
@@ -226,7 +226,7 @@ export default function NewEntry(props: NewEntryProps): ReactElement {
226226 < Grid2 size = { 4 } >
227227 < VernWithSuggestions
228228 isNew
229- vernacular = { newVern }
229+ vernacular = { submitting ? "" : newVern }
230230 vernInput = { vernInput }
231231 updateVernField = { ( newValue : string , openDialog ?: boolean ) =>
232232 updateVernField ( newValue , openDialog )
@@ -261,7 +261,7 @@ export default function NewEntry(props: NewEntryProps): ReactElement {
261261 < Grid2 size = { 4 } >
262262 < GlossWithSuggestions
263263 isNew
264- gloss = { newGloss }
264+ gloss = { submitting ? "" : newGloss }
265265 glossInput = { glossInput }
266266 updateGlossField = { setNewGloss }
267267 handleEnter = { ( ) => handleGlossEnter ( ) }
@@ -276,15 +276,15 @@ export default function NewEntry(props: NewEntryProps): ReactElement {
276276 // note is not available if user selected to modify an existing entry
277277 < NoteButton
278278 buttonId = { NewEntryId . ButtonNote }
279- noteText = { newNote }
279+ noteText = { submitting ? "" : newNote }
280280 updateNote = { setNewNote }
281281 />
282282 ) }
283283 </ Grid2 >
284284
285285 < Grid2 size = { 2 } >
286286 < PronunciationsFrontend
287- audio = { newAudio }
287+ audio = { submitting ? [ ] : newAudio }
288288 deleteAudio = { delNewAudio }
289289 replaceAudio = { repNewAudio }
290290 uploadAudio = { addNewAudio }
@@ -295,7 +295,10 @@ export default function NewEntry(props: NewEntryProps): ReactElement {
295295 < Grid2 size = { 1 } >
296296 < DeleteEntry
297297 buttonId = { NewEntryId . ButtonDelete }
298- removeEntry = { ( ) => resetState ( ) }
298+ removeEntry = { ( ) => {
299+ resetState ( ) ;
300+ focus ( FocusTarget . Vernacular ) ;
301+ } }
299302 />
300303 </ Grid2 >
301304
0 commit comments