您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Connexion automatique, boutons de téléchargement dans les résultats de recherche, prévisualisation des images de torrent, et bien d'autres améliorations très cool...
// ==UserScript== // @name YggTorrent Plus // @match https://www.yggtorrent.top/* // @version 1.5 // @author Binouchette // @license MIT // @description Connexion automatique, boutons de téléchargement dans les résultats de recherche, prévisualisation des images de torrent, et bien d'autres améliorations très cool... // @run-at document-end // @noframes // @grant GM.getValue // @grant GM.setValue // @grant GM.deleteValue // @grant GM_addStyle // @grant GM_getResourceURL // @grant GM_xmlhttpRequest // @namespace https://greasyfork.org/fr/scripts/537591-yggtorrent-plus // @icon https://www.google.com/s2/favicons?sz=64&domain=yggtorrent.top // ==/UserScript== (async function() { const CONFIG = { CHANGE_FONT: false, // Changer la police du site - Polices : 'Roboto Mono', 'Roboto Serif', 'Source Code Pro', OpenDyslexic HIDE_VOSTFR: true, // Afficher / masquer les films en VOSTFR FILTER_SIZE: true, // Filtrer par taille HIDE_OLD_TORRENTS: true, // Afficher / masquer les torrents vieux de X jours / année(s) RESIZE_COLUMNS: true, // Dans la liste des torrents, les tailles des colonnes sont plus harmonieuses RESIZE_COLUMNS_TODAY: true, // Dans la liste des torrents sur la page des "Torrents du jour", les tailles des colonnes sont plus harmonieuses DOWNLOAD_BUTTONS: true, // Ajoute un bouton pour télécharger un fichier dans la liste des torrents DOWNLOAD_BUTTONS_TODAY: true, // Ajoute un bouton pour télécharger un fichier dans la liste des torrents sur la page des "Torrents du jour" HOVER_TABLE: true, // Sur la liste des torrents, change la couleur de fond au passage de la souris LOGIN_AUTOMATICALLY: true, // Connexion automatique PREVIEWS_IMAGES_ON_HOVER: true, // Aperçu de l'image du torrent PREVIEWS_IMAGES_SIZE: 400, // Taille des images de prévisualisation (en pixels) HIDE_SIDEBAR: false, // Masquer la barre latérale LARGER_NFO: true, // Agrandir la fenêtre de prévisualisation du NFO SEARCH_BY_LATEST_FIRST: true, // Résultats de recherche par date de publication (du plus récent au plus ancien) KEEP_SEARCH_WHEN_CLICKING_ON_SUBCATEGORY_ICON: true, // Conserve les critères de recherche lorsqu'on clique sur une catégorie DARK_THEME: false, // Thème sombre }; const SELECTORS = { HOVER_TABLE_LIGNE: '.table-responsive', REGISTER_BUTTON: '.register', TORRENT_NAME_LINK: 'a[id="torrent_name"]', RESULTS_TABLE_ROW: '.results table tbody tr', INPUT_USERNAME: 'input[name="id"]', INPUT_PASSWORD: 'input[name="pass"]', INPUT_SUBMIT: 'button[type="submit"]', LOGOUT_LINK: 'a[href="https://www.yggtorrent.top/user/logout"]', NFO_MODAL: 'nfoModal', SEARCH_FORM: 'form.search', LOGIN_FORM: '.login-form', }; const CONSTANTS = { COOKIES_STORAGE_KEY: 'yggtorrent_credentials', MOUSEENTER_DELAY: 100, REGEX_URL: /engine\/search|torrents\/exclus/ }; /* Changer la Police */ async function changeFont() { const selectedFont = 'Source Code Pro'; // Roboto Mono, Roboto Serif, Source Code Pro, // Charger les polices Google Fonts const fontsLink = document.createElement('link'); fontsLink.rel = 'stylesheet'; fontsLink.href = 'https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&family=Roboto+Serif:ital,opsz,wght@0,8..144,100..900;1,8..144,100..900&family=Source+Code+Pro:ital,wght@0,200..900;1,200..900&display=swap'; document.head.appendChild(fontsLink); GM_addStyle(` @font-face { font-family: OpenDyslexic; src:url(https://opendyslexic.org/assets/fonts/OpenDyslexic3-d2c01a97d426dbf4de2e249d3c69da4d.woff2) format('woff2'), url(https://opendyslexic.org/assets/fonts/OpenDyslexic3-387e0788d88667639fca4731ef1e20c4.woff) format('woff'); font-weight: 400 !important; font-style: normal !important; font-display: swap !important; } * { font-family: '${selectedFont}', sans-serif !important; } `); } CONFIG.CHANGE_FONT && changeFont() GM_addStyle(` .hidden-vostfr { display: none !important; } `); async function hideLinesVostfr(masquer) { const lignes = document.querySelectorAll(SELECTORS.RESULTS_TABLE_ROW); const isVostRow = (ligne) => { const nameCell = ligne.querySelector('td:nth-child(2)'); if (!nameCell) return false; // Essaye le lien de nom officiel si présent, sinon tout le texte de la cellule const link = nameCell.querySelector(SELECTORS.TORRENT_NAME_LINK); const rawText = (link?.textContent || nameCell.textContent || '').trim(); // Normalise (retire les accents) puis majuscules const text = rawText .normalize('NFD').replace(/[\u0300-\u036f]/g, '') .toUpperCase(); // Variantes fréquentes return /\b(VOSTFR|VOST\-FR|VOST FR|SUBFRENCH|VOSTFRENCH)\b/.test(text); }; lignes.forEach((ligne) => { if (isVostRow(ligne)) { if (masquer) { ligne.classList.add('hidden-vostfr'); } else { ligne.classList.remove('hidden-vostfr'); } } }); } /*async function hideLinesVostfr(masquer) { const lignes = document.querySelectorAll(SELECTORS.RESULTS_TABLE_ROW); lignes.forEach((ligne) => { const td = ligne.querySelector('td:nth-child(2) a'); if (td && /SUBFRENCH|VOSTFR/i.test(td.textContent)) { ligne.style.display = masquer ? 'none' : ''; } }); }*/ async function buttonHideVostfr() { let etat = true; // true = masquer const btnVostfr = document.createElement('button'); btnVostfr.innerHTML = 'Afficher les VOSTFR'; btnVostfr.title = 'Afficher / masquer les torrents VOSTFR'; btnVostfr.style.background = 'linear-gradient(90deg, rgba(110, 225, 225, 1) 0%, rgba(110, 220, 200, 1) 50%, rgba(100, 220, 175, 1) 100%)'; btnVostfr.style.border = 'none'; btnVostfr.style.borderRadius = '.25rem'; btnVostfr.style.color = 'rgba(0, 0, 0, 1)'; btnVostfr.style.cursor = 'pointer'; btnVostfr.style.display = 'flex'; btnVostfr.style.alignItems = 'center'; btnVostfr.style.justifyContent = 'center'; btnVostfr.style.fontSize = '1rem'; btnVostfr.style.fontWeight = 'bold'; btnVostfr.style.margin = '0'; btnVostfr.style.padding = '1rem 2rem'; btnVostfr.style.position = 'absolute'; btnVostfr.style.right = '330px'; btnVostfr.style.top = '175px'; btnVostfr.style.width = '220px' btnVostfr.style.zIndex = '999'; let observer = null; function observeTable() { const tbody = document.querySelector('.results table tbody'); if (!tbody) return; if (observer) observer.disconnect(); observer = new MutationObserver(() => hideLinesVostfr(etat)); observer.observe(tbody, { childList: true, subtree: true }); } btnVostfr.addEventListener('click', () => { etat = !etat; hideLinesVostfr(etat); btnVostfr.innerHTML = etat ? 'Afficher les VOSTFR' : 'Masquer les VOSTFR'; }); document.body.appendChild(btnVostfr); observeTable(); hideLinesVostfr(etat); const mainObserver = new MutationObserver(observeTable); mainObserver.observe(document.body, { childList: true, subtree: true }); } if (CONSTANTS.REGEX_URL.test(window.location.href)) { CONFIG.HIDE_VOSTFR && buttonHideVostfr(); } /* Afficher / masquer les torrents vieux de 7, 14, 30 jours etc. */ async function buttonTime() { // Liste des jours à masquer const optionsJours = [0, 7, 14, 30, 60, 120, 180, 365, (365 * 2), (365 * 5), (365 * 8)]; let seuilActuel = 0; function hideOldTorrents(jours) { const lignes = document.querySelectorAll(SELECTORS.RESULTS_TABLE_ROW); const maintenant = new Date(); const seuilMs = jours * 24 * 60 * 60 * 1000; lignes.forEach((ligne) => { const tdAge = ligne.querySelector('td:nth-child(5)'); if (!tdAge) return; const hiddenTimestamp = tdAge.querySelector('div.hidden'); if (!hiddenTimestamp) return; const timestamp = parseInt(hiddenTimestamp.textContent.trim(), 10); if (isNaN(timestamp)) return; const dateTorrent = new Date(timestamp * 1000); const tropVieux = (maintenant - dateTorrent) > seuilMs; ligne.style.display = (jours === 0 || !tropVieux) ? '' : 'none'; }); } const container = document.createElement('div'); container.id = 'filter-container-date'; container.style.backgroundColor = 'rgba(250, 250, 250, 1)'; container.style.backgroundColor = 'rgba(250, 250, 250, 1)'; container.style.borderRadius = '.25rem'; container.style.display = 'flex'; container.style.alignItems = 'center'; container.style.justifyContent = 'center'; container.style.flexDirection = 'column'; container.style.fontSize = '1rem'; container.style.fontWeight = 'bold'; container.style.padding = '2rem 0'; container.style.position = 'absolute'; container.style.right = '330px'; container.style.top = '235px'; container.style.zIndex = '999'; container.style.width = '220px' function formatOptionLabel(jours) { if (jours === 0) return 'Tous'; if (jours % 365 === 0 && jours >= 365) { const annees = jours / 365; return `${annees} an${annees > 1 ? 's' : ''}`; } if (jours % 30 === 0 && jours >= 30) { const mois = jours / 30; return `${mois} mois`; } return `${jours} jour${jours > 1 ? 's' : ''}`; } const radioGroup = document.createElement('div'); radioGroup.style.display = 'flex'; container.style.alignItems = 'center'; container.style.justifyContent = 'center'; radioGroup.style.flexDirection = 'column'; radioGroup.style.flexWrap = 'wrap'; radioGroup.style.gap = '.5rem .75rem'; optionsJours.forEach((jours) => { const id = `filter-radio-${jours}`; const label = document.createElement('label'); label.setAttribute('for', id); label.style.alignItems = 'center'; label.style.backgroundColor = 'rgba(255, 255, 255, 1)'; label.style.border = '1px solid rgba(205, 210, 220, 1)'; label.style.borderRadius = '.25rem'; label.style.cursor = 'pointer'; label.style.display = 'flex'; label.style.padding = '.5rem .75rem'; const input = document.createElement('input'); input.type = 'radio'; input.name = 'jour'; input.value = jours; input.id = id; input.style.marginRight = '1rem'; if (jours === 0) { input.checked = true; hideOldTorrents(0); // affiche tout par défaut } input.addEventListener('change', () => { seuilActuel = parseInt(input.value, 10); hideOldTorrents(seuilActuel); }); label.appendChild(input); label.appendChild(document.createTextNode(formatOptionLabel(jours))); radioGroup.appendChild(label); }); container.appendChild(radioGroup); document.body.appendChild(container); } if (CONSTANTS.REGEX_URL.test(window.location.href)) { CONFIG.HIDE_OLD_TORRENTS && buttonTime(); } /* Largeurs des lignes */ async function styleLignesTd() { const lignes = document.querySelectorAll(SELECTORS.RESULTS_TABLE_ROW); lignes.forEach(ligne => { const tds = ligne.querySelectorAll('td'); if (tds[0]) { Object.assign(tds[0].style, { width: '90px', maxWidth: '90px', textAlign: 'center' }); } // Type if (tds[1]) { Object.assign(tds[1].style, { width: '720px', maxWidth: '720px', textAlign: 'left', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }); } // Nom if (tds[2]) { Object.assign(tds[2].style, { width: '120px', maxWidth: '120px', textAlign: 'center' }); } // NFO if (tds[3]) { Object.assign(tds[3].style, { width: '50px', maxWidth: '50px', textAlign: 'center' }); } // Commentaire if (tds[4]) { Object.assign(tds[4].style, { width: '150px', maxWidth: '150px', textAlign: 'center' }); } // Age if (tds[5]) { Object.assign(tds[5].style, { width: '70px', maxWidth: '70px', textAlign: 'center' }); } // Taille if (tds[6]) { Object.assign(tds[6].style, { width: '50px', maxWidth: '50px', textAlign: 'center' }); } // Complétés if (tds[7]) { Object.assign(tds[7].style, { width: '50px', maxWidth: '50px', textAlign: 'center' }); } // Sources if (tds[8]) { Object.assign(tds[8].style, { width: '50px', maxWidth: '50px', textAlign: 'center' }); } // Clients }); } CONFIG.RESIZE_COLUMNS && styleLignesTd(); /* Filtrer par taille */ async function buttonSize() { let minBytes = 0; const optionsGo = [0, 1, 2, 5, 10, 20, 50]; function parseSizeToBytes(txt) { if (!txt) { return NaN; } const s = txt.trim().replace(/\s+/g, ''); const m = s.match(/^([\d.,]+)\s*(ko|mo|go|to|kb|mb|gb|tb)$/i); if (!m) { return NaN; } const value = parseFloat(m[1].replace(',', '.')); const unit = m[2].toLowerCase(); const KB = 1024; const MB = 1024 * KB; const GB = 1024 * MB; const TB = 1024 * GB; switch (unit) { case 'ko': case 'kb': return value * KB; case 'mo': case 'mb': return value * MB; case 'go': case 'gb': return value * GB; case 'to': case 'tb': return value * TB; default: return NaN; } } function applySizeFilter(minB) { const rows = document.querySelectorAll(SELECTORS?.RESULTS_TABLE_ROW || '.results table tbody tr'); rows.forEach((tr) => { const td = tr.querySelector('td:nth-child(6)'); if (!td) { return; } const sizeTxt = td.textContent; const bytes = parseSizeToBytes(sizeTxt); if (isNaN(bytes)) { return; } tr.style.display = (minB === 0 || bytes >= minB) ? '' : 'none'; }); } const container = document.createElement('div'); container.id = 'filter-container-size'; container.style.backgroundColor = 'rgba(250, 250, 250, 1)'; container.style.borderRadius = '.25rem'; container.style.display = 'flex'; container.style.alignItems = 'center'; container.style.justifyContent = 'center'; container.style.flexDirection = 'column'; container.style.fontSize = '1rem'; container.style.fontWeight = 'bold'; container.style.padding = '2rem 0'; container.style.position = 'absolute'; container.style.right = '330px'; container.style.zIndex = '999'; container.style.width = '220px'; const title = document.createElement('div'); title.textContent = 'Taille'; title.style.marginBottom = '.75rem'; container.appendChild(title); const radioGroup = document.createElement('div'); radioGroup.style.display = 'flex'; radioGroup.style.flexDirection = 'column'; radioGroup.style.gap = '.5rem'; container.appendChild(radioGroup); function labelFor(go) { return go === 0 ? 'Tous' : `≥ ${go} Go`; } optionsGo.forEach((go) => { const id = `size-radio-${go}`; const label = document.createElement('label'); label.setAttribute('for', id); label.style.alignItems = 'center'; label.style.backgroundColor = 'rgba(255, 255, 255, 1)'; label.style.border = '1px solid rgba(205, 210, 220, 1)'; label.style.borderRadius = '.25rem'; label.style.cursor = 'pointer'; label.style.display = 'flex'; label.style.padding = '.5rem .75rem'; const input = document.createElement('input'); input.type = 'radio'; input.name = 'size-min'; input.value = go; input.id = id; input.style.marginRight = '1rem'; if (go === 0) { input.checked = true; } input.addEventListener('change', () => { minBytes = go === 0 ? 0 : go * 1024 * 1024 * 1024; // Go -> octets (base 1024) applySizeFilter(minBytes); }); label.appendChild(input); label.appendChild(document.createTextNode(labelFor(go))); radioGroup.appendChild(label); }); document.body.appendChild(container); const dateBox = document.getElementById('filter-container-date'); if (dateBox) { const rect = dateBox.getBoundingClientRect(); container.style.top = `${rect.bottom + 10}px`; } else { container.style.top = '540px'; } let observer = null; function observeTable() { const tbody = document.querySelector('.results table tbody'); if (!tbody) { return; } if (observer) observer.disconnect(); observer = new MutationObserver(() => applySizeFilter(minBytes)); observer.observe(tbody, { childList: true, subtree: true }); } observeTable(); applySizeFilter(minBytes); const mainObserver = new MutationObserver(observeTable); mainObserver.observe(document.body, { childList: true, subtree: true }); } if (CONSTANTS.REGEX_URL.test(window.location.href)) { CONFIG.FILTER_SIZE && buttonSize(); } /* Largeur des lignes des "Torrents du jours" (page spécial avec DataTables.js) */ async function applyColumnStylesToRow(row) { const tds = row.querySelectorAll('td'); const styles = [ { width: '90px', textAlign: 'center' }, { width: '720px', textAlign: 'left', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }, { width: '120px', textAlign: 'center' }, { width: '50px', textAlign: 'center' }, { width: '150px', textAlign: 'center' }, { width: '70px', textAlign: 'center' }, { width: '50px', textAlign: 'center' }, { width: '50px', textAlign: 'center' }, { width: '50px', textAlign: 'center' } ]; styles.forEach((style, index) => { if (tds[index]) { Object.assign(tds[index].style, { width: style.width, maxWidth: style.width, textAlign: style.textAlign, overflow: style.overflow || '', textOverflow: style.textOverflow || '', whiteSpace: style.whiteSpace || '' }); } }); } async function applyStylesToAllVisibleRows() { const tables = document.querySelectorAll('table[id^="DataTables_Table_"]'); tables.forEach(table => { const tbody = table.querySelector('tbody'); if (!tbody) return; const rows = tbody.querySelectorAll('tr'); rows.forEach(row => applyColumnStylesToRow(row)); }); } async function watchForNewTables() { const observer = new MutationObserver(() => { attachDrawHooks(); }); observer.observe(document.body, { childList: true, subtree: true }); } async function attachDrawHooks() { const tables = document.querySelectorAll('table[id^="DataTables_Table_"]'); tables.forEach(table => { if (table.dataset.stylesApplied === 'true') return; table.dataset.stylesApplied = 'true'; const dtInstance = $(table).DataTable(); dtInstance.on('draw', () => { const rows = table.querySelectorAll('tbody > tr'); rows.forEach(row => applyColumnStylesToRow(row)); }); const initialRows = table.querySelectorAll('tbody > tr'); initialRows.forEach(row => applyColumnStylesToRow(row)); }); } async function startStylingAllTables() { if (typeof $ === 'undefined' || !$.fn.DataTable) { setTimeout(startStylingAllTables, 300); return; } attachDrawHooks(); watchForNewTables(); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startStylingAllTables); } else { CONFIG.RESIZE_COLUMNS_TODAY && startStylingAllTables(); } /* Boutons Télécharger */ async function addCustomButtons() { const torrents = document.querySelectorAll(SELECTORS.RESULTS_TABLE_ROW); torrents.forEach(torrent => { const torrentId = torrent.querySelector('a[target]')?.target; if (!torrentId) return; const nomCell = torrent.querySelector('td:nth-child(2)'); let nom = ''; if (nomCell) { const nomLink = nomCell.querySelector('a'); // 'a#torrent_name' if (nomLink) { nom = nomLink.textContent.trim(); } } const downloadIcon = document.createElement('span'); downloadIcon.classList.add('ico_download', 'custom_ygg'); const downloadButton = document.createElement('a'); downloadButton.href = `/engine/download_torrent?id=${torrentId}`; downloadButton.title = `Télécharger le torrent`; const imgYGG = document.createElement('img'); imgYGG.src = 'https://i.ibb.co/hRcq4zSM/favicon-copie-min.png'; imgYGG.style = 'width: 20px;'; downloadButton.appendChild(imgYGG); downloadButton.style = 'margin-right: 10px; vertical-align: middle;'; const td = torrent.querySelector('td:nth-child(3)'); if (td) { td.querySelectorAll('.custom_ygg').forEach(el => el.remove()); td.prepend(downloadButton); } }); } if (CONSTANTS.REGEX_URL.test(window.location.href)) { CONFIG.DOWNLOAD_BUTTONS && addCustomButtons(); } /* Boutons Télécharger sur la pages des "Torrents du jours" (page spécial avec DataTables.js) */ async function addCustomButtonsToYggRows() { document.querySelectorAll('table[id^="DataTables_Table_"] > tbody > tr').forEach(tr => { const tds = tr.querySelectorAll('td'); if (tds.length < 3) return; const td = tds[2]; // Nettoyage des anciens boutons td.querySelectorAll('.custom_ygg').forEach(el => el.remove()); const nfoLink = td.querySelector('a[target]'); const torrentId = nfoLink ? nfoLink.getAttribute('target') : null; if (!torrentId) return; // Création du bouton de téléchargement const downloadButton = document.createElement('a'); downloadButton.href = `/engine/download_torrent?id=${torrentId}`; downloadButton.title = "Télécharger le torrent"; downloadButton.className = "custom_ygg"; downloadButton.style = 'margin-right: 10px; vertical-align: middle;'; const imgYGG = document.createElement('img'); imgYGG.src = 'https://i.ibb.co/7JzTJ2CY/favicon-1-min-1.png'; imgYGG.style = 'width: 20px;'; downloadButton.appendChild(imgYGG); td.prepend(downloadButton); }); } async function attachYggButtonHooksToAllTables() { const tables = document.querySelectorAll('table[id^="DataTables_Table_"]'); tables.forEach(table => { if (table.dataset.yggButtonsAttached === 'true') return; table.dataset.yggButtonsAttached = 'true'; const dt = $(table).DataTable(); dt.on('draw', () => { addCustomButtonsToYggRows(); }); // Exécution immédiate une fois addCustomButtonsToYggRows(); }); } async function watchYggButtonsOnTables() { // Attente que jQuery + DataTables soient chargés if (typeof $ === 'undefined' || !$.fn.DataTable) { setTimeout(watchYggButtonsOnTables, 300); return; } attachYggButtonHooksToAllTables(); // Surveiller si de nouvelles DataTables apparaissent const observer = new MutationObserver(() => { attachYggButtonHooksToAllTables(); }); observer.observe(document.body, { childList: true, subtree: true }); } // Lancer au bon moment if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', watchYggButtonsOnTables); } else { CONFIG.DOWNLOAD_BUTTONS_TODAY && watchYggButtonsOnTables(); } /* Changement de style au passage de la souris dans la liste des torrents */ async function hoverTable() { const style = document.createElement('style'); const lignes = document.querySelector(SELECTORS.HOVER_TABLE_LIGNE); if(lignes) { style.textContent = ` .results .table td { padding: .5rem !important; } .results .table tr:hover > * { color: rgba(0, 0, 0, 1) !important; background-color: rgba(0, 0, 0, 0.1) !important; } .results .table :not(caption) > * > * { box-shadow: inset 0 0 0 9999px transparent !important; } #get_nfo img { height: 20px !important; width: 20px !important; } `; document.head.appendChild(style); } } CONFIG.HOVER_TABLE && hoverTable(); /* Connexion automatique */ async function handleLogin() { const isNotLoggedIn = document.querySelector(SELECTORS.REGISTER_BUTTON); const savedCredentials = await GM.getValue(CONSTANTS.COOKIES_STORAGE_KEY); if (isNotLoggedIn && !savedCredentials) { await getCredentials(); } else if (isNotLoggedIn && savedCredentials) { await autoLogin(savedCredentials); } } async function getCredentials() { try { const loginForm = document.querySelector(SELECTORS.LOGIN_FORM); if (loginForm) { loginForm.addEventListener('submit', async (e) => { e.preventDefault(); const usernameInput = loginForm.querySelector(SELECTORS.INPUT_USERNAME); const passwordInput = loginForm.querySelector(SELECTORS.INPUT_PASSWORD); await saveCredentials(usernameInput.value, passwordInput.value); }); } } catch (error) { console.error('Error getting credentials:', error); } } async function autoLogin(credentials) { try { const loginForm = document.querySelector(SELECTORS.LOGIN_FORM); if (loginForm) { const usernameInput = loginForm.querySelector(SELECTORS.INPUT_USERNAME); const passwordInput = loginForm.querySelector(SELECTORS.INPUT_PASSWORD); const submitButton = loginForm.querySelector(SELECTORS.INPUT_SUBMIT); if (usernameInput && passwordInput && submitButton) { usernameInput.value = credentials.username; passwordInput.value = credentials.password; submitButton.click(); } } } catch (error) { console.error('Error during login:', error); } } const logoutLink = document.querySelector(SELECTORS.LOGOUT_LINK); if (logoutLink) { logoutLink.addEventListener('click', deleteCredentials); } async function deleteCredentials() { try { await GM.deleteValue(CONSTANTS.COOKIES_STORAGE_KEY); } catch (error) { console.error('Error deleting credentials:', error); } } async function saveCredentials(username, password) { try { await GM.setValue(CONSTANTS.COOKIES_STORAGE_KEY, { username, password }); } catch (error) { console.error('Error saving credentials:', error); } } CONFIG.LOGIN_AUTOMATICALLY && await handleLogin(); /* Aperçu de l'image du torrent */ function fetchImageSize(url) { return new Promise((resolve, reject) => { const img = new Image(); img.onload = () => resolve({ width: img.width, height: img.height, url }); img.onerror = reject; img.src = url; }); } function makeGetRequest(url) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'GET', url, onload: function(response) { resolve(response.responseText); }, onerror: function(error) { reject(error); }, }); }); } async function getImages(url) { const imageRet = []; try { const response = await makeGetRequest(url); const parser = new DOMParser(); const doc = parser.parseFromString(response, 'text/html'); if (doc.title.includes('Just a moment...')) { imageRet.push({ width: 500, height: 500, url: 'https://i.ibb.co/39tFNwS1/Error.png', }); return imageRet; } const imgElements = doc.getElementsByTagName('img'); for (const imgElement of imgElements) { if (imgElement.src.includes('summer_icon') || imgElement.src.includes('yggtorrent') || imgElement.src.includes('avatars') || imgElement.src.startsWith('data:image/png;base64')) { continue; } const image = await fetchImageSize(imgElement.src); if (image.width > 250 && image.height > 250) { imageRet.push(image); break; } } } catch (error) { console.error('Error fetching images:', error); } return imageRet; } function displayImageHandler() { createImageModal(); let timeout = null; let canDisplay = false; const torrents = document.querySelectorAll(SELECTORS.RESULTS_TABLE_ROW); if (!torrents) return; torrents.forEach((torrent) => { const torrentNameLink = torrent.querySelector(SELECTORS.TORRENT_NAME_LINK); if (!torrentNameLink) return; torrentNameLink.addEventListener('mouseenter', async (e) => { timeout = setTimeout(async () => { if (e.target.id !== 'torrent_name') return; canDisplay = true; const images = await getImages(e.target.href); if (canDisplay) { displayImageModal(e, images[0]); } }, CONSTANTS.MOUSEENTER_DELAY); }); torrentNameLink.addEventListener('mousemove', (e) => { const modal = document.getElementById('imageModal'); if (modal) { const mouseY = e.clientY - 25; const outOfScreen = mouseY + document.getElementById('imageModalImage').offsetHeight - window.innerHeight; modal.style.top = outOfScreen > -25 ? mouseY - outOfScreen - 25 + 'px' : mouseY + 'px'; modal.style.left = e.clientX + 125 + 'px'; } }); torrentNameLink.addEventListener('mouseout', () => { document.getElementById('imageModal').style.display = 'none'; canDisplay = false; clearTimeout(timeout); }); }); } function createImageModal() { const modal = document.createElement('div'); modal.id = 'imageModal'; modal.classList.add('modal'); modal.style.display = 'none'; const modalImage = document.createElement('img'); modalImage.id = 'imageModalImage'; modalImage.classList.add('modal-content'); modalImage.style = `min-width: ${CONFIG.PREVIEWS_IMAGES_SIZE}px; max-width: ${CONFIG.PREVIEWS_IMAGES_SIZE}px;`; modal.appendChild(modalImage); document.body.append(modal); } function displayImageModal(event, image) { const modal = document.getElementById('imageModal'); if (modal) { const mouseY = event.clientY - 25; const modalImage = document.getElementById('imageModalImage'); modalImage.src = image.url; modal.style.display = 'block'; modal.style.left = event.clientX + 125 + 'px'; const outOfScreen = mouseY + modalImage.offsetHeight - window.innerHeight; modal.style.top = outOfScreen > -25 ? mouseY - outOfScreen - 25 + 'px' : mouseY + 'px'; } } CONFIG.PREVIEWS_IMAGES_ON_HOVER && displayImageHandler(); /* Masquer la barre latérale */ function hideSidebar() { const sidebar = document.getElementById('cat'); if (sidebar && sidebar.classList.contains('active')) { sidebar.querySelector('.open').click(); } } CONFIG.HIDE_SIDEBAR && hideSidebar(); /* Modification du NFO */ function displayLargerNfo() { const modal = document.getElementById(SELECTORS.NFO_MODAL); if (!modal) return; const modalDialog = modal.querySelector('.modal-dialog'); modalDialog.classList.remove('modal-sm'); modalDialog.classList.add('modal-lg'); const nfoDiv = document.querySelector('#nfo'); if (nfoDiv) { GM_addStyle(` @import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap&display=swap'); `); GM_addStyle(` #nfo { padding: 0 !important; } #nfo pre { background-color: rgba(255, 255, 255, 1) !important; color: rgba(77, 77, 77, 1) !important; font-family: 'Source Code Pro', monospace !important; font-optical-sizing: auto !important; font-style: normal !important; font-weight: 500 !important; margin: 0 !important; padding: 2rem !important; text-align: center !important; } `); } } CONFIG.LARGER_NFO && displayLargerNfo(); /* Résultats de recherche par date de publication (du plus récent au plus ancien) */ function searchByLatestFirst() { const searchForm = document.querySelector(SELECTORS.SEARCH_FORM); if (!searchForm) return; const orderInput = document.createElement('input'); orderInput.name = 'order'; orderInput.value = 'desc'; orderInput.style = 'display: none'; const sortInput = document.createElement('input'); sortInput.name = 'sort'; sortInput.value = 'publish_date'; sortInput.style = 'display: none'; searchForm.append(orderInput); searchForm.append(sortInput); } CONFIG.SEARCH_BY_LATEST_FIRST && searchByLatestFirst(); /* Conserve les critères de recherche lorsqu'on clique sur une catégorie */ function keepSearchWhenClickingOnSubcategoryIcon() { document.querySelectorAll('[class^="tag_subcat_"]').forEach((node) => { const subcategoryId = node.className.split('tag_subcat_')[1]; node.parentNode.href = `${document.URL}&sub_category=${subcategoryId}`; }); } CONFIG.KEEP_SEARCH_WHEN_CLICKING_ON_SUBCATEGORY_ICON && keepSearchWhenClickingOnSubcategoryIcon(); /** * Thème Sombre * Par https://github.com/a-carvallo/YggTorrentDark * Dernière mise à jour : 25 mars 2025 */ async function darkTheme() { const customStyles = ` .donate.pulse{display:none}#middle .row .results tr:nth-child(odd) td{background-color:#3d444e;color:#cbd1da}#middle .row .results tr:nth-child(2n) td{background-color:#2c343f;color:#cbd1da}#middle .row .results tr td:nth-child(8){color:#4caf50}#middle .row .results tr td:nth-child(9){color:#f44336}#commentary li .message .add,#connect a:hover,#connect h3,#connect input:focus,#middle #commentary h4,#middle .comment h4,#middle .default font,#middle .row .results td .ico_comment,#middle .row table td a{color:#cbd1da}#middle .row .results td{background-color:#2c343f;border:1px solid #1b1e24;color:#cbd1da}#middle .row table td.adv_search_option,#middle .row table td:first-child,#middle .row table.infos-torrent td.adv_search_option,#middle .row table.infos-torrent td:first-child,.inbox thead th,.results thead th{background:#354150;color:#cbd1da}#middle .row .results tr:hover td{background:#245b44}#commentary,#middle .row .search-criteria,.card{background:#354150}#middle .row .search-criteria td.adv_search_option,#middle .row .search-criteria td:first-child{background:#354150;color:#cbd1da!important}#middle .row .search-criteria td,#middle .row table td:not(.bg-transparent),#middle .row table.infos-torrent td{background:#354150;color:#cbd1da;border-right:1px solid #1b1e24;border-bottom:1px solid #1b1e24}#middle .search-criteria td input{background:#2a313c;color:#6c798d}#middle .search-criteria td button.solo{transition:.1s ease-in-out;background:0 0;max-width:100%;color:#5ad9a4;top:-1px;font-size:11px;font-weight:700;text-transform:uppercase;border:3px solid #5ad9a4;border-radius:25px;padding:5px 10px}#middle .search-criteria td button.solo:hover{color:#fff;background:#5ad9a4;text-decoration:none}.form-control,.select2-selection__rendered{background:#2a313c;border:1px solid #1b1e24}.select2-container--bootstrap .select2-selection--single{background-color:#2a313c}#connect a,.field-label-responsive label,.form-control,.select2-container--bootstrap .select2-selection--single .select2-selection__rendered,.select2-selection__rendered,.wysibb-toolbar-btn{color:#6c798d}.select2-dropdown{background-color:#2a313c;color:#6c798d}.inbox thead td,.select2-container--bootstrap .select2-dropdown,.table-bordered{border:1px solid #1b1e24}.select2-container--bootstrap .select2-search--dropdown .select2-search__field{border:1px solid #1b1e24;background-color:#2a313c;color:#6c798d}.select2-container--bootstrap .select2-results__option[aria-selected=true]{background-color:#354150}.select2-container--bootstrap .select2-selection{background-color:#2a313c;border:1px solid #1b1e24!important}.select2-container--bootstrap .select2-selection .select2-selection__rendered{border:none}.select2-container,.select2-container--bootstrap{width:400px!important}input:focus{border-color:#6c798d!important;color:#cbd1da}#middle .pagination,#middle .pagination li a{background:#2a313c;color:#cbd1da}#nfoModal .modal-body,#nfoModal .modal-footer,div.bg-light,div.row.justify-content-center.py-5.bg-white{background-color:#354150!important}#middle .pagination li{border-left:1px solid #1b1e24}#middle .pagination li a:hover,.bottom-resize-line.drag,.bottom-resize-line:hover{background:#6c798d}.description-header{background:#354150;border-bottom:1px solid #1b1e24}#nfoModal .modal-footer,#nfoModal .modal-header{border-color:rgba(0,0,0,.125)}#middle table td .red{color:#ef5f5f}#middle .default{background:#354150!important;color:#cbd1da}#middle .default a{color:#5ad9a4}#nfoModal .modal-sm{max-width:60%!important}#nfoModal .modal-body{color:#cbd1da}#middle .add-comment,#middle .add-note{background:#354150;border-bottom:3px solid #6c798d}#commentary li{border-top:1px solid #6c798d}#commentary li .message{background:#6c798d;border:1px solid #6c798d}#commentary li .message:after,#commentary li .message:before{border-right:15px solid #6c798d}#commentary li .message a,.wysibb-body{color:#fff}#commentary li .left{background-color:#6c798d;border:1px solid #1b1e24}#comment-list li img[src$="/assets/img/avatar.jpg"],#middle section.content div.row div.card img[src$="/assets/img/avatar.jpg"]{filter:invert(70%)}#comment-list li .left .ratio{font-size:10px}#comment-list li .ratio .red{color:#b50616}#comment-list li .ratio .green{color:#0a490e}#comment-list .utilisateur .message{color:#eee}.wysibb{background:#354150;border:1px solid #1b1e24}.wysibb .wysibb-toolbar .wysibb-toolbar-container .wysibb-toolbar-btn .fonticon{color:#6c798d;text-shadow:none}.wysibb .wysibb-toolbar{border-bottom:1px solid #1b1e24}.wysibb .wysibb-toolbar .wysibb-toolbar-container{border-right:1px solid #1b1e24}#middle .row table td .input-table{background:#2a313c;color:#cbd1da;border:1px solid #1b1e24;border-radius:5px}#connect{background:#2c343f}#connect input{background:#2a313c;color:#6c798d;border-top:1px solid #1b1e24}.form-control:focus{background:#2a313c;color:#cbd1da;border-color:#6c798d!important}#middle .row table.detail-account{border-left:2px solid #6c798d}.card-footer{border-top:1px solid rgba(27,30,36,.4)!important;background:#354150}#top_panel img[src$="/assets/img/avatar.jpg"]{filter:invert(70%);border-color:rgba(0,0,0,.125)}.well{background-color:#343a40;border-color:rgba(0,0,0,.125)}.well[style^="background: #fff"]{background-color:#6c757d!important;border-color:rgba(0,0,0,.125)}.well[style^="background: #e0ffd7"]{background-color:#48a648!important}.well[style^="background: #f0f0f0"]{text-decoration:line-through;background-color:#555!important;border-color:rgba(0,0,0,.125)}.well strong[style^="color: #3b454e"]{color:#cbd1da!important}[role=button],a,area,button,input,label,select,summary,textarea{touch-action:auto}#middle #description .date,#middle .default .date{background:#2c343f;border-top:1px solid rgba(27,30,36,.4)}h4.text-dark,p.text-dark{color:#f8f9fa!important}.text-primary{color:#eff1f2!important}div.card.mb-0.border.border-dark{background-color:#434b56;border:1px solid #555!important}font.bg-white,table.bg-white{background-color:#434b56!important;border:1px solid #555!important}img.img-thumbnail{background-color:#434b56;border:1px solid #555}table.bg-white.table-hover tbody tr:hover{background-color:#333}#middle table.bg-white tbody tr td{border-right:1px solid #555;border-bottom:1px solid #555;border-top:1px solid #555}div font b span.text-danger{color:#28a745!important} `; GM_addStyle(customStyles); } CONFIG.DARK_THEME && darkTheme(); })();