Прошлые домены не функционирует! Используйте адрес
ARHIVACH.VC.
24 декабря 2023 г. Архивач восстановлен после серьёзной аварии. К сожалению, значительная часть сохранённых изображений и видео была потеряна.
Подробности случившегося. Мы призываем всех неравнодушных
помочь нам с восстановлением утраченного контента!
2. Делаешь пик 1-2-3
3. Сортируешь посты
4. ??????
5. Профит
пик 1. жмёшь одновременно shift ctrl I это ш
или правой кнопкой мыщи по части экрана и 'показать код элемента' пик 2(1).
пик 2. Найти в появившейся панели вкладку console (2.1, 2.2)
она может быть уже активна, может быть спратана в стрелочках (1.2)
пик 3. Вы должны увидеть появляется пик 3, вставить туда следущий код и нажать enter
пик 4 - результат
(() => {
const thread = document.querySelector('.thread');
if (!thread) return console.warn('Тред не найден');
const parseDate = s => {
const m = s.match(/(\d{2})\/(\d{2})\/(\d{2})\D+(\d{2}):(\d{2}):(\d{2})/);
if(!m) return 0;
return new Date(`20${m[3]}`, m[2]-1, m[1], m[4], m[5], m[6]).getTime();
};
const getPostsData = () => Array.from(thread.querySelectorAll('.post')).map(post => {
const id = post.id.split('-')[1];
const refmap = document.getElementById(`refmap-${id}`);
const repliesCount = refmap ? refmap.querySelectorAll('a').length : 0;
const timeEl = post.querySelector('.post__time');
const time = timeEl ? parseDate(timeEl.textContent) : 0;
const msg = post.querySelector('.post__message');
const textLen = msg ? msg.textContent.length : 0;
const isOp = post.classList.contains('post_type_oppost');
return {post, repliesCount, time, textLen, isOp};
});
// Сортируем, но OP всегда сверху
const sortAndRender = (arr, prop, desc = true) => {
arr.sort((a,b)=>{
if(a.isOp && !b.isOp) return -1;
if(!a.isOp && b.isOp) return 1;
return desc ? b[prop]-a[prop] : a[prop]-b[prop];
});
arr.forEach(({post})=>thread.appendChild(post));
};
// Создаем контейнер и кнопки
const container = document.createElement('div');
Object.assign(container.style,{
position:'fixed',bottom:'10px',right:'10px',zIndex:9999,
display:'flex',flexDirection:'column',gap:'5px',
background:'#fff',border:'1px solid #ccc',padding:'5px',borderRadius:'5px',
fontFamily:'sans-serif',fontSize:'12px',userSelect:'none',
width:'140px'
});
document.body.appendChild(container);
// Создаем кнопки и стрелки
const buttons = [
{name:'repliesCount', text:'По ответам'},
{name:'time', text:'По времени'},
{name:'textLen', text:'По объёму'}
];
let active = null; // {name, desc}
const createBtn = ({name,text}) => {
const btn = document.createElement('button');
btn.textContent = text;
btn.style = 'text-align:left;position:relative;padding-right:18px;cursor:pointer;';
const arrow = document.createElement('span');
arrow.style = 'position:absolute;right:6px;top:50%;transform:translateY(-50%);font-weight:bold;';
btn.appendChild(arrow);
btn.onclick = () => {
let desc = true;
if(active && active.name === name) desc = !active.desc; // переключаем направление
active = {name, desc};
updateButtons();
const data = getPostsData();
sortAndRender(data, name, desc);
};
return {btn, arrow, name};
};
const btnObjs = buttons.map(createBtn);
btnObjs.forEach(({btn})=>container.appendChild(btn));
const updateButtons = () => {
btnObjs.forEach(({btn,arrow,name})=>{
if(active && active.name === name){
arrow.textContent = active.desc ? '↓' : '↑';
btn.style.fontWeight = '700';
} else {
arrow.textContent = '';
btn.style.fontWeight = '400';
}
});
};
// Инициализация: сортируем по ответам по убыванию и показываем стрелку
active = {name:'time', desc:false};
updateButtons();
sortAndRender(getPostsData(), active.name, active.desc);
})();