gitea源码

pull-view-file.ts 4.5KB

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