mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-29 12:04:17 +00:00
8babbe7ccf
Backport #29448 by @charles7668 issue : #28239 The counter number script uses the 'checkbox' attribute to determine whether an item is selected or not. However, the input event only increments the counter value, and when more items are displayed, it does not update all previously loaded items. As a result, the display becomes incorrect because it triggers the update counter script, but checkboxes that are selected without the 'checked' attribute are not counted Co-authored-by: charles <30816317+charles7668@users.noreply.github.com> (cherry picked from commit 5477728282de19b1638691b88449b1933ed5a4d8)
100 lines
4.5 KiB
JavaScript
100 lines
4.5 KiB
JavaScript
import {diffTreeStore} from '../modules/stores.js';
|
|
import {setFileFolding} from './file-fold.js';
|
|
import {POST} from '../modules/fetch.js';
|
|
|
|
const {pageData} = window.config;
|
|
const prReview = pageData.prReview || {};
|
|
const viewedStyleClass = 'viewed-file-checked-form';
|
|
const viewedCheckboxSelector = '.viewed-file-form'; // Selector under which all "Viewed" checkbox forms can be found
|
|
const expandFilesBtnSelector = '#expand-files-btn';
|
|
const collapseFilesBtnSelector = '#collapse-files-btn';
|
|
|
|
|
|
// Refreshes the summary of viewed files if present
|
|
// The data used will be window.config.pageData.prReview.numberOf{Viewed}Files
|
|
function refreshViewedFilesSummary() {
|
|
const viewedFilesProgress = document.getElementById('viewed-files-summary');
|
|
viewedFilesProgress?.setAttribute('value', prReview.numberOfViewedFiles);
|
|
const summaryLabel = document.getElementById('viewed-files-summary-label');
|
|
if (summaryLabel) summaryLabel.innerHTML = summaryLabel.getAttribute('data-text-changed-template')
|
|
.replace('%[1]d', prReview.numberOfViewedFiles)
|
|
.replace('%[2]d', prReview.numberOfFiles);
|
|
}
|
|
|
|
// Explicitly recounts how many files the user has currently reviewed by counting the number of checked "viewed" checkboxes
|
|
// Additionally, the viewed files summary will be updated if it exists
|
|
export function countAndUpdateViewedFiles() {
|
|
// The number of files is constant, but the number of viewed files can change because files can be loaded dynamically
|
|
prReview.numberOfViewedFiles = document.querySelectorAll(`${viewedCheckboxSelector} > input[type=checkbox][checked]`).length;
|
|
refreshViewedFilesSummary();
|
|
}
|
|
|
|
// Initializes a listener for all children of the given html element
|
|
// (for example 'document' in the most basic case)
|
|
// to watch for changes of viewed-file checkboxes
|
|
export function initViewedCheckboxListenerFor() {
|
|
for (const form of document.querySelectorAll(`${viewedCheckboxSelector}:not([data-has-viewed-checkbox-listener="true"])`)) {
|
|
// To prevent double addition of listeners
|
|
form.setAttribute('data-has-viewed-checkbox-listener', true);
|
|
|
|
// The checkbox consists of a div containing the real checkbox with its label and the CSRF token,
|
|
// hence the actual checkbox first has to be found
|
|
const checkbox = form.querySelector('input[type=checkbox]');
|
|
checkbox.addEventListener('input', function() {
|
|
// Mark the file as viewed visually - will especially change the background
|
|
if (this.checked) {
|
|
form.classList.add(viewedStyleClass);
|
|
checkbox.setAttribute('checked', '');
|
|
prReview.numberOfViewedFiles++;
|
|
} else {
|
|
form.classList.remove(viewedStyleClass);
|
|
checkbox.removeAttribute('checked');
|
|
prReview.numberOfViewedFiles--;
|
|
}
|
|
|
|
// Update viewed-files summary and remove "has changed" label if present
|
|
refreshViewedFilesSummary();
|
|
const hasChangedLabel = form.parentNode.querySelector('.changed-since-last-review');
|
|
hasChangedLabel?.remove();
|
|
|
|
const fileName = checkbox.getAttribute('name');
|
|
|
|
// check if the file is in our difftreestore and if we find it -> change the IsViewed status
|
|
const fileInPageData = diffTreeStore().files.find((x) => x.Name === fileName);
|
|
if (fileInPageData) {
|
|
fileInPageData.IsViewed = this.checked;
|
|
}
|
|
|
|
// Unfortunately, actual forms cause too many problems, hence another approach is needed
|
|
const files = {};
|
|
files[fileName] = this.checked;
|
|
const data = {files};
|
|
const headCommitSHA = form.getAttribute('data-headcommit');
|
|
if (headCommitSHA) data.headCommitSHA = headCommitSHA;
|
|
POST(form.getAttribute('data-link'), {data});
|
|
|
|
// Fold the file accordingly
|
|
const parentBox = form.closest('.diff-file-header');
|
|
setFileFolding(parentBox.closest('.file-content'), parentBox.querySelector('.fold-file'), this.checked);
|
|
});
|
|
}
|
|
}
|
|
|
|
export function initExpandAndCollapseFilesButton() {
|
|
// expand btn
|
|
document.querySelector(expandFilesBtnSelector)?.addEventListener('click', () => {
|
|
for (const box of document.querySelectorAll('.file-content[data-folded="true"]')) {
|
|
setFileFolding(box, box.querySelector('.fold-file'), false);
|
|
}
|
|
});
|
|
// collapse btn, need to exclude the div of “show more”
|
|
document.querySelector(collapseFilesBtnSelector)?.addEventListener('click', () => {
|
|
for (const box of document.querySelectorAll('.file-content:not([data-folded="true"])')) {
|
|
if (box.getAttribute('id') === 'diff-incomplete') continue;
|
|
setFileFolding(box, box.querySelector('.fold-file'), true);
|
|
}
|
|
});
|
|
}
|
|
|
|
|