Greasy Fork is available in English.

Hiện Join date

như tên

  1. // ==UserScript==
  2. // @name Hiện Join date
  3. // @namespace idmresettrial
  4. // @version 2021.05.18.03
  5. // @description như tên
  6. // @author You
  7. // @match https://voz.vn/t/*
  8. // @grant GM_setValue
  9. // @grant GM_getValue
  10. // @run-at document-start
  11. // @antifeature tracking
  12. // ==/UserScript==
  13.  
  14. document.addEventListener('DOMContentLoaded', function () {
  15. 'use strict';
  16.  
  17. const warningDate = new Date(new Date() - 3 * 30 * 86400 * 1000);
  18.  
  19. let cachedIds = GM_getValue("cachedIds", {});
  20. let dataVersion = 1;
  21. if (GM_getValue("dataVersion", 0) < dataVersion) {
  22. cachedIds = {};
  23. GM_setValue("dataVersion", dataVersion);
  24. }
  25.  
  26. function gnsJd(id) {
  27. if (Object.keys(cachedIds).includes(id)) {
  28. showJd(id);
  29. return;
  30. }
  31.  
  32. let token = document.getElementsByName("_xfToken")[0].value;
  33. let queryUrl = "https://voz.vn/u/{username}.{id}/?tooltip=true&_xfRequestUri={requestUri}&_xfWithData=1&_xfToken={token}&_xfResponseType=json";
  34. let username = document.querySelector(".message-userDetails a.username[data-user-id='" + id + "']").innerText;
  35. queryUrl = queryUrl
  36. .replace("{username}", encodeURIComponent(username))
  37. .replace("{id}", id)
  38. .replace("{requestUri}", document.location.pathname)
  39. .replace("{token}", token);
  40.  
  41. let httpRequest = new XMLHttpRequest();
  42. httpRequest.onreadystatechange = function() {
  43. if (httpRequest.readyState === XMLHttpRequest.DONE && httpRequest.status === 200) {
  44. let joindate = JSON.parse(httpRequest.responseText).html.content.match(/data-time=\"(.*?)\"/);
  45. if (joindate && !isNaN(Number(joindate[1]))) {
  46. cachedIds[id] = Number(joindate[1]);
  47. showJd(id);
  48. }
  49. }
  50. }
  51.  
  52. httpRequest.open("GET", queryUrl);
  53. httpRequest.send();
  54. }
  55.  
  56. let done = [];
  57. function showJd(id) {
  58. if (done.includes(id)) {
  59. return;
  60. }
  61.  
  62. let els = document.querySelectorAll(".message-userDetails a.username[data-user-id='" + id + "']");
  63. els.forEach(el => {
  64. let jd = new Date(cachedIds[id]*1000)
  65. jd = jd.toLocaleDateString("vi-VN") + (jd < warningDate ? "" : " *");
  66.  
  67. let jdEl = ('<h5 class="message-userTitle joindate" dir="auto" itemprop="joindate">Joined: {jd}</h5>{br}')
  68. .replace("{jd}", jd);
  69. let parent = el.parentElement.parentElement;
  70. let userBanners = parent.querySelectorAll(".userBanner");
  71.  
  72. jdEl = jdEl.replace("{br}", (userBanners.length >= 2)? "<br/>" : "");
  73. parent.querySelector("[itemProp=jobTitle]").insertAdjacentHTML('afterend', jdEl);
  74. });
  75.  
  76. done.push(id);
  77. }
  78.  
  79. window.addEventListener("beforeunload", function() {
  80. GM_setValue("cachedIds", cachedIds);
  81. });
  82.  
  83. function inoHandler(entries, observer) {
  84. entries.forEach(entry => {
  85. let id = entry.target.getAttribute("data-user-id");
  86. if (Object.keys(cachedIds).includes(id)) {
  87. observer.unobserve(entry.target);
  88. }
  89. gnsJd(id);
  90. });
  91. }
  92. let observer = new IntersectionObserver(inoHandler);
  93.  
  94. let els = document.querySelectorAll(".message-userDetails a.username");
  95. els.forEach(el => observer.observe(el));
  96.  
  97. let style = document.createElement('style');
  98. style.innerHTML = '@media (max-width: 751px) { .message-userTitle.joindate:before {content: ". "} }' +
  99. '@media (min-width: 752px) { .message-userTitle.joindate + br {display: none;} }';
  100. document.head.appendChild(style);
  101.  
  102.  
  103. });