Дата: Вторник, 14.10.2025, 03:05 | Сообщение # 1 |
|
Написал: Начинающий
Автор темы
Мурчанн
не в сети
Сообщений: 101
Логика: Никаких поисков реальных аватарок , а фиксированная дефолтная ава , везде и внутри и в теле письма и в списке сообщений Вставляете в самом низу шаблона , перед закрывающем тегом бодиКод
<script> (function(){ 'use strict'; const DEFAULT_AVATAR = "https://jordan.moy.su/ava/avapm.png"; const CACHE_KEY = "pmAvatarCache_vFinal"; const CHECK_DELAY = 150; let cache = {}; try { cache = JSON.parse(localStorage.getItem(CACHE_KEY) || "{}"); } catch(e){ cache = {}; } function saveCache(){ localStorage.setItem(CACHE_KEY, JSON.stringify(cache)); } async function fetchAvatar(profileUrl){ try { const res = await fetch(profileUrl, {cache: "no-cache"}); if(!res.ok) return null; const txt = await res.text(); const doc = new DOMParser().parseFromString(txt, "text/html"); const img = doc.querySelector('img[src*="/avatar/"], img[src*="/ava/"], .user_avatar img, .avatar img'); if(img && img.src){ const src = new URL(img.src, profileUrl).href; if(/noavatar|default|empty/i.test(src)) return null; return src; } } catch(e){ console.warn("fetchAvatar error", profileUrl, e); } return null; } function buildProfileUrls(username){ if(!username) return []; const safe = encodeURIComponent(username.replace(/\s+/g,'-')); return [ location.origin + '/index/8-0-' + safe, location.origin + '/index/8-0-' + username ]; } async function getAvatar(username){ if(!username) return DEFAULT_AVATAR; if(cache[username]) return cache[username]; const urls = buildProfileUrls(username); for(const u of urls){ const found = await fetchAvatar(u); if(found){ cache[username] = found; saveCache(); return found; } await new Promise(r=>setTimeout(r,CHECK_DELAY)); } cache[username] = DEFAULT_AVATAR; saveCache(); return DEFAULT_AVATAR; } async function insertAvatar(container, username){ if(!container || !username) return; const src = await getAvatar(username); // Скрываем букву const letters = container.querySelectorAll('.avatarLetter'); letters.forEach(l=>l.style.visibility='hidden'); let overlay = container.querySelector('.avatarOverlay'); if(!overlay){ overlay = document.createElement('div'); overlay.className = 'avatarOverlay'; overlay.style.position = 'absolute'; overlay.style.top = '0'; overlay.style.left = '0'; overlay.style.width = '60px'; overlay.style.height = '60px'; overlay.style.overflow = 'hidden'; overlay.style.zIndex = '10'; container.style.position = 'relative'; container.appendChild(overlay); } overlay.innerHTML = ''; const img = document.createElement('img'); img.src = src || DEFAULT_AVATAR; img.alt = username; img.style.width = '100%'; img.style.height = '100%'; img.style.objectFit = 'cover'; img.style.borderRadius = '2px'; img.onerror = ()=>{ img.src = DEFAULT_AVATAR; }; overlay.appendChild(img); } function findSender(row){ // Ищем текст "От:" или первую ссылку профиля, не совпадающую с получателем const fromCell = Array.from(row.querySelectorAll('td, span, div')).find(el=>{ const text = (el.textContent||'').toLowerCase(); return /(^|\s)от(\:|\s)/i.test(text) || /отправитель/i.test(text); }); if(fromCell){ const a = fromCell.querySelector('a[href]'); if(a) return a.textContent.trim(); return (fromCell.textContent||'').replace(/От:/i,'').trim(); } // fallback: первая ссылка на профиль const a = row.querySelector('a[href*="/index/8-0-"], a[href*="/users/"], a.profile-link'); if(a) return a.textContent.trim(); return null; } async function processRows(root=document){ const rows = Array.from(root.querySelectorAll('.userpm-messages-table tr[id^="ent"], .userpm-message-table')); for(const row of rows){ if(row.dataset._avatarInjected === "1") continue; const senderName = findSender(row); const avatarCell = row.querySelector('.r_round, .avatar, .pm_avatar, td:first-child'); if(senderName && avatarCell){ await insertAvatar(avatarCell, senderName); } row.dataset._avatarInjected = "1"; await new Promise(r=>setTimeout(r,CHECK_DELAY)); } } async function init(){ await processRows(); const table = document.querySelector('.userpm-messages-table, .userpm-message-table'); if(table){ const obs = new MutationObserver(()=> setTimeout(()=>processRows(),200)); obs.observe(table,{childList:true,subtree:true}); } else { const obs2 = new MutationObserver(()=> setTimeout(()=>processRows(),400)); obs2.observe(document.body,{childList:true,subtree:true}); } } // Небольшой стиль (function addStyles(){ const css = `.avatarOverlay img:hover { transform: scale(1.04); transition: transform .18s ease; }`; const st = document.createElement('style'); st.textContent = css; document.head.appendChild(st); })(); if(document.readyState==='loading') document.addEventListener('DOMContentLoaded', init); else init(); })(); </script>
Признаюсь, не знаю почему, но глядя на звезды мне всегда хочется мечтать.