feat: fetch secondary room info via JSON

This commit decreases the shipped DOM size by removing room tags and
the room staff list. These are not used by non-JS browsers and may
instead be fetched via JS.
dev
gravel 7 months ago
parent 68aada55dd
commit 378589e8ac
Signed by: gravel
GPG Key ID: C0538F3C906B308F

@ -2,6 +2,71 @@
// of redundant values in the main file, especially those that could
// change in the foreseeable future.
class _RoomInfo {
static ROOMS_ENDPOINT = '/servers.json';
static rooms = {};
static servers = {};
static async fetchRooms() {
const response = await fetch(this.ROOMS_ENDPOINT);
const servers = await response.json();
for (const server of servers) {
for (const room of server.rooms) {
const identifier = `${room.token}+${server.pubkey.slice(0, 4)}`;
this.rooms[identifier] = {...room, server_key: server.pubkey};
}
delete server.rooms;
this.servers[server.pubkey] = server;
}
}
/**
* @param {string} identifier
*/
static assertRoomExists(identifier) {
if (!(identifier in this.rooms)) {
throw new Error(`No such room: ${identifier}`);
}
}
/**
* @param {string} identifier
* @returns {CommunityRoom}
*/
static getRoom(identifier) {
this.assertRoomExists(identifier);
return this.rooms[identifier];
}
/**
* @param {string} identifier
* @returns {CommunityServer}
*/
static getRoomServer(identifier) {
this.assertRoomExists(identifier);
return this.servers[this.rooms[identifier].server_key];
}
}
export class RoomInfo {
static async fetchRooms() {
return _RoomInfo.fetchRooms();
}
/**
* @param {string} identifier
* @returns {{type: string, text: string, description: string}[]}
*/
static getRoomTags(identifier) {
return _RoomInfo.getRoom(identifier).tags;
}
static getRoomStaff(identifier) {
const room = _RoomInfo.getRoom(identifier);
const { admins = [], moderators = [] } = room;
return [...new Set([...admins, ...moderators])];
}
}
export const dom = {
/** @return {HTMLTableElement | null} */
tbl_communities: () => document.getElementById("tbl_communities"),
@ -10,6 +75,7 @@ export const dom = {
community_row: (communityID) => document.querySelector(`.room-row[${ATTRIBUTES.ROW.IDENTIFIER}="${communityID}"]`),
row_info: (row) => {
const dateCreated = new Date(row.getAttribute(ATTRIBUTES.ROW.DATE_CREATED) * 1000);
const identifier = row.getAttribute(ATTRIBUTES.ROW.IDENTIFIER);
/** @type {string[]} */
return {
language_flag: row.querySelector('.td_language').textContent.trim(),
@ -18,12 +84,11 @@ export const dom = {
users: parseFloat(row.querySelector('.td_users').textContent.trim()),
preview_link: row.querySelector('.td_preview a[href]').getAttribute('href'),
join_link: row.querySelector('.td_join_url a[href]').getAttribute('href'),
identifier: row.getAttribute(ATTRIBUTES.ROW.IDENTIFIER),
identifier,
hostname: row.getAttribute(ATTRIBUTES.ROW.HOSTNAME),
public_key: row.getAttribute(ATTRIBUTES.ROW.PUBLIC_KEY),
staff: row.getAttribute(ATTRIBUTES.ROW.STAFF_DATA),
/** @type {{type: string, text: string, description: string}[]} */
tags: JSON.parse(row.getAttribute(ATTRIBUTES.ROW.TAGS)),
staff: RoomInfo.getRoomStaff(identifier),
tags: RoomInfo.getRoomTags(identifier),
icon: row.getAttribute(ATTRIBUTES.ROW.ROOM_ICON),
has_icon: row.getAttribute(ATTRIBUTES.ROW.ROOM_ICON).trim() != "",
icon_safety: row.getAttribute(ATTRIBUTES.ROW.ROOM_ICON_SAFETY),

@ -17,7 +17,7 @@
import {
dom, COLUMN, COLUMN_LITERAL, COMPARISON, ATTRIBUTES,
columnAscendingByDefault, columnIsSortable, COLUMN_TRANSFORMATION,
element, JOIN_URL_PASTE, communityQRCodeURL, STAFF_ID_PASTE, IDENTIFIER_PASTE, DETAILS_LINK_PASTE, CLASSES, flagToLanguageAscii
element, JOIN_URL_PASTE, communityQRCodeURL, STAFF_ID_PASTE, IDENTIFIER_PASTE, DETAILS_LINK_PASTE, CLASSES, flagToLanguageAscii, RoomInfo
} from './js/util.js';
// Hidden communities for transparency.
@ -130,7 +130,7 @@ function addInformativeInteractions() {
/**
* Triggers all actions dependent on page load.
*/
function onLoad() {
async function onLoad() {
const timestamp = getTimestamp();
if (timestamp !== null) {
setLastChecked(timestamp);
@ -148,7 +148,6 @@ function onLoad() {
setInterval(() => {
preloadImages();
}, 60 * 60E3);
reactToURLParameters();
addInformativeInteractions();
Array.from(document.querySelectorAll('.enter-clicks')).forEach(element => {
// @ts-ignore
@ -158,6 +157,8 @@ function onLoad() {
}
})
})
await RoomInfo.fetchRooms();
reactToURLParameters();
}
/**

@ -72,9 +72,6 @@
$join_link = html_sanitize($room->get_join_url());
$pubkey = html_sanitize($pubkey);
$hostname = html_sanitize($hostname);
$staff_json = json_encode(array_map('html_sanitize', $room->get_staff()));
$tags_json = json_encode($room->get_room_tags());
?>
<tr class="room-row"
@ -84,8 +81,6 @@
data-identifier="<?=$id?>"
data-pubkey="<?=$pubkey?>"
data-hostname="<?=$hostname?>"
data-staff='<?=$staff_json?>'
data-tags='<?=$tags_json?>'
data-icon='<?=room_icon($room, '64x64')?>'
data-icon-safe='<?=$room->icon_safety()?>'
data-created='<?=html_sanitize($room->created)?>'

Loading…
Cancel
Save