|
|
@ -158,17 +158,22 @@ export function initRepoIssueSidebarList() { |
|
|
|
|
|
|
|
|
|
|
|
export function initRepoIssueCommentDelete() { |
|
|
|
export function initRepoIssueCommentDelete() { |
|
|
|
// Delete comment
|
|
|
|
// Delete comment
|
|
|
|
$(document).on('click', '.delete-comment', async function () { |
|
|
|
document.addEventListener('click', async (e) => { |
|
|
|
const $this = $(this); |
|
|
|
if (!e.target.matches('.delete-comment')) return; |
|
|
|
if (window.confirm($this.data('locale'))) { |
|
|
|
e.preventDefault(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const deleteButton = e.target; |
|
|
|
|
|
|
|
if (window.confirm(deleteButton.getAttribute('data-locale'))) { |
|
|
|
try { |
|
|
|
try { |
|
|
|
const response = await POST($this.data('url')); |
|
|
|
const response = await POST(deleteButton.getAttribute('data-url')); |
|
|
|
if (!response.ok) throw new Error('Failed to delete comment'); |
|
|
|
if (!response.ok) throw new Error('Failed to delete comment'); |
|
|
|
const $conversationHolder = $this.closest('.conversation-holder'); |
|
|
|
|
|
|
|
const $parentTimelineItem = $this.closest('.timeline-item'); |
|
|
|
const conversationHolder = deleteButton.closest('.conversation-holder'); |
|
|
|
const $parentTimelineGroup = $this.closest('.timeline-item-group'); |
|
|
|
const parentTimelineItem = deleteButton.closest('.timeline-item'); |
|
|
|
|
|
|
|
const parentTimelineGroup = deleteButton.closest('.timeline-item-group'); |
|
|
|
|
|
|
|
|
|
|
|
// Check if this was a pending comment.
|
|
|
|
// Check if this was a pending comment.
|
|
|
|
if ($conversationHolder.find('.pending-label').length) { |
|
|
|
if (conversationHolder?.querySelector('.pending-label')) { |
|
|
|
const counter = document.querySelector('#review-box .review-comments-counter'); |
|
|
|
const counter = document.querySelector('#review-box .review-comments-counter'); |
|
|
|
let num = parseInt(counter?.getAttribute('data-pending-comment-number')) - 1 || 0; |
|
|
|
let num = parseInt(counter?.getAttribute('data-pending-comment-number')) - 1 || 0; |
|
|
|
num = Math.max(num, 0); |
|
|
|
num = Math.max(num, 0); |
|
|
@ -176,29 +181,32 @@ export function initRepoIssueCommentDelete() { |
|
|
|
counter.textContent = String(num); |
|
|
|
counter.textContent = String(num); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$(`#${$this.data('comment-id')}`).remove(); |
|
|
|
document.getElementById(deleteButton.getAttribute('data-comment-id'))?.remove(); |
|
|
|
if ($conversationHolder.length && !$conversationHolder.find('.comment').length) { |
|
|
|
|
|
|
|
const path = $conversationHolder.data('path'); |
|
|
|
if (conversationHolder && !conversationHolder.querySelector('.comment')) { |
|
|
|
const side = $conversationHolder.data('side'); |
|
|
|
const path = conversationHolder.getAttribute('data-path'); |
|
|
|
const idx = $conversationHolder.data('idx'); |
|
|
|
const side = conversationHolder.getAttribute('data-side'); |
|
|
|
const lineType = $conversationHolder.closest('tr').data('line-type'); |
|
|
|
const idx = conversationHolder.getAttribute('data-idx'); |
|
|
|
|
|
|
|
const lineType = conversationHolder.closest('tr').getAttribute('data-line-type'); |
|
|
|
|
|
|
|
|
|
|
|
if (lineType === 'same') { |
|
|
|
if (lineType === 'same') { |
|
|
|
$(`[data-path="${path}"] .add-code-comment[data-idx="${idx}"]`).removeClass('tw-invisible'); |
|
|
|
document.querySelector(`[data-path="${path}"] .add-code-comment[data-idx="${idx}"]`).classList.remove('tw-invisible'); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
$(`[data-path="${path}"] .add-code-comment[data-side="${side}"][data-idx="${idx}"]`).removeClass('tw-invisible'); |
|
|
|
document.querySelector(`[data-path="${path}"] .add-code-comment[data-side="${side}"][data-idx="${idx}"]`).classList.remove('tw-invisible'); |
|
|
|
} |
|
|
|
} |
|
|
|
$conversationHolder.remove(); |
|
|
|
|
|
|
|
|
|
|
|
conversationHolder.remove(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Check if there is no review content, move the time avatar upward to avoid overlapping the content below.
|
|
|
|
// Check if there is no review content, move the time avatar upward to avoid overlapping the content below.
|
|
|
|
if (!$parentTimelineGroup.find('.timeline-item.comment').length && !$parentTimelineItem.find('.conversation-holder').length) { |
|
|
|
if (!parentTimelineGroup?.querySelector('.timeline-item.comment') && !parentTimelineItem?.querySelector('.conversation-holder')) { |
|
|
|
const $timelineAvatar = $parentTimelineGroup.find('.timeline-avatar'); |
|
|
|
const timelineAvatar = parentTimelineGroup?.querySelector('.timeline-avatar'); |
|
|
|
$timelineAvatar.removeClass('timeline-avatar-offset'); |
|
|
|
timelineAvatar?.classList.remove('timeline-avatar-offset'); |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
} catch (error) { |
|
|
|
console.error(error); |
|
|
|
console.error(error); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -222,32 +230,35 @@ export function initRepoIssueDependencyDelete() { |
|
|
|
|
|
|
|
|
|
|
|
export function initRepoIssueCodeCommentCancel() { |
|
|
|
export function initRepoIssueCodeCommentCancel() { |
|
|
|
// Cancel inline code comment
|
|
|
|
// Cancel inline code comment
|
|
|
|
$(document).on('click', '.cancel-code-comment', (e) => { |
|
|
|
document.addEventListener('click', (e) => { |
|
|
|
const $form = $(e.currentTarget).closest('form'); |
|
|
|
if (!e.target.matches('.cancel-code-comment')) return; |
|
|
|
if ($form.length > 0 && $form.hasClass('comment-form')) { |
|
|
|
|
|
|
|
$form.addClass('tw-hidden'); |
|
|
|
const form = e.target.closest('form'); |
|
|
|
showElem($form.closest('.comment-code-cloud').find('button.comment-form-reply')); |
|
|
|
if (form?.classList.contains('comment-form')) { |
|
|
|
|
|
|
|
hideElem(form); |
|
|
|
|
|
|
|
showElem(form.closest('.comment-code-cloud')?.querySelectorAll('button.comment-form-reply')); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
$form.closest('.comment-code-cloud').remove(); |
|
|
|
form.closest('.comment-code-cloud')?.remove(); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
export function initRepoPullRequestUpdate() { |
|
|
|
export function initRepoPullRequestUpdate() { |
|
|
|
// Pull Request update button
|
|
|
|
// Pull Request update button
|
|
|
|
const $pullUpdateButton = $('.update-button > button'); |
|
|
|
const pullUpdateButton = document.querySelector('.update-button > button'); |
|
|
|
$pullUpdateButton.on('click', async function (e) { |
|
|
|
if (!pullUpdateButton) return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pullUpdateButton.addEventListener('click', async function (e) { |
|
|
|
e.preventDefault(); |
|
|
|
e.preventDefault(); |
|
|
|
const $this = $(this); |
|
|
|
const redirect = this.getAttribute('data-redirect'); |
|
|
|
const redirect = $this.data('redirect'); |
|
|
|
this.classList.add('is-loading'); |
|
|
|
$this.addClass('is-loading'); |
|
|
|
|
|
|
|
let response; |
|
|
|
let response; |
|
|
|
try { |
|
|
|
try { |
|
|
|
response = await POST($this.data('do')); |
|
|
|
response = await POST(this.getAttribute('data-do')); |
|
|
|
} catch (error) { |
|
|
|
} catch (error) { |
|
|
|
console.error(error); |
|
|
|
console.error(error); |
|
|
|
} finally { |
|
|
|
} finally { |
|
|
|
$this.removeClass('is-loading'); |
|
|
|
this.classList.remove('is-loading'); |
|
|
|
} |
|
|
|
} |
|
|
|
let data; |
|
|
|
let data; |
|
|
|
try { |
|
|
|
try { |
|
|
@ -266,10 +277,13 @@ export function initRepoPullRequestUpdate() { |
|
|
|
|
|
|
|
|
|
|
|
$('.update-button > .dropdown').dropdown({ |
|
|
|
$('.update-button > .dropdown').dropdown({ |
|
|
|
onChange(_text, _value, $choice) { |
|
|
|
onChange(_text, _value, $choice) { |
|
|
|
const $url = $choice.data('do'); |
|
|
|
const url = $choice[0].getAttribute('data-do'); |
|
|
|
if ($url) { |
|
|
|
if (url) { |
|
|
|
$pullUpdateButton.find('.button-text').text($choice.text()); |
|
|
|
const buttonText = pullUpdateButton.querySelector('.button-text'); |
|
|
|
$pullUpdateButton.data('do', $url); |
|
|
|
if (buttonText) { |
|
|
|
|
|
|
|
buttonText.textContent = $choice.text(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
pullUpdateButton.setAttribute('data-do', url); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
}); |
|
|
|
}); |
|
|
@ -367,10 +381,10 @@ export function initRepoIssueComments() { |
|
|
|
|
|
|
|
|
|
|
|
$('.re-request-review').on('click', async function (e) { |
|
|
|
$('.re-request-review').on('click', async function (e) { |
|
|
|
e.preventDefault(); |
|
|
|
e.preventDefault(); |
|
|
|
const url = $(this).data('update-url'); |
|
|
|
const url = this.getAttribute('data-update-url'); |
|
|
|
const issueId = $(this).data('issue-id'); |
|
|
|
const issueId = this.getAttribute('data-issue-id'); |
|
|
|
const id = $(this).data('id'); |
|
|
|
const id = this.getAttribute('data-id'); |
|
|
|
const isChecked = $(this).hasClass('checked'); |
|
|
|
const isChecked = this.classList.contains('checked'); |
|
|
|
|
|
|
|
|
|
|
|
await updateIssuesMeta(url, isChecked ? 'detach' : 'attach', issueId, id); |
|
|
|
await updateIssuesMeta(url, isChecked ? 'detach' : 'attach', issueId, id); |
|
|
|
window.location.reload(); |
|
|
|
window.location.reload(); |
|
|
@ -397,7 +411,7 @@ export function initRepoIssueComments() { |
|
|
|
export async function handleReply($el) { |
|
|
|
export async function handleReply($el) { |
|
|
|
hideElem($el); |
|
|
|
hideElem($el); |
|
|
|
const $form = $el.closest('.comment-code-cloud').find('.comment-form'); |
|
|
|
const $form = $el.closest('.comment-code-cloud').find('.comment-form'); |
|
|
|
$form.removeClass('tw-hidden'); |
|
|
|
showElem($form); |
|
|
|
|
|
|
|
|
|
|
|
const $textarea = $form.find('textarea'); |
|
|
|
const $textarea = $form.find('textarea'); |
|
|
|
let editor = getComboMarkdownEditor($textarea); |
|
|
|
let editor = getComboMarkdownEditor($textarea); |
|
|
@ -454,20 +468,20 @@ export function initRepoPullRequestReview() { |
|
|
|
|
|
|
|
|
|
|
|
$(document).on('click', '.show-outdated', function (e) { |
|
|
|
$(document).on('click', '.show-outdated', function (e) { |
|
|
|
e.preventDefault(); |
|
|
|
e.preventDefault(); |
|
|
|
const id = $(this).data('comment'); |
|
|
|
const id = this.getAttribute('data-comment'); |
|
|
|
$(this).addClass('tw-hidden'); |
|
|
|
hideElem(this); |
|
|
|
$(`#code-comments-${id}`).removeClass('tw-hidden'); |
|
|
|
showElem(`#code-comments-${id}`); |
|
|
|
$(`#code-preview-${id}`).removeClass('tw-hidden'); |
|
|
|
showElem(`#code-preview-${id}`); |
|
|
|
$(`#hide-outdated-${id}`).removeClass('tw-hidden'); |
|
|
|
showElem(`#hide-outdated-${id}`); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
$(document).on('click', '.hide-outdated', function (e) { |
|
|
|
$(document).on('click', '.hide-outdated', function (e) { |
|
|
|
e.preventDefault(); |
|
|
|
e.preventDefault(); |
|
|
|
const id = $(this).data('comment'); |
|
|
|
const id = this.getAttribute('data-comment'); |
|
|
|
$(this).addClass('tw-hidden'); |
|
|
|
hideElem(this); |
|
|
|
$(`#code-comments-${id}`).addClass('tw-hidden'); |
|
|
|
hideElem(`#code-comments-${id}`); |
|
|
|
$(`#code-preview-${id}`).addClass('tw-hidden'); |
|
|
|
hideElem(`#code-preview-${id}`); |
|
|
|
$(`#show-outdated-${id}`).removeClass('tw-hidden'); |
|
|
|
showElem(`#show-outdated-${id}`); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
$(document).on('click', 'button.comment-form-reply', async function (e) { |
|
|
|
$(document).on('click', 'button.comment-form-reply', async function (e) { |
|
|
@ -504,18 +518,19 @@ export function initRepoPullRequestReview() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$(document).on('click', '.add-code-comment', async function (e) { |
|
|
|
$(document).on('click', '.add-code-comment', async function (e) { |
|
|
|
if ($(e.target).hasClass('btn-add-single')) return; // https://github.com/go-gitea/gitea/issues/4745
|
|
|
|
if (e.target.classList.contains('btn-add-single')) return; // https://github.com/go-gitea/gitea/issues/4745
|
|
|
|
e.preventDefault(); |
|
|
|
e.preventDefault(); |
|
|
|
|
|
|
|
|
|
|
|
const isSplit = $(this).closest('.code-diff').hasClass('code-diff-split'); |
|
|
|
const isSplit = this.closest('.code-diff')?.classList.contains('code-diff-split'); |
|
|
|
const side = $(this).data('side'); |
|
|
|
const side = this.getAttribute('data-side'); |
|
|
|
const idx = $(this).data('idx'); |
|
|
|
const idx = this.getAttribute('data-idx'); |
|
|
|
const path = $(this).closest('[data-path]').data('path'); |
|
|
|
const path = this.closest('[data-path]')?.getAttribute('data-path'); |
|
|
|
const $tr = $(this).closest('tr'); |
|
|
|
const tr = this.closest('tr'); |
|
|
|
const lineType = $tr.data('line-type'); |
|
|
|
const lineType = tr.getAttribute('data-line-type'); |
|
|
|
|
|
|
|
|
|
|
|
let $ntr = $tr.next(); |
|
|
|
const ntr = tr.nextElementSibling; |
|
|
|
if (!$ntr.hasClass('add-comment')) { |
|
|
|
let $ntr = $(ntr); |
|
|
|
|
|
|
|
if (!ntr?.classList.contains('add-comment')) { |
|
|
|
$ntr = $(` |
|
|
|
$ntr = $(` |
|
|
|
<tr class="add-comment" data-line-type="${lineType}"> |
|
|
|
<tr class="add-comment" data-line-type="${lineType}"> |
|
|
|
${isSplit ? ` |
|
|
|
${isSplit ? ` |
|
|
@ -525,7 +540,7 @@ export function initRepoPullRequestReview() { |
|
|
|
<td class="add-comment-left add-comment-right" colspan="5"></td> |
|
|
|
<td class="add-comment-left add-comment-right" colspan="5"></td> |
|
|
|
`}
|
|
|
|
`}
|
|
|
|
</tr>`); |
|
|
|
</tr>`); |
|
|
|
$tr.after($ntr); |
|
|
|
$(tr).after($ntr); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const $td = $ntr.find(`.add-comment-${side}`); |
|
|
|
const $td = $ntr.find(`.add-comment-${side}`); |
|
|
@ -611,13 +626,13 @@ export function initRepoIssueTitleEdit() { |
|
|
|
|
|
|
|
|
|
|
|
const editTitleToggle = function () { |
|
|
|
const editTitleToggle = function () { |
|
|
|
toggleElem($issueTitle); |
|
|
|
toggleElem($issueTitle); |
|
|
|
toggleElem($('.not-in-edit')); |
|
|
|
toggleElem('.not-in-edit'); |
|
|
|
toggleElem($('#edit-title-input')); |
|
|
|
toggleElem('#edit-title-input'); |
|
|
|
toggleElem($('#pull-desc')); |
|
|
|
toggleElem('#pull-desc'); |
|
|
|
toggleElem($('#pull-desc-edit')); |
|
|
|
toggleElem('#pull-desc-edit'); |
|
|
|
toggleElem($('.in-edit')); |
|
|
|
toggleElem('.in-edit'); |
|
|
|
toggleElem($('.new-issue-button')); |
|
|
|
toggleElem('.new-issue-button'); |
|
|
|
$('#issue-title-wrapper').toggleClass('edit-active'); |
|
|
|
document.getElementById('issue-title-wrapper')?.classList.toggle('edit-active'); |
|
|
|
$editInput[0].focus(); |
|
|
|
$editInput[0].focus(); |
|
|
|
$editInput[0].select(); |
|
|
|
$editInput[0].select(); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|