|
|
|
@ -22,32 +22,18 @@ import {
|
|
|
|
|
// Hidden communities for transparency.
|
|
|
|
|
const filteredCommunities = {
|
|
|
|
|
tests: [
|
|
|
|
|
"2e9345+c7fb", // TestRoom
|
|
|
|
|
"762ba9+c7fb", // TesterRoom
|
|
|
|
|
"b4d829+c7fb", // Test
|
|
|
|
|
"e5853a+c7fb", // testtest
|
|
|
|
|
"fishing+8e2e", // Example group from PySOGS documentation
|
|
|
|
|
"test+118d", // Testing 1, 2, 3
|
|
|
|
|
"test+13f6", // Testing room
|
|
|
|
|
"test+c01b", // Testing room
|
|
|
|
|
"test+13f6", // Testing room2
|
|
|
|
|
"test+fe93", // 测试(Test)
|
|
|
|
|
"xyz+7908", // XYZ Room
|
|
|
|
|
"xyz+efca", // XYZ Room
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
offensive: [
|
|
|
|
|
"60fa60+c7fb", // "N-word" Community
|
|
|
|
|
"ab1a4d+c7fb", // zUnsensored Group (CSAM)
|
|
|
|
|
"AlexMed+e093", //
|
|
|
|
|
"AlexMed+e093", // drug trading?
|
|
|
|
|
"gore+e5e0", // gore
|
|
|
|
|
"RU-STEROID+e093" //
|
|
|
|
|
"RU-STEROID+e093" // drug trading?
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// These communities should be checked regularly
|
|
|
|
|
// in case they update their PySOGS version
|
|
|
|
|
legacy: [
|
|
|
|
|
"Ukraine+02bd" // https://reccacon.com/view/room/Ukraine
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// This can be achieved with `text-overflow: ellipsis` instead
|
|
|
|
@ -60,13 +46,27 @@ const transformJoinURL = (join_link) => {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onLoad(timestamp) {
|
|
|
|
|
setLastChecked(timestamp);
|
|
|
|
|
function getTimestamp() {
|
|
|
|
|
const timestampRaw = dom.meta_timestamp()
|
|
|
|
|
?.getAttribute('content');
|
|
|
|
|
if (!timestampRaw) return null;
|
|
|
|
|
const timestamp = parseInt(timestampRaw);
|
|
|
|
|
if (Number.isNaN(timestamp)) return null;
|
|
|
|
|
return timestamp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onLoad() {
|
|
|
|
|
const timestamp = getTimestamp();
|
|
|
|
|
if (timestamp !== null) {
|
|
|
|
|
setLastChecked(timestamp);
|
|
|
|
|
}
|
|
|
|
|
hideBadCommunities();
|
|
|
|
|
// Sort by server to show off new feature & align colors.
|
|
|
|
|
sortTable(COLUMN.SERVER_ICON);
|
|
|
|
|
createJoinLinkButtons();
|
|
|
|
|
markSortableColumns();
|
|
|
|
|
addQRModalHandlers();
|
|
|
|
|
addServerIconInteractions();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function displayQRModal(communityID) {
|
|
|
|
@ -77,6 +77,24 @@ function hideQRModal(communityID) {
|
|
|
|
|
dom.qr_modal(communityID).style.display = "none";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function addQRModalHandlers() {
|
|
|
|
|
const rows = dom.tbl_communities_content_rows();
|
|
|
|
|
if (!rows) throw new Error("Rows not found");
|
|
|
|
|
for (const row of rows) {
|
|
|
|
|
const communityID = row.getAttribute('data-identifier');
|
|
|
|
|
row.querySelector('.td_qr_code').addEventListener(
|
|
|
|
|
'click',
|
|
|
|
|
() => displayQRModal(communityID)
|
|
|
|
|
);
|
|
|
|
|
const closeButton =
|
|
|
|
|
dom.qr_modal(communityID).querySelector('.qr-code-modal-close');
|
|
|
|
|
closeButton.addEventListener(
|
|
|
|
|
'click',
|
|
|
|
|
() => hideQRModal(communityID)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createJoinLinkButtons() {
|
|
|
|
|
const join_URLs = dom.join_urls();
|
|
|
|
|
Array.from(join_URLs).forEach((td_url) => {
|
|
|
|
@ -89,7 +107,7 @@ function createJoinLinkButtons() {
|
|
|
|
|
function hideBadCommunities() {
|
|
|
|
|
let numberOfHiddenCommunities = 0;
|
|
|
|
|
|
|
|
|
|
for (const category of ['tests', 'offensive', 'legacy']) {
|
|
|
|
|
for (const category of ['tests', 'offensive']) {
|
|
|
|
|
numberOfHiddenCommunities +=
|
|
|
|
|
filteredCommunities[category]
|
|
|
|
|
.map(hideElementByID)
|
|
|
|
@ -138,6 +156,19 @@ function setLastChecked(last_checked) {
|
|
|
|
|
timestamp_element.innerText = `${time_passed_in_minutes} minutes ago`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: Move info into dynamic modal.
|
|
|
|
|
function addServerIconInteractions() {
|
|
|
|
|
const rows = dom.tbl_communities_content_rows();
|
|
|
|
|
for (const row of rows) {
|
|
|
|
|
const hostname = row.getAttribute('data-hostname');
|
|
|
|
|
const publicKey = row.getAttribute('data-pubkey');
|
|
|
|
|
const serverIcon = row.querySelector('.td_server_icon');
|
|
|
|
|
serverIcon.addEventListener('click', () => {
|
|
|
|
|
alert(`Host: ${hostname}?>\n\nPublic key:\n${publicKey}?>`);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Function comparing two elements.
|
|
|
|
|
*
|
|
|
|
@ -253,9 +284,13 @@ function markSortableColumns() {
|
|
|
|
|
const table = dom.tbl_communities();
|
|
|
|
|
const header_cells = table.querySelectorAll('th');
|
|
|
|
|
for (let colno = 0; colno < header_cells.length; colno++) {
|
|
|
|
|
if (!columnIsSortable(colno)) continue;
|
|
|
|
|
if (!columnIsSortable(colno)) continue;
|
|
|
|
|
header_cells[colno].classList.add('sortable');
|
|
|
|
|
}
|
|
|
|
|
header_cells[colno].addEventListener(
|
|
|
|
|
'click',
|
|
|
|
|
() => sortTable(colno)
|
|
|
|
|
)
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -279,13 +314,7 @@ function sortTable(column) {
|
|
|
|
|
setSortState(table, { ascending, column });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// html.js for styling purposes
|
|
|
|
|
window.document.documentElement.classList.add("js");
|
|
|
|
|
|
|
|
|
|
// Crude way to export from module script due to inline event handlers.
|
|
|
|
|
// Ideally, all handlers would be attached from JS via addEventListener.
|
|
|
|
|
Object.assign(window, {
|
|
|
|
|
onLoad, sortTable, displayQRModal,
|
|
|
|
|
hideQRModal, copyToClipboard
|
|
|
|
|
});
|
|
|
|
|
// `html.js` selector for styling purposes
|
|
|
|
|
document.documentElement.classList.add("js");
|
|
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', () => onLoad());
|
|
|
|
|