GreasyFork Moderator Actions Log Viewer

to view GreasyFork Moderator Actions Log Table

נכון ליום 23-05-2023. ראה הגרסה האחרונה.

// ==UserScript==
// @name         GreasyFork Moderator Actions Log Viewer
// @namespace    http://tampermonkey.net/
// @version      0.1.0
// @description  to view GreasyFork Moderator Actions Log Table
// @author       CY Fung
// @match        https://gf.zukizuki.org/*/moderator_actions*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=gf.zukizuki.org
// @grant        none
// @run-at document-idle
// @license MIT
// ==/UserScript==

(function () {
  'use strict';

  function formatDateToCustomFormat(date) {
    var year = date.getFullYear();
    var month = padZero(date.getMonth() + 1);
    var day = padZero(date.getDate());
    var hours = padZero(date.getHours());
    var minutes = padZero(date.getMinutes());
    var timeZoneOffset = getTimeZoneOffsetString();

    return year + '.' + month + '.' + day + ' ' + hours + ':' + minutes + ' (GMT' + timeZoneOffset + ')';
  }

  function padZero(value) {
    return value.toString().padStart(2, '0');
  }

  function getTimeZoneOffsetString() {
    var offsetMinutes = new Date().getTimezoneOffset();
    var sign = offsetMinutes > 0 ? '-' : '+';
    var offsetHours = Math.floor(Math.abs(offsetMinutes) / 60);

    return sign + offsetHours;
  }



  for (const s of document.querySelectorAll('.log-table td:nth-child(1) relative-time:not(.jsm)')) {

    s.classList.add('jsm')

    let date = s.date;
    if (date) {

      let e = document.createElement('div');
      let q = formatDateToCustomFormat(date);
      q = q.split(' ');
      // e.textContent = formatDateToCustomFormat(date);
      e.className = 'date-entry';
      s.classList.add('jsm-hidden')
      s.after(e)

      e.appendChild(Object.assign(document.createElement('span'), {
        className: 'date-entry-date',

        textContent: q[0]
      }));

      e.appendChild(Object.assign(document.createElement('span'), {
        className: 'date-entry-time',

        textContent: q[1]
      }));

      e.appendChild(Object.assign(document.createElement('span'), {
        className: 'date-entry-gmt',
        textContent: q[2]
      }));
    }


  }


  for (const s of document.querySelectorAll('.log-table td:nth-child(3) a[href*="/scripts/"]:not(.jsm)')) {



    s.classList.add('jsm')
    let m = /\/scripts\/(\d+)/.exec(s.href);
    if (m) {
      let e = document.createElement('div');
      e.className = 'script-entry';
      s.replaceWith(e);
      e.appendChild(s);

      let span = document.createElement('span');
      span.className = 'entry-rid';
      span.textContent = m[1]
      e.prepend(span)
    }


  }


  for (const s of document.querySelectorAll('.log-table td:nth-child(3) a[href*="/users/"]:not(.jsm)')) {



    s.classList.add('jsm')
    let m = /\/users\/(\d+)/.exec(s.href);
    if (m) {
      let e = document.createElement('div');
      e.className = 'user-entry';
      s.replaceWith(e);
      e.appendChild(s);

      let span = document.createElement('span');
      span.className = 'entry-rid';
      span.textContent = m[1]
      e.prepend(span)
    }


  }


  function convertToAdvancedTable(tableSelector) {
    // Get the table element
    var table = document.querySelector(tableSelector);

    // Add classes to the table and its components
    table.classList.add('advanced-table');
    table.tHead.classList.add('advanced-table-head');
    table.tBodies[0].classList.add('advanced-table-body');

    // Get the table headers
    var headers = Array.from(table.tHead.rows[0].cells);

    var sortOrder = []; // Track sort order for each column

    // Add classes and event listeners to enable sorting
    headers.forEach(function (header, index) {
      header.classList.add('sortable');
      header.addEventListener('click', function (event) {
        if (!event.target.classList.contains('search-input')) {
          sortTable(table, index, sortOrder);
          sortOrder[index] = !sortOrder[index]; // Toggle sort order
        }
      });

      // Create search input element
      var searchInput = document.createElement('input');
      searchInput.setAttribute('type', 'text');
      searchInput.setAttribute('placeholder', 'Search');
      searchInput.classList.add('search-input');
      searchInput.addEventListener('input', function () {
        filterTable(table, index);
      });
      header.appendChild(searchInput);

      // Create sort icon element
      var sortIcon = document.createElement('span');
      sortIcon.classList.add('sort-icon');
      header.appendChild(sortIcon);
    });
  }

  // Function to sort the table by column index
  function sortTable(table, columnIndex, sortOrder) {
    var rows = Array.from(table.tBodies[0].rows);

    rows.sort(function (a, b) {
      var cellA = a.cells[columnIndex].textContent.toLowerCase();
      var cellB = b.cells[columnIndex].textContent.toLowerCase();

      if (sortOrder[columnIndex]) {
        // Sort in descending order
        if (cellA < cellB) return 1;
        if (cellA > cellB) return -1;
        return 0;
      } else {
        // Sort in ascending order
        if (cellA < cellB) return -1;
        if (cellA > cellB) return 1;
        return 0;
      }
    });

    table.tBodies[0].innerHTML = '';
    rows.forEach(function (row) {
      table.tBodies[0].appendChild(row);
    });
  }

  // Function to filter the table by column index
  function filterTable(table, columnIndex) {
    var filterValue = table.tHead.rows[0].cells[columnIndex].querySelector('.search-input').value.toLowerCase();
    var rows = Array.from(table.tBodies[0].rows);

    rows.forEach(function (row) {
      var cellValue = row.cells[columnIndex].textContent.toLowerCase();
      row.style.display = cellValue.includes(filterValue) ? '' : 'none';
    });
  }


  const colsize = (idx) => `.log-table th:nth-child(${idx}), .log-table td:nth-child(${idx}){width:${colsizes[idx - 1]}; max-width:${colsizes[idx - 1]};}`

  let colsizes = [8, 10, 30, 12, 25];
  let colsizeSum = colsizes.reduce((a, b) => a + b, 0);
  colsizes = colsizes.map(t => (t / colsizeSum * 100).toFixed(2) + '%');

  document.head.appendChild(document.createElement('style')).textContent = `
.advanced-table-head th {
  position: relative;
  padding: 8px;
}

.sortable {
  cursor: pointer;
}

.sort-icon {
  position: absolute;
  top: 50%;
  right: 8px;
  transform: translateY(-50%);
  width: 8px;
  height: 8px;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  transition: transform 0.2s ease;
}

.sortable.asc .sort-icon {
  border-bottom: 4px solid #000;
}

.sortable.desc .sort-icon {
  border-top: 4px solid #000;
}

.search-input {
  width: 100%;
  box-sizing: border-box;
  padding: 4px;
  border: 1px solid #ccc;
  border-radius: 4px;
}



		${colsize(1)}
		${colsize(2)}
		${colsize(3)}
		${colsize(4)}
		${colsize(5)}


/* Shared styles for both ".user-entry > .entry-rid" and ".script-entry > .entry-rid" */
.user-entry > .entry-rid,
.script-entry > .entry-rid {
  display: inline-block;
  padding: 4px 8px;
  color: #fff; /* Set an appropriate white text color */
  border-radius: 8px; /* Set the desired border radius */
  transition: background-color 0.3s; /* Add transition effect */
}

/* Styles for ".user-entry > .entry-rid" */
.user-entry > .entry-rid {
  background-color: #4287f5; /* Set your desired background color */
}

.user-entry > .entry-rid:hover {
  background-color: #1b4a99; /* Set your desired hover background color */
}

/* Styles for ".script-entry > .entry-rid" */
.script-entry > .entry-rid {
  background-color: #f57d1f; /* Set your desired background color */
}

.script-entry > .entry-rid:hover {
  background-color: #994d17; /* Set your desired hover background color */
}

relative-time.jsm-hidden {
display:none;
}

.date-entry-date{

  display: inline-block;
  padding: 4px 8px;
  color: #fff; /* Set an appropriate white text color */
  border-radius: 8px; /* Set the desired border radius */
  transition: background-color 0.3s; /* Add transition effect */
  font-size:70%;
  background-color: #9932cc;
}


.date-entry-time{

  display: inline-block;
  padding: 4px 8px;
  color: #fff; /* Set an appropriate white text color */
  border-radius: 8px; /* Set the desired border radius */
  transition: background-color 0.3s; /* Add transition effect */
  font-size:70%;
  background-color: #dc143c;
}

.date-entry-gmt{

  display: inline-block;
  padding: 4px 8px;
  color: #fff; /* Set an appropriate white text color */
  border-radius: 8px; /* Set the desired border radius */
  transition: background-color 0.3s; /* Add transition effect */
  font-size:40%;
  background-color: #3cb371;

}

`



  convertToAdvancedTable('table.log-table')

  // Your code here...
})();