Before you install, Greasy Fork would like you to know that this script contains antifeatures, which are things there for the script author's benefit, rather than yours.
This script contains code that will track your browsing.
Greasy Fork is available in English.
như tên
// ==UserScript== // @name Hiện Join date // @namespace idmresettrial // @version 2021.05.18.03 // @description như tên // @author You // @match https://voz.vn/t/* // @grant GM_setValue // @grant GM_getValue // @run-at document-start // @antifeature tracking // ==/UserScript== document.addEventListener('DOMContentLoaded', function () { 'use strict'; const warningDate = new Date(new Date() - 3 * 30 * 86400 * 1000); let cachedIds = GM_getValue("cachedIds", {}); let dataVersion = 1; if (GM_getValue("dataVersion", 0) < dataVersion) { cachedIds = {}; GM_setValue("dataVersion", dataVersion); } function gnsJd(id) { if (Object.keys(cachedIds).includes(id)) { showJd(id); return; } let token = document.getElementsByName("_xfToken")[0].value; let queryUrl = "https://voz.vn/u/{username}.{id}/?tooltip=true&_xfRequestUri={requestUri}&_xfWithData=1&_xfToken={token}&_xfResponseType=json"; let username = document.querySelector(".message-userDetails a.username[data-user-id='" + id + "']").innerText; queryUrl = queryUrl .replace("{username}", encodeURIComponent(username)) .replace("{id}", id) .replace("{requestUri}", document.location.pathname) .replace("{token}", token); let httpRequest = new XMLHttpRequest(); httpRequest.onreadystatechange = function() { if (httpRequest.readyState === XMLHttpRequest.DONE && httpRequest.status === 200) { let joindate = JSON.parse(httpRequest.responseText).html.content.match(/data-time=\"(.*?)\"/); if (joindate && !isNaN(Number(joindate[1]))) { cachedIds[id] = Number(joindate[1]); showJd(id); } } } httpRequest.open("GET", queryUrl); httpRequest.send(); } let done = []; function showJd(id) { if (done.includes(id)) { return; } let els = document.querySelectorAll(".message-userDetails a.username[data-user-id='" + id + "']"); els.forEach(el => { let jd = new Date(cachedIds[id]*1000) jd = jd.toLocaleDateString("vi-VN") + (jd < warningDate ? "" : " *"); let jdEl = ('<h5 class="message-userTitle joindate" dir="auto" itemprop="joindate">Joined: {jd}</h5>{br}') .replace("{jd}", jd); let parent = el.parentElement.parentElement; let userBanners = parent.querySelectorAll(".userBanner"); jdEl = jdEl.replace("{br}", (userBanners.length >= 2)? "<br/>" : ""); parent.querySelector("[itemProp=jobTitle]").insertAdjacentHTML('afterend', jdEl); }); done.push(id); } window.addEventListener("beforeunload", function() { GM_setValue("cachedIds", cachedIds); }); function inoHandler(entries, observer) { entries.forEach(entry => { let id = entry.target.getAttribute("data-user-id"); if (Object.keys(cachedIds).includes(id)) { observer.unobserve(entry.target); } gnsJd(id); }); } let observer = new IntersectionObserver(inoHandler); let els = document.querySelectorAll(".message-userDetails a.username"); els.forEach(el => observer.observe(el)); let style = document.createElement('style'); style.innerHTML = '@media (max-width: 751px) { .message-userTitle.joindate:before {content: ". "} }' + '@media (min-width: 752px) { .message-userTitle.joindate + br {display: none;} }'; document.head.appendChild(style); });