aboutsummaryrefslogtreecommitdiffstats
path: root/web_src/js/features
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2023-02-24 09:26:27 +0800
committerGitHub <noreply@github.com>2023-02-24 09:26:27 +0800
commit0bc8bb3cc4f003e70bfee75863b74c2243c6d23c (patch)
treed25f3732243ada34b2093d16e4ae90a99d64e225 /web_src/js/features
parent1f09051f2b0893933ec4cd9fccbb6137e7e9df89 (diff)
downloadgitea-0bc8bb3cc4f003e70bfee75863b74c2243c6d23c.tar.gz
gitea-0bc8bb3cc4f003e70bfee75863b74c2243c6d23c.zip
Make issue meta dropdown support Enter, confirm before reloading (#23014)
As the title. Label/assignee share the same code. * Close #22607 * Close #20727 Also: * partially fix for #21742, now the comment reaction and menu work with keyboard. * partially fix for #17705, in most cases the comment won't be lost. * partially fix for #21539 * partially fix for #20347 * partially fix for #7329 ### The `Enter` support Before, if user presses Enter, the dropdown just disappears and nothing happens or the window reloads. After, Enter can be used to select/deselect labels, and press Esc to hide the dropdown to update the labels (still no way to cancel .... maybe you can do a Cmd+R or F5 to refresh the window to discard the changes .....) This is only a quick patch, the UX is still not perfect, but it's much better than before. ### The `confirm` before reloading And more fixes for the `reload` problem, the new behaviors: * If nothing changes (just show/hide the dropdown), then the page won't be reloaded. * If there are draft comments, show a confirm dialog before reloading, to avoid losing comments. That's the best effect can be done at the moment, unless completely refactor these dropdown related code. Screenshot of the confirm dialog: <details> ![image](https://user-images.githubusercontent.com/2114189/220538288-e2da8459-6a4e-43cb-8596-74057f8a03a2.png) </details> --------- Co-authored-by: Brecht Van Lommel <brecht@blender.org> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Diffstat (limited to 'web_src/js/features')
-rw-r--r--web_src/js/features/aria.js3
-rw-r--r--web_src/js/features/repo-legacy.js49
2 files changed, 39 insertions, 13 deletions
diff --git a/web_src/js/features/aria.js b/web_src/js/features/aria.js
index a5ac84e446..373d667c5f 100644
--- a/web_src/js/features/aria.js
+++ b/web_src/js/features/aria.js
@@ -81,7 +81,8 @@ function attachOneDropdownAria($dropdown) {
$dropdown.on('keydown', (e) => {
// here it must use keydown event before dropdown's keyup handler, otherwise there is no Enter event in our keyup handler
if (e.key === 'Enter') {
- const $item = $dropdown.dropdown('get item', $dropdown.dropdown('get value'));
+ let $item = $dropdown.dropdown('get item', $dropdown.dropdown('get value'));
+ if (!$item) $item = $menu.find('> .item.selected'); // when dropdown filters items by input, there is no "value", so query the "selected" item
// if the selected item is clickable, then trigger the click event. in the future there could be a special CSS class for it.
if ($item && $item.is('a')) $item[0].click();
}
diff --git a/web_src/js/features/repo-legacy.js b/web_src/js/features/repo-legacy.js
index 8178ed6547..a9229c0d1e 100644
--- a/web_src/js/features/repo-legacy.js
+++ b/web_src/js/features/repo-legacy.js
@@ -29,6 +29,26 @@ import {hideElem, showElem} from '../utils/dom.js';
const {csrfToken} = window.config;
+// if there are draft comments (more than 20 chars), confirm before reloading, to avoid losing comments
+function reloadConfirmDraftComment() {
+ const commentTextareas = [
+ document.querySelector('.edit-content-zone:not(.gt-hidden) textarea'),
+ document.querySelector('.edit_area'),
+ ];
+ for (const textarea of commentTextareas) {
+ // Most users won't feel too sad if they lose a comment with 10 or 20 chars, they can re-type these in seconds.
+ // But if they have typed more (like 50) chars and the comment is lost, they will be very unhappy.
+ if (textarea && textarea.value.trim().length > 20) {
+ textarea.parentElement.scrollIntoView();
+ if (!window.confirm('Page will be reloaded, but there are draft comments. Continuing to reload will discard the comments. Continue?')) {
+ return;
+ }
+ break;
+ }
+ }
+ window.location.reload();
+}
+
export function initRepoCommentForm() {
const $commentForm = $('.comment.form');
if ($commentForm.length === 0) {
@@ -86,12 +106,15 @@ export function initRepoCommentForm() {
let hasUpdateAction = $listMenu.data('action') === 'update';
const items = {};
- $(`.${selector}`).dropdown('setting', 'onHide', () => {
- hasUpdateAction = $listMenu.data('action') === 'update'; // Update the var
- if (hasUpdateAction) {
- // TODO: Add batch functionality and make this 1 network request.
- (async function() {
- for (const [elementId, item] of Object.entries(items)) {
+ $(`.${selector}`).dropdown({
+ 'action': 'nothing', // do not hide the menu if user presses Enter
+ fullTextSearch: 'exact',
+ async onHide() {
+ hasUpdateAction = $listMenu.data('action') === 'update'; // Update the var
+ if (hasUpdateAction) {
+ // TODO: Add batch functionality and make this 1 network request.
+ const itemEntries = Object.entries(items);
+ for (const [elementId, item] of itemEntries) {
await updateIssuesMeta(
item['update-url'],
item.action,
@@ -99,9 +122,11 @@ export function initRepoCommentForm() {
elementId,
);
}
- window.location.reload();
- })();
- }
+ if (itemEntries.length) {
+ reloadConfirmDraftComment();
+ }
+ }
+ },
});
$listMenu.find('.item:not(.no-select)').on('click', function (e) {
@@ -196,7 +221,7 @@ export function initRepoCommentForm() {
'clear',
$listMenu.data('issue-id'),
'',
- ).then(() => window.location.reload());
+ ).then(reloadConfirmDraftComment);
}
$(this).parent().find('.item').each(function () {
@@ -239,7 +264,7 @@ export function initRepoCommentForm() {
'',
$menu.data('issue-id'),
$(this).data('id'),
- ).then(() => window.location.reload());
+ ).then(reloadConfirmDraftComment);
}
let icon = '';
@@ -272,7 +297,7 @@ export function initRepoCommentForm() {
'',
$menu.data('issue-id'),
$(this).data('id'),
- ).then(() => window.location.reload());
+ ).then(reloadConfirmDraftComment);
}
$list.find('.selected').html('');