diff options
author | Giteabot <teabot@gitea.io> | 2023-11-21 12:02:58 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-21 12:02:58 +0800 |
commit | ffab076b72fb5822531f24f9e608f3b49bb2d324 (patch) | |
tree | 3bd9d2ef9e26b9d7a89b80a7b054c822c75209f1 /web_src | |
parent | 117d9a117fd124c008895bbabecdbfac1dfac653 (diff) | |
download | gitea-ffab076b72fb5822531f24f9e608f3b49bb2d324.tar.gz gitea-ffab076b72fb5822531f24f9e608f3b49bb2d324.zip |
Use "is-loading" to avoid duplicate form submit for code comment (#28143) (#28147)
Backport #28143 by @wxiaoguang
Compare by ignoring spaces:
https://github.com/go-gitea/gitea/pull/28143/files?diff=split&w=1
When the form is going to be submitted, add the "is-loading" class to
show an indicator and avoid user UI events.
When the request finishes (success / error), remove the "is-loading"
class to make user can interact the UI.
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Diffstat (limited to 'web_src')
-rw-r--r-- | web_src/js/features/repo-diff.js | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/web_src/js/features/repo-diff.js b/web_src/js/features/repo-diff.js index 864b28a3bb..e74db04d08 100644 --- a/web_src/js/features/repo-diff.js +++ b/web_src/js/features/repo-diff.js @@ -6,8 +6,9 @@ import {initDiffCommitSelect} from './repo-diff-commitselect.js'; import {validateTextareaNonEmpty} from './comp/ComboMarkdownEditor.js'; import {initViewedCheckboxListenerFor, countAndUpdateViewedFiles, initExpandAndCollapseFilesButton} from './pull-view-file.js'; import {initImageDiff} from './imagediff.js'; +import {showErrorToast} from '../modules/toast.js'; -const {csrfToken, pageData} = window.config; +const {csrfToken, pageData, i18n} = window.config; function initRepoDiffReviewButton() { const $reviewBox = $('#review-box'); @@ -50,26 +51,34 @@ function initRepoDiffConversationForm() { return; } - const formData = new FormData($form[0]); + if ($form.hasClass('is-loading')) return; + try { + $form.addClass('is-loading'); + const formData = new FormData($form[0]); - // if the form is submitted by a button, append the button's name and value to the form data - const submitter = e.originalEvent?.submitter; - const isSubmittedByButton = (submitter?.nodeName === 'BUTTON') || (submitter?.nodeName === 'INPUT' && submitter.type === 'submit'); - if (isSubmittedByButton && submitter.name) { - formData.append(submitter.name, submitter.value); - } - const formDataString = String(new URLSearchParams(formData)); - const $newConversationHolder = $(await $.post($form.attr('action'), formDataString)); - const {path, side, idx} = $newConversationHolder.data(); - - $form.closest('.conversation-holder').replaceWith($newConversationHolder); - if ($form.closest('tr').data('line-type') === 'same') { - $(`[data-path="${path}"] .add-code-comment[data-idx="${idx}"]`).addClass('gt-invisible'); - } else { - $(`[data-path="${path}"] .add-code-comment[data-side="${side}"][data-idx="${idx}"]`).addClass('gt-invisible'); + // if the form is submitted by a button, append the button's name and value to the form data + const submitter = e.originalEvent?.submitter; + const isSubmittedByButton = (submitter?.nodeName === 'BUTTON') || (submitter?.nodeName === 'INPUT' && submitter.type === 'submit'); + if (isSubmittedByButton && submitter.name) { + formData.append(submitter.name, submitter.value); + } + const formDataString = String(new URLSearchParams(formData)); + const $newConversationHolder = $(await $.post($form.attr('action'), formDataString)); + const {path, side, idx} = $newConversationHolder.data(); + + $form.closest('.conversation-holder').replaceWith($newConversationHolder); + if ($form.closest('tr').data('line-type') === 'same') { + $(`[data-path="${path}"] .add-code-comment[data-idx="${idx}"]`).addClass('gt-invisible'); + } else { + $(`[data-path="${path}"] .add-code-comment[data-side="${side}"][data-idx="${idx}"]`).addClass('gt-invisible'); + } + $newConversationHolder.find('.dropdown').dropdown(); + initCompReactionSelector($newConversationHolder); + } 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 + showErrorToast(i18n.network_error); + } finally { + $form.removeClass('is-loading'); } - $newConversationHolder.find('.dropdown').dropdown(); - initCompReactionSelector($newConversationHolder); }); $(document).on('click', '.resolve-conversation', async function (e) { |