@@ -6,8 +6,9 @@ import {initDiffCommitSelect} from './repo-diff-commitselect.js';
66import { validateTextareaNonEmpty } from './comp/ComboMarkdownEditor.js' ;
77import { initViewedCheckboxListenerFor , countAndUpdateViewedFiles , initExpandAndCollapseFilesButton } from './pull-view-file.js' ;
88import { initImageDiff } from './imagediff.js' ;
9+ import { showErrorToast } from '../modules/toast.js' ;
910
10- const { csrfToken, pageData} = window . config ;
11+ const { csrfToken, pageData, i18n } = window . config ;
1112
1213function initRepoDiffReviewButton ( ) {
1314 const $reviewBox = $ ( '#review-box' ) ;
@@ -50,26 +51,34 @@ function initRepoDiffConversationForm() {
5051 return ;
5152 }
5253
53- const formData = new FormData ( $form [ 0 ] ) ;
54+ if ( $form . hasClass ( 'is-loading' ) ) return ;
55+ try {
56+ $form . addClass ( 'is-loading' ) ;
57+ const formData = new FormData ( $form [ 0 ] ) ;
5458
55- // if the form is submitted by a button, append the button's name and value to the form data
56- const submitter = e . originalEvent ?. submitter ;
57- const isSubmittedByButton = ( submitter ?. nodeName === 'BUTTON' ) || ( submitter ?. nodeName === 'INPUT' && submitter . type === 'submit' ) ;
58- if ( isSubmittedByButton && submitter . name ) {
59- formData . append ( submitter . name , submitter . value ) ;
60- }
61- const formDataString = String ( new URLSearchParams ( formData ) ) ;
62- const $newConversationHolder = $ ( await $ . post ( $form . attr ( 'action' ) , formDataString ) ) ;
63- const { path, side, idx} = $newConversationHolder . data ( ) ;
64-
65- $form . closest ( '.conversation-holder' ) . replaceWith ( $newConversationHolder ) ;
66- if ( $form . closest ( 'tr' ) . data ( 'line-type' ) === 'same' ) {
67- $ ( `[data-path="${ path } "] .add-code-comment[data-idx="${ idx } "]` ) . addClass ( 'gt-invisible' ) ;
68- } else {
69- $ ( `[data-path="${ path } "] .add-code-comment[data-side="${ side } "][data-idx="${ idx } "]` ) . addClass ( 'gt-invisible' ) ;
59+ // if the form is submitted by a button, append the button's name and value to the form data
60+ const submitter = e . originalEvent ?. submitter ;
61+ const isSubmittedByButton = ( submitter ?. nodeName === 'BUTTON' ) || ( submitter ?. nodeName === 'INPUT' && submitter . type === 'submit' ) ;
62+ if ( isSubmittedByButton && submitter . name ) {
63+ formData . append ( submitter . name , submitter . value ) ;
64+ }
65+ const formDataString = String ( new URLSearchParams ( formData ) ) ;
66+ const $newConversationHolder = $ ( await $ . post ( $form . attr ( 'action' ) , formDataString ) ) ;
67+ const { path, side, idx} = $newConversationHolder . data ( ) ;
68+
69+ $form . closest ( '.conversation-holder' ) . replaceWith ( $newConversationHolder ) ;
70+ if ( $form . closest ( 'tr' ) . data ( 'line-type' ) === 'same' ) {
71+ $ ( `[data-path="${ path } "] .add-code-comment[data-idx="${ idx } "]` ) . addClass ( 'gt-invisible' ) ;
72+ } else {
73+ $ ( `[data-path="${ path } "] .add-code-comment[data-side="${ side } "][data-idx="${ idx } "]` ) . addClass ( 'gt-invisible' ) ;
74+ }
75+ $newConversationHolder . find ( '.dropdown' ) . dropdown ( ) ;
76+ initCompReactionSelector ( $newConversationHolder ) ;
77+ } catch { // here the caught error might be a jQuery AJAX error (thrown by await $.post), which is not good to use for error message handling
78+ showErrorToast ( i18n . network_error ) ;
79+ } finally {
80+ $form . removeClass ( 'is-loading' ) ;
7081 }
71- $newConversationHolder . find ( '.dropdown' ) . dropdown ( ) ;
72- initCompReactionSelector ( $newConversationHolder ) ;
7382 } ) ;
7483
7584 $ ( document ) . on ( 'click' , '.resolve-conversation' , async function ( e ) {
0 commit comments