// ==UserScript== // @name Oncheures // @namespace http://tampermonkey.net/ // @version 2.0 // @description Affichez les heures des posts comme sur JVC // @author Annapurna // @match https://onche.org/topic/* // ==/UserScript== function getThemeValue() { const cookieName = 'theme'; // Split document.cookie string into individual cookie key-value pairs const cookieArray = document.cookie.split(';'); // Iterate through each cookie key-value pair for (let i = 0; i < cookieArray.length; i++) { const cookie = cookieArray[i].trim(); // Trim any leading or trailing spaces // Check if the cookie starts with the specified cookieName if (cookie.startsWith(cookieName + '=')) { // Extract the value of the cookie return cookie.substring(cookieName.length + 1); // Add 1 to skip the '=' character } } // If the cookie with the specified name is not found, return null return null; } function getTimeColorBasedOnThemeValue() { const theme = getThemeValue(); switch (theme) { case 'grey': return "#79bcee"; break; case 'light': return "#1078c5"; break; case 'blue': return "#79bcee"; break; default: return null; break; } } function copyToClipboard(eventTarget, message){ const href = eventTarget.getAttribute('href'); navigator.clipboard.writeText(href); } // Get all message elements with class 'message' const messages = document.querySelectorAll('.message'); // Get the href content of the first occurrence of the class 'active' const hrefContent = document.querySelector('.active').href; // Loop through each message messages.forEach(message => { // Find the element with class 'message-date' within this message const messageDateElement = message.querySelector('.message-date'); // If such an element was found, extract the date and time from its title attribute using a regular expression if (messageDateElement) { const originalString = messageDateElement.getAttribute('title'); const regex = /(\d{2}\/\d{2}\/\d{4} à \d{2}:\d{2}:\d{2})/; const match = regex.exec(originalString); // Check if messageDateElement has a child element with class name containing 'color' const hasColorChild = messageDateElement.querySelector('[class*=color]') !== null; // If a match was found, create a new div element and set its inner HTML to the extracted date and time if (match) { const newLink = document.createElement('a'); const messageID = message.getAttribute('data-id'); newLink.href = hrefContent + '#message_' + messageID; // Add CSS styles to the new link element newLink.classList.add('my-link-class'); newLink.style.fontSize = '0.8125rem'; newLink.innerHTML = match[0]; if (hasColorChild) { // Set the inner HTML of the link to the extracted date and time const pemtDisplay = document.createElement('span'); pemtDisplay.innerHTML = ' (PEMT)'; pemtDisplay.style.color = 'red'; newLink.appendChild(pemtDisplay); } newLink.style.color = getTimeColorBasedOnThemeValue(); // Find the element with class 'message-infos' within this message and append the new link element to it const messageInfosElement = message.querySelector('.message-infos'); if (messageInfosElement) { messageInfosElement.appendChild(newLink); } if (messageDateElement.classList.contains('edited')) { const newLinkEdit = document.createElement('a'); newLinkEdit.href = hrefContent + '#message_' + messageID; newLinkEdit.classList.add('my-link-class'); newLinkEdit.style.fontSize = '0.8125rem'; newLinkEdit.style.color = getTimeColorBasedOnThemeValue(); newLinkEdit.style.display = 'flex'; const newLinkEditText = document.createElement('span'); //mdi-book-open-page-variant // 'edited' class is present in the classList of messageDateElement // Regex pattern to match the desired part const regexEdit = /modifié le (\d{2}\/\d{2}\/\d{4} à \d{2}:\d{2}:\d{2})/; // Match the pattern in the string const matchEdit = originalString.match(regexEdit); // Extract the captured group newLinkEditText.innerHTML = matchEdit[1]; const editLogo = document.createElement('div'); editLogo.classList.add('mdi', 'mdi-book-open-page-variant'); editLogo.style.marginRight = '7px'; newLinkEdit.appendChild(editLogo); // Now append newLinkEdit newLinkEdit.appendChild(newLinkEditText); // Now append newLinkEdit // Append editLogo before newLinkEdit messageInfosElement.appendChild(newLinkEdit); // Now append newLinkEdit newLinkEdit.addEventListener('click', event => { const newTarget = event.target.closest('a'); copyToClipboard(newTarget, message); }); } messageDateElement.remove(); // Add a click event listener to the new link that scrolls to the target message and copies its href attribute to the clipboard newLink.addEventListener('click', event => { copyToClipboard(event.target, message); }); } } }); const themeButtonDiv = document.getElementById('theme-button'); const myLinkElements = document.querySelectorAll('.my-link-class'); const topic = document.querySelector('#topic'); const rightContent = topic.querySelector('.right'); const newImg = document.createElement('img'); newImg.classList.add('response'); newImg.style.cursor = 'pointer'; function getButtonLinkBasedOnThemeValue() { const theme = getThemeValue(); switch (theme) { case 'grey': return 'https://codeberg.org/Annapurna/Oncheures/raw/branch/main/blackresp.png'; break; case 'light': return 'https://codeberg.org/Annapurna/Oncheures/raw/branch/main/whiteresp.png'; break; case 'blue': return 'https://codeberg.org/Annapurna/Oncheures/raw/branch/main/blueresp.png'; break; default: return null; break; } } themeButtonDiv.addEventListener('click', () => { // Update the src attribute of the element // Set a delay of 1000 milliseconds (1 second) setTimeout(() => { newImg.src = getButtonLinkBasedOnThemeValue(); myLinkElements.forEach(link => { link.style.color = getTimeColorBasedOnThemeValue(); }); }, 10); }); // Add a click event listener to the parent element topic.addEventListener('click', function (event) { // Check if the clicked element has the .response class if (event.target.classList.contains('response')) { // Scroll to the bottom of the page window.scrollTo(0, document.body.scrollHeight); } }); newImg.src = getButtonLinkBasedOnThemeValue(); rightContent.insertBefore(newImg, rightContent.firstChild);