code.gitea.io/gitea@v1.22.3/web_src/js/features/pull-view-file.js (about) 1 import {diffTreeStore} from '../modules/stores.js'; 2 import {setFileFolding} from './file-fold.js'; 3 import {POST} from '../modules/fetch.js'; 4 5 const {pageData} = window.config; 6 const prReview = pageData.prReview || {}; 7 const viewedStyleClass = 'viewed-file-checked-form'; 8 const viewedCheckboxSelector = '.viewed-file-form'; // Selector under which all "Viewed" checkbox forms can be found 9 const expandFilesBtnSelector = '#expand-files-btn'; 10 const collapseFilesBtnSelector = '#collapse-files-btn'; 11 12 // Refreshes the summary of viewed files if present 13 // The data used will be window.config.pageData.prReview.numberOf{Viewed}Files 14 function refreshViewedFilesSummary() { 15 const viewedFilesProgress = document.getElementById('viewed-files-summary'); 16 viewedFilesProgress?.setAttribute('value', prReview.numberOfViewedFiles); 17 const summaryLabel = document.getElementById('viewed-files-summary-label'); 18 if (summaryLabel) summaryLabel.innerHTML = summaryLabel.getAttribute('data-text-changed-template') 19 .replace('%[1]d', prReview.numberOfViewedFiles) 20 .replace('%[2]d', prReview.numberOfFiles); 21 } 22 23 // Explicitly recounts how many files the user has currently reviewed by counting the number of checked "viewed" checkboxes 24 // Additionally, the viewed files summary will be updated if it exists 25 export function countAndUpdateViewedFiles() { 26 // The number of files is constant, but the number of viewed files can change because files can be loaded dynamically 27 prReview.numberOfViewedFiles = document.querySelectorAll(`${viewedCheckboxSelector} > input[type=checkbox][checked]`).length; 28 refreshViewedFilesSummary(); 29 } 30 31 // Initializes a listener for all children of the given html element 32 // (for example 'document' in the most basic case) 33 // to watch for changes of viewed-file checkboxes 34 export function initViewedCheckboxListenerFor() { 35 for (const form of document.querySelectorAll(`${viewedCheckboxSelector}:not([data-has-viewed-checkbox-listener="true"])`)) { 36 // To prevent double addition of listeners 37 form.setAttribute('data-has-viewed-checkbox-listener', true); 38 39 // The checkbox consists of a div containing the real checkbox with its label and the CSRF token, 40 // hence the actual checkbox first has to be found 41 const checkbox = form.querySelector('input[type=checkbox]'); 42 checkbox.addEventListener('input', function() { 43 // Mark the file as viewed visually - will especially change the background 44 if (this.checked) { 45 form.classList.add(viewedStyleClass); 46 checkbox.setAttribute('checked', ''); 47 prReview.numberOfViewedFiles++; 48 } else { 49 form.classList.remove(viewedStyleClass); 50 checkbox.removeAttribute('checked'); 51 prReview.numberOfViewedFiles--; 52 } 53 54 // Update viewed-files summary and remove "has changed" label if present 55 refreshViewedFilesSummary(); 56 const hasChangedLabel = form.parentNode.querySelector('.changed-since-last-review'); 57 hasChangedLabel?.remove(); 58 59 const fileName = checkbox.getAttribute('name'); 60 61 // check if the file is in our difftreestore and if we find it -> change the IsViewed status 62 const fileInPageData = diffTreeStore().files.find((x) => x.Name === fileName); 63 if (fileInPageData) { 64 fileInPageData.IsViewed = this.checked; 65 } 66 67 // Unfortunately, actual forms cause too many problems, hence another approach is needed 68 const files = {}; 69 files[fileName] = this.checked; 70 const data = {files}; 71 const headCommitSHA = form.getAttribute('data-headcommit'); 72 if (headCommitSHA) data.headCommitSHA = headCommitSHA; 73 POST(form.getAttribute('data-link'), {data}); 74 75 // Fold the file accordingly 76 const parentBox = form.closest('.diff-file-header'); 77 setFileFolding(parentBox.closest('.file-content'), parentBox.querySelector('.fold-file'), this.checked); 78 }); 79 } 80 } 81 82 export function initExpandAndCollapseFilesButton() { 83 // expand btn 84 document.querySelector(expandFilesBtnSelector)?.addEventListener('click', () => { 85 for (const box of document.querySelectorAll('.file-content[data-folded="true"]')) { 86 setFileFolding(box, box.querySelector('.fold-file'), false); 87 } 88 }); 89 // collapse btn, need to exclude the div of “show more” 90 document.querySelector(collapseFilesBtnSelector)?.addEventListener('click', () => { 91 for (const box of document.querySelectorAll('.file-content:not([data-folded="true"])')) { 92 if (box.getAttribute('id') === 'diff-incomplete') continue; 93 setFileFolding(box, box.querySelector('.fold-file'), true); 94 } 95 }); 96 }