aboutsummaryrefslogtreecommitdiffstats
path: root/web_src
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2023-11-21 10:12:31 +0800
committerGitHub <noreply@github.com>2023-11-21 02:12:31 +0000
commit247927a9b51cea88db6f7d2dee25471339feb51b (patch)
tree2158b212fdb89eb337303d495b2e8870393949fd /web_src
parent0c72256ab4e6e6f6c6cd6d4949b37d32a7816785 (diff)
downloadgitea-247927a9b51cea88db6f7d2dee25471339feb51b.tar.gz
gitea-247927a9b51cea88db6f7d2dee25471339feb51b.zip
Use "is-loading" to avoid duplicate form submit for code comment (#28143)
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.
Diffstat (limited to 'web_src')
-rw-r--r--web_src/js/features/repo-diff.js47
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) {