GreasyFork Moderator Actions Log Viewer

to view GreasyFork Moderator Actions Log Table

Ekde 2023/05/23. Vidu La ĝisdata versio.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==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://greasyfork.org/*/moderator_actions*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=greasyfork.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...
})();