454 lines
24 KiB
JavaScript
454 lines
24 KiB
JavaScript
import * as light from './light.module.css';
|
|
import * as dark from './dark.module.css';
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
loading()
|
|
var hold, external, timeout, ac, last
|
|
document.getElementById('instance').addEventListener('keydown', function (event) {
|
|
if (event.key && !event.ctrlKey && !event.altKey && !event.shiftKey) {
|
|
if ((event.key.length === 1 && /[a-z0-9.\-*:]/i.test(event.key)) || (event.key === 'Backspace' && event.target.value !== '')) {
|
|
last = event.target.value
|
|
} else {
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
}
|
|
} else {
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
}
|
|
})
|
|
document.getElementById('instance').addEventListener('keyup', function (event) {
|
|
if (event.key && !event.ctrlKey && !event.altKey && !event.shiftKey) {
|
|
if ((event.key.length === 1 && /[a-z0-9.\-*:]/i.test(event.key)) || (event.key === 'Backspace' && event.target.value !== '')) {
|
|
keypress(event.target.value)
|
|
} else {
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
}
|
|
} else {
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
}
|
|
})
|
|
var modal = document.getElementById('modal'),
|
|
closemodal = document.getElementById('closemodal'),
|
|
modalcontent = document.querySelector('.modal-content')
|
|
document.getElementById('reverse').addEventListener('click', function (event) {
|
|
var content = document.getElementById('instance').value
|
|
if (content && content.length > 0) {
|
|
loading()
|
|
fetch('/api/block_count/' + content).then(async function (result) {
|
|
var res = await result.json()
|
|
if (res && res.block_count >= 0) {
|
|
document.getElementById('blockcount').innerText = res.block_count
|
|
document.getElementById('blockinstance').innerText = 'ing ' + content
|
|
document.getElementById('blocktook').innerText = res.took
|
|
var list = document.getElementById('blocklist'),
|
|
download = document.getElementById('download')
|
|
download.removeAttribute('href')
|
|
download.removeAttribute('download')
|
|
download.style.display = 'none'
|
|
while (list.hasChildNodes()) {
|
|
list.removeChild(list.firstChild)
|
|
}
|
|
res.instances.map(function (instance, index) {
|
|
var li = document.createElement('li'),
|
|
text = document.createTextNode((index + 1) + '. '),
|
|
link = '<a href="/' + (new URLSearchParams(window.location.search).has('matrix') ? '?matrix' : '') + '#' + instance.instance + '" onclick="window.location.href=this.href; window.location.reload(false);">' + instance.instance + '</a>',
|
|
text2 = document.createTextNode(instance.comment ? ' - ' + instance.comment : '')
|
|
li.appendChild(text)
|
|
li.insertAdjacentHTML('beforeend', link)
|
|
li.appendChild(text2)
|
|
blocklist.appendChild(li)
|
|
})
|
|
listinstance(content, new AbortController())
|
|
modalcontent.style.animationName = 'animatetop'
|
|
modal.style.display = 'block'
|
|
var locationsearch = !new URLSearchParams(window.location.search).has('reverse') ? window.location.search ? window.location.search + '&reverse' : '?reverse' : window.location.search
|
|
history.pushState({}, null, '/' + locationsearch + '#' + content)
|
|
if (new URLSearchParams(window.location.search).has('matrix')) {
|
|
var walker = document.createTreeWalker(list, NodeFilter.SHOW_TEXT)
|
|
while (walker.nextNode()) {
|
|
if (walker.currentNode.textContent.length > 1) {
|
|
new Messenger(walker.currentNode)
|
|
}
|
|
}
|
|
}
|
|
document.getElementById('loader-content').style.display = 'none'
|
|
}
|
|
})
|
|
}
|
|
})
|
|
document.body.addEventListener('click', function (event) {
|
|
if (event.target == modal) {
|
|
modalcontent.style.animationName = 'animatebottom'
|
|
}
|
|
})
|
|
closemodal.addEventListener('click', function (event) {
|
|
modalcontent.style.animationName = 'animatebottom'
|
|
})
|
|
modalcontent.addEventListener('animationend', function (event) {
|
|
if (event.animationName === 'animatebottom') {
|
|
modal.style.display = 'none'
|
|
}
|
|
})
|
|
document.getElementById('title').addEventListener('click', function (event) {
|
|
document.getElementById('instance').value = ''
|
|
if (new URLSearchParams(window.location.search).has('matrix')) {
|
|
window.location.href = '/?matrix'
|
|
} else {
|
|
window.location.href = '/'
|
|
}
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
})
|
|
document.getElementById('capture').addEventListener('click', function (event) {
|
|
html2canvas(document.querySelector('.modal-body')).then(function (canvas) {
|
|
var a = document.createElement('a')
|
|
a.download = 'fediblock-' + Date.now() + '.png'
|
|
a.href = canvas.toDataURL({ type: 'image/png' })
|
|
a.type = 'image/png'
|
|
a.target = '_blank'
|
|
a.dispatchEvent(new MouseEvent('click'))
|
|
})
|
|
})
|
|
document.getElementById('download_index').addEventListener('click', function (event) {
|
|
loading()
|
|
ac = new AbortController()
|
|
fetch('/api/download_index', { signal: ac.signal }).then(async function (result) {
|
|
var res = await result.blob(),
|
|
a = document.createElement('a')
|
|
a.download = 'fediblock-index.json.gz'
|
|
a.href = URL.createObjectURL(res)
|
|
a.type = 'application/gzip'
|
|
a.target = '_blank'
|
|
a.dispatchEvent(new MouseEvent('click'))
|
|
document.getElementById('loader-content').style.display = 'none'
|
|
}).catch(function (err) {
|
|
console.error(err)
|
|
document.getElementById('loader-content').style.display = 'none'
|
|
})
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
})
|
|
document.getElementById('darklight').addEventListener('click', function(event) {
|
|
if(event.target.innerText === '☼') {
|
|
document.getElementById('css').setAttribute('href', light.meta.url)
|
|
event.target.innerText = '☽'
|
|
} else {
|
|
document.getElementById('css').setAttribute('href', dark.meta.url)
|
|
event.target.innerText = '☼'
|
|
}
|
|
})
|
|
function keypress(content) {
|
|
loading()
|
|
if (timeout) {
|
|
clearTimeout(timeout)
|
|
}
|
|
if (ac && ac.signal) {
|
|
ac.abort()
|
|
}
|
|
ac = new AbortController()
|
|
if (content.length === 0) {
|
|
hold = true
|
|
ranking()
|
|
} else if (content.length > 0 && !hold) {
|
|
hold = true
|
|
listinstance(content, ac)
|
|
} else if (content.length > 0 && hold) {
|
|
timeout = setTimeout(function () {
|
|
listinstance(content, ac)
|
|
}, 300)
|
|
}
|
|
}
|
|
function listinstance(content, ac) {
|
|
loading()
|
|
var list = document.getElementById('instancelist')
|
|
fetch('/api/list/' + content, { signal: ac.signal }).then(async function (result) {
|
|
var res = await result.json()
|
|
if (res && Array.isArray(res.instances) && Array.isArray(res.suggests)) {
|
|
while (list.hasChildNodes()) {
|
|
list.removeChild(list.firstChild)
|
|
}
|
|
res.instances.map(function (r) {
|
|
var li = document.createElement('li')
|
|
li.innerHTML = r.domain + (r.blocks ? ' - ' + r.blocks + ' blocks' : '')
|
|
+ (r.nodeinfo ? ' <a href="/api/detail_nodeinfo/' + r.domain + '" title="Nodeinfo for ' + r.domain + '" target="_blank">ⓘ</a>' : '')
|
|
+ (r.api.title ? '<br /> <br />' + r.api.title + ' - ' + r.api.uri + '<br />'
|
|
+ (r.last ? 'Last update: ' + (new Date(r.last)).toLocaleString() + '<br />' : '')
|
|
+ (r.api.email ? 'Email: ' + r.api.email + '<br />' : '')
|
|
+ 'Registration: ' + (r.api.registrations ? 'open' : 'closed') + ' - Version: ' + r.api.version + '<br />'
|
|
+ (r.api.stats ? 'Users: ' + r.api.stats.user_count + ' - Statuses: ' + r.api.stats.status_count + ' - Domains: ' + r.api.stats.domain_count + '<br />' : '')
|
|
+ (r.api.description ? 'Description: ' + r.api.description + '<br />' : '')
|
|
+ (r.api.thumbnail ? '<img domain="' + r.domain + '" loading="lazy" src="' + r.api.thumbnail + '" /><br />' : '') : '')
|
|
li.setAttribute('data-domain', r.domain)
|
|
li.addEventListener('click', function (event) {
|
|
if (event.target.matches('a')) {
|
|
return true
|
|
}
|
|
loading()
|
|
var blocklist = document.getElementById('blocklist'),
|
|
download = document.getElementById('download'),
|
|
domain = event.target.getAttribute('data-domain')
|
|
while (blocklist.hasChildNodes()) {
|
|
blocklist.removeChild(blocklist.firstChild)
|
|
}
|
|
fetch('/api/detail/' + domain).then(async function (result) {
|
|
var res = await result.json()
|
|
if (res.blocks && Array.isArray(res.blocks) && res.blocks.length > 0) {
|
|
var csv = '#domain,#severity,#reject_media,#reject_reports,#public_comment,#obfuscate\n'
|
|
res.blocks.map(function (r, i) {
|
|
var liblock = document.createElement('li'),
|
|
text = document.createTextNode((i + 1) + '. '),
|
|
link = '<a href="/' + (new URLSearchParams(window.location.search).has('matrix') ? '?matrix' : '') + '#' + r.domain + '" onclick="window.location.href=this.href; window.location.reload(false);">' + r.domain + '</a>',
|
|
textSeverity = document.createTextNode(r.severity ? ' - ' + r.severity : ''),
|
|
textComment = document.createTextNode(r.comment ? ' - ' + r.comment : '')
|
|
liblock.appendChild(text)
|
|
liblock.insertAdjacentHTML('beforeend', link)
|
|
liblock.appendChild(textSeverity)
|
|
liblock.appendChild(textComment)
|
|
blocklist.appendChild(liblock)
|
|
csv += !r.domain.match(/\*/) ? r.domain + ',' + (r.severity ? r.severity : '') + ',False,False,' + (r.comment ? '"' + r.comment + '"' : '') + ',False\n' : ''
|
|
})
|
|
modalcontent.style.animationName = 'animatetop'
|
|
modal.style.display = 'block'
|
|
document.getElementById('blockcount').innerText = res.blocks.length
|
|
document.getElementById('blockinstance').innerHTML = 'ed by ' + (res.api ? '<a href="/api/detail_api/' + res.instance + '" title="API info for ' + res.instance + '" target="_blank">'
|
|
+ res.instance + '</a>' : res.instance) + (res.nodeinfo ? ' <a href="/api/detail_nodeinfo/' + res.instance + '" title="Nodeinfo for ' + res.instance + '" target="_blank">ⓘ</a>' : '')
|
|
+ '<br/>Last update: ' + (new Date(res.last)).toLocaleString()
|
|
document.getElementById('blocktook').innerText = res.took
|
|
if (csv.split('\n').length > 2) {
|
|
download.href = window.URL.createObjectURL(new Blob([csv], { type: 'text/csv' }))
|
|
download.download = 'fediblock-' + res.instance + '.csv'
|
|
download.style.display = 'inherit'
|
|
} else {
|
|
download.removeAttribute('href')
|
|
download.removeAttribute('download')
|
|
download.style.display = 'none'
|
|
}
|
|
if (new URLSearchParams(window.location.search).has('matrix')) {
|
|
var walker = document.createTreeWalker(blocklist, NodeFilter.SHOW_TEXT)
|
|
while (walker.nextNode()) {
|
|
if (walker.currentNode.textContent.length > 1) {
|
|
new Messenger(walker.currentNode)
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
var a = document.createElement('a')
|
|
a.href = '/api/detail_api/' + domain
|
|
a.title = 'API info for ' + domain
|
|
a.target = '_blank'
|
|
a.dispatchEvent(new MouseEvent('click'))
|
|
}
|
|
document.getElementById('loader-content').style.display = 'none'
|
|
})
|
|
window.location.hash = domain
|
|
document.getElementById('loader-content').style.display = 'none'
|
|
})
|
|
list.appendChild(li)
|
|
})
|
|
var placeholder = document.getElementById('placeholder')
|
|
if (res.suggests.length > 0) {
|
|
placeholder.innerHTML = res.suggests.map(function (instance) {
|
|
return '<a href="/' + (new URLSearchParams(window.location.search).has('matrix') ? '?matrix' : '') + '#' + instance + '" onclick="suggest(this.innerText);">' + instance + '</a>'
|
|
}).join(', ')
|
|
} else {
|
|
placeholder.innerText = ''
|
|
}
|
|
if (external) {
|
|
document.getElementById('instancelist').childNodes.forEach(function (node) {
|
|
if (node.textContent.split(' ')[0].trim() === content) {
|
|
node.dispatchEvent(new MouseEvent('click'))
|
|
}
|
|
})
|
|
external = false
|
|
}
|
|
if (new URLSearchParams(window.location.search).has('matrix')) {
|
|
var walker = document.createTreeWalker(list, NodeFilter.SHOW_TEXT)
|
|
while (walker.nextNode()) {
|
|
if (walker.currentNode.textContent.length > 1) {
|
|
new Messenger(walker.currentNode)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
document.getElementById('loader-content').style.display = 'none'
|
|
hold = false
|
|
}).catch(function (err) {
|
|
// console.error(err)
|
|
document.getElementById('loader-content').style.display = 'none'
|
|
hold = false
|
|
})
|
|
}
|
|
function ranking() {
|
|
loading()
|
|
var list = document.getElementById('instancelist'),
|
|
placeholder = document.getElementById('placeholder')
|
|
fetch('/api/ranking').then(async function (result) {
|
|
var res = await result.json()
|
|
if (Array.isArray(res) && res.length > 0) {
|
|
while (list.hasChildNodes()) {
|
|
list.removeChild(list.firstChild)
|
|
}
|
|
var li = document.createElement('li'),
|
|
strong = document.createElement('strong'),
|
|
text = document.createTextNode('Top 100')
|
|
strong.appendChild(text)
|
|
li.appendChild(strong)
|
|
list.appendChild(li)
|
|
res.map(function (r, i) {
|
|
var li = document.createElement('li'),
|
|
text = document.createTextNode(`${i + 1} - ${r.domain} - ${r.count} blocks`)
|
|
li.addEventListener('click', function (event) {
|
|
var instance = document.getElementById('instance'),
|
|
text = event.target.innerText.split(' - ')[1].trim()
|
|
instance.value = text
|
|
document.getElementById('reverse').click()
|
|
})
|
|
li.appendChild(text)
|
|
list.appendChild(li)
|
|
})
|
|
}
|
|
if (new URLSearchParams(window.location.search).has('matrix')) {
|
|
var walker = document.createTreeWalker(list, NodeFilter.SHOW_TEXT)
|
|
while (walker.nextNode()) {
|
|
if (walker.currentNode.textContent.length > 1) {
|
|
new Messenger(walker.currentNode)
|
|
}
|
|
}
|
|
}
|
|
placeholder.innerText = ''
|
|
hold = false
|
|
document.getElementById('loader-content').style.display = 'none'
|
|
}).catch(function (err) {
|
|
console.error(err)
|
|
hold = false
|
|
document.getElementById('loader-content').style.display = 'none'
|
|
})
|
|
}
|
|
function suggest(urlitem) {
|
|
var instance = document.getElementById('instance')
|
|
window.location.hash = urlitem
|
|
instance.value = urlitem
|
|
listinstance(urlitem, new AbortController())
|
|
}
|
|
function loading() {
|
|
var loader = document.getElementById('load'),
|
|
loaders = ['loader-pong', 'loader-pacman', 'loader-abyss', 'loader-jump', 'loader-loading', 'loader-avenger', 'loader-mario']
|
|
if (loader.classList.value) {
|
|
loader.classList.remove(loader.classList.value)
|
|
}
|
|
loader.classList.add(loaders[Math.floor(Math.random() * loaders.length)])
|
|
document.getElementById('loader-content').style.display = 'initial'
|
|
}
|
|
window.suggest = suggest
|
|
fetch('/api/count').then(async function (result) {
|
|
var res = await result.json()
|
|
if (res && res.count) {
|
|
fetch('/api/stats').then(async function (statsresult) {
|
|
var statsres = await statsresult.json()
|
|
if (statsres) {
|
|
document.getElementById('count').innerHTML = res.count + '<div id="tooltip">' +
|
|
'<u><strong><center>STATS</center></strong></u>' +
|
|
'<ul><li>Statuses AVG: ' + Math.round(statsres.status_avg) + '</li>' +
|
|
'<li>Statuses MAX: ' + statsres.status_max + '</li>' +
|
|
'<li>Domain AVG: ' + Math.round(statsres.domain_avg) + '</li>' +
|
|
'<li>Domain MAX: ' + statsres.domain_max + '</li>' +
|
|
'<li>Users AVG: ' + Math.round(statsres.user_avg) + '</li>' +
|
|
'<li>Users MAX: ' + statsres.user_max + '</li>' +
|
|
'<li>Stats Instances: ' + statsres.stats_filtered + '</li>' +
|
|
'<li>Total Instances: ' + statsres.instance_count + '</li>' +
|
|
'<li>Users by Instance: ' + (Math.round(statsres.user_avg) / statsres.instance_count).toFixed(2) + '</li>' +
|
|
'<li>Statuses by Domain: ' + (Math.round(statsres.status_avg) / Math.round(statsres.domain_avg)).toFixed(2) + '</li>' +
|
|
'<li>Statuses by User: ' + (Math.round(statsres.status_avg) / Math.round(statsres.user_avg)).toFixed(2) + '</li>' +
|
|
'</ul></div>'
|
|
} else {
|
|
document.getElementById('count').innerText = res.count
|
|
}
|
|
})
|
|
fetch('/api/outbox').then(async function (result) {
|
|
var res = await result.json()
|
|
if (res && res.length > 0) {
|
|
var bounce = document.getElementById('bounce'),
|
|
host = new URL(window.location.href).host
|
|
reg = '(<\/?p>|(https?:\/\/)?' + host + ')'
|
|
bounce.innerHTML = res.map(function (p) { return `${p.content.replace(new RegExp(reg, 'igm'), '')} ${dayjs().to(p.published)}` }).join(' | ')
|
|
}
|
|
})
|
|
fetch('/api/served').then(async function (result) {
|
|
var res = await result.json()
|
|
if (res.served) {
|
|
var served = document.getElementById('served')
|
|
served.innerText = res.served
|
|
}
|
|
if (res.lastscan) {
|
|
var lastscan = document.getElementById('lastscan')
|
|
lastscan.innerText = res.lastscan
|
|
}
|
|
if (res.server) {
|
|
var server = document.getElementById('server')
|
|
server.innerHTML = '<a href="/' + (new URLSearchParams(window.location.search).has('matrix') ? '?matrix' : '') + '#' + res.server + '" onclick="window.location.href=this.href; window.location.reload(false);">' + res.server + '</a>'
|
|
}
|
|
if (res.instances) {
|
|
var instances = document.getElementById('instances')
|
|
instances.innerText = res.instances
|
|
}
|
|
if (res.peers) {
|
|
var peers = document.getElementById('peers')
|
|
peers.innerText = res.peers
|
|
}
|
|
if (res.created) {
|
|
var created = document.getElementById('created')
|
|
created.innerText = res.created
|
|
}
|
|
if (res.updated) {
|
|
var updated = document.getElementById('updated')
|
|
updated.innerText = res.updated
|
|
}
|
|
})
|
|
}
|
|
})
|
|
if (window.location.hash && window.location.hash !== null && window.location.hash !== '#') {
|
|
var instance = document.getElementById('instance'),
|
|
urlitem = window.location.hash.substring(1)
|
|
instance.value = urlitem
|
|
if (new URLSearchParams(window.location.search).has('reverse')) {
|
|
document.getElementById('reverse').click()
|
|
} else {
|
|
external = true
|
|
listinstance(urlitem, new AbortController())
|
|
}
|
|
} else {
|
|
ranking()
|
|
document.getElementById('instance').focus()
|
|
}
|
|
var source = new window.EventSource('/api/scan'),
|
|
scan = document.getElementById('scan')
|
|
source.onmessage = function (event) {
|
|
if (event.data) {
|
|
if (event.data.length > 0) {
|
|
scan.innerText = 'Async Scanning' + event.data
|
|
} else {
|
|
scan.innerText = 'Async Scanning...'
|
|
}
|
|
}
|
|
}
|
|
source.onerror = function (error) {
|
|
console.error(error)
|
|
}
|
|
if (new URLSearchParams(window.location.search).has('matrix')) {
|
|
var walker = document.createTreeWalker(document, NodeFilter.SHOW_TEXT)
|
|
while (walker.nextNode()) {
|
|
if (walker.currentNode.textContent.length > 1) {
|
|
new Messenger(walker.currentNode)
|
|
}
|
|
}
|
|
var matrix = document.getElementById('matrix')
|
|
matrix.href = '/'
|
|
matrix.innerText = 'on'
|
|
} else {
|
|
var matrix = document.getElementById('matrix')
|
|
matrix.href = '/?matrix'
|
|
matrix.innerText = 'off'
|
|
}
|
|
}) |