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  }