Skip to content

Instantly share code, notes, and snippets.

@xiaoxiaoflood
Created October 28, 2021 18:52
Show Gist options
  • Save xiaoxiaoflood/6dc7a804d9cce7cc2c3e828dc4970a83 to your computer and use it in GitHub Desktop.
Save xiaoxiaoflood/6dc7a804d9cce7cc2c3e828dc4970a83 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name VK Xiao - Ordena tópicos no fórum
// @namespace https://vk.com/xiaoxiaoflood
// @match https://vk.com/board*
// @match https://oauth.vk.com/blank.html
// @version 1.0
// @grant none
// @run-at document-start
// ==/UserScript==
// baseado na extensão feita por Jônathas Gouveia.
let token;
let cmm;
let initialScrap = 1;
let pageLoaded = false;
async function checkToken () {
if (location.href.startsWith('https://oauth.vk.com/blank.html')) {
await GM.setValue('token', location.hash.match(/(?<=access_token=)\w+/)[0]);
GM.getValue('redirUrl').then(url => {
GM.deleteValue('redirUrl');
location = url;
});
} else {
token = await GM.getValue('token');
if (!token)
getAccessToken();
else
init();
}
}
checkToken();
async function init () {
cmm = location.pathname.match(/\d+/)[0];
scrap();
await elementReady('#blst_cont');
pageLoaded = true;
if (typeof initialScrap === 'string')
document.querySelector('#blst_cont').innerHTML = initialScrap;
insertButton();
}
async function generateTopicsHTML (topics, profiles) {
let newTopics = '';
topics = topics.sort((a, b) => new Date(b.updated) - new Date(a.updated));
topics = topics.sort((a, b) => b.is_fixed - a.is_fixed);
let fixed = `<div class="blst_fixed" onmouseover="showTooltip(this, {text: 'Tópico fixado', black: 1, shift: [14, 8, 8]})"></div>`;
let closed = `<div class="blst_closed" onmouseover="showTooltip(this, {text: 'Tópico fechado', black: 1, shift: [14, 8, 8]})"></div>`;
for (let i = 0; i < topics.length; i++) {
let a = topics[i];
let currentProfile = profiles.find(b => b.id === a.updated_by) || profiles.find(b => b.id === 101);
let pagination = [];
for (let j = 0; a.comments > j * 20; j++) {
if (a.comments < 140 || j !== 3) {
pagination.push('<a class="blst_page" href="/topic-' + cmm + '_' + a.id + '?offset=' + j * 20 + '">' + (j + 1) + '</a>');
} else if (j == 3) {
pagination.push('..');
j = Math.ceil(a.comments / 20) - 4;
}
}
let html = `
<div class="blst_row clear_fix">
<a class="blst_last" href="/topic-${cmm}_${a.id}?offset=last&amp;scroll=1" onclick="return nav.go(this, event)">
<div class="blst_thumb"><img class="blst_img" src="${currentProfile.photo_50}"></div>
<div class="blst_mem">${currentProfile.first_name + " " + currentProfile.last_name}</div>
<div class="blst_date">${formatDate(a.updated)}</div>
</a>
<div class="blst_info">
<div class="blst_title_wrap">
<a class="blst_title" href="/topic-${cmm}_${a.id}" onclick="return nav.go(this, event)">${a.title}</a>${a.is_fixed ? fixed : ''}${a.is_closed ? closed : ''}
</div>
<div class="blst_other">
${a.comments} recado${a.comments ? 's' : ''}${a.comments >= 20 ? `<span class="divider">|</span>Pgs. ${pagination.join(' ')}` : ''}
</div>
</div>
</div>
`
newTopics += html;
}
if (pageLoaded) {
document.querySelector('#blst_cont').innerHTML = newTopics;
initialScrap = 0;
} else {
initialScrap = newTopics;
}
}
function formatDate (date) {
let s = new Intl.DateTimeFormat('pt-BR', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: 'numeric'
}).formatToParts(date * 1000);
let agora = new Date();
let dia = ('0' + agora.getDate()).slice(-2);
let ontem = ('0' + (d => new Date(d.setDate(d.getDate()-1)))(agora).getDate()).slice(-2);
let ano = new Date().getFullYear();
let data = s[0].value == dia ? 'hoje' : s[0].value == ontem ? 'ontem' : s[0].value + ' de ' + s[2].value.charAt(0).toUpperCase() + s[2].value.slice(1);
let horario = s[4].value == agora.getFullYear() ? 'às ' + s[6].value + ':' + s[8].value : 'de ' + s[4].value;
return data + ' ' + horario;
};
function scrap () {
GM.xmlHttpRequest({
url: 'https://api.vk.com/method/board.getTopics?group_id=' + cmm + '&order=1&extended=1&count=100&offset=0&access_token=' + token + '&v=5.812',
onload: response => {
let { items: topics, profiles } = JSON.parse(response.responseText).response;
generateTopicsHTML(topics.sort((a, b) => a.updated < b.updated), profiles);
}
});
}
function insertButton () {
const btn = document.createElement('button');
btn.id = 'buttonAtt'
btn.className = 'flat_button'
btn.innerHTML = `Atualizar`
btn.addEventListener('click', scrap)
document.querySelector('._header_extra').appendChild(btn);
}
function elementReady (selector) {
return new Promise(resolve => {
let el = document.querySelector(selector);
if (el)
resolve(el);
let observer = new MutationObserver(() => {
if (el = document.querySelector(selector)) {
resolve(el);
observer.disconnect();
}
});
observer.observe(document.documentElement, {
childList: true,
subtree: true
});
});
}
function getAccessToken () {
GM.setValue('redirUrl', location.href);
let params = Object.entries({
client_id : 7579150,
scope : 'groups,offline',
redirect_uri : 'https://oauth.vk.com/blank.html',
display : 'popup',
v : 5.812,
response_type : 'token'
}).map(([key, val]) => key + '=' + encodeURIComponent(val)).join('&');
location = 'https://oauth.vk.com/authorize?' + params;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment