feat: restructure site generation, reduce dom size
This commit does the following: - Expands site generation with ability to include page-specific fragments - Expands staff rating algorithms - Restricts list of Communities statically included in main page - Adds mechanism to fetch rest of Communities dynamically - Adds /groups/all to request all pages statically - Extracts duplicate tag information from servers.json into tags.json - Minor changes (clickable h1 resets URL hash)dev
parent
c7b8c6d272
commit
606170e672
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
require_once "servers/servers-rooms.php";
|
||||
|
||||
class CommunityDatabase {
|
||||
private function __construct(array $servers) {
|
||||
$this->servers = $servers;
|
||||
$this->rooms = CommunityServer::enumerate_rooms($servers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var CommunityServer[] $servers
|
||||
*/
|
||||
public array $servers;
|
||||
|
||||
/**
|
||||
* @var CommunityRoom[] $rooms
|
||||
*/
|
||||
public array $rooms;
|
||||
|
||||
public static function read_from_file(string $rooms_file): CommunityDatabase {
|
||||
$servers = CommunityServer::read_servers_from_file($rooms_file);
|
||||
return new CommunityDatabase($servers);
|
||||
}
|
||||
|
||||
public function fetch_assets(): CommunityDatabase {
|
||||
CommunityRoom::fetch_assets($this->rooms);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function unpack() {
|
||||
return [$this->rooms, $this->servers];
|
||||
}
|
||||
}
|
||||
?>
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
class SiteGeneration {
|
||||
public static function getCanonicalPageURL() {
|
||||
global $SITE_CANONICAL_URL;
|
||||
|
||||
return dirname($SITE_CANONICAL_URL.getenv('SSG_TARGET')) . '/';
|
||||
}
|
||||
public static function getAbsoluteSourceDocumentPath() {
|
||||
return $_SERVER['SCRIPT_NAME'];
|
||||
}
|
||||
|
||||
public static function getTargetDocumentPath() {
|
||||
return getenv('SSG_TARGET');
|
||||
}
|
||||
|
||||
public static function getTargetDocumentRoute() {
|
||||
return dirname(SiteGeneration::getTargetDocumentPath());
|
||||
}
|
||||
|
||||
public static function getOwnSubDocumentPath(string $identifier) {
|
||||
$page = SiteGeneration::getAbsoluteSourceDocumentPath();
|
||||
$sub_document = dirname($page) . '/+' . preg_replace('/[.]php$/', ".$identifier.php", basename($page));
|
||||
return $sub_document;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,134 @@
|
||||
<?php
|
||||
require_once 'php/utils/utils.php';
|
||||
require_once 'php/servers/servers-rooms.php';
|
||||
require_once 'php/assets/room-invites.php';
|
||||
require_once 'php/assets/room-icons.php';
|
||||
require_once 'php/assets/server-icons.php';
|
||||
|
||||
function renderCommunityRoomRow(CommunityRoom $room) {
|
||||
if ($room->is_off_record()) {
|
||||
// This can later allow SOGS
|
||||
// to pass server-wide info using hidden dummy rooms.
|
||||
return;
|
||||
}
|
||||
|
||||
$pubkey = $room->server->get_pubkey();
|
||||
$icon_hue = hexdec($pubkey[2] . $pubkey[2]);
|
||||
$icon_color = "hsl($icon_hue, 80%, 50%)";
|
||||
$server_icon = server_icon($room->server, '64x64');
|
||||
$pubkey_shorthand = strtoupper($pubkey[0] . $pubkey[1]);
|
||||
|
||||
$id = html_sanitize($room->get_room_identifier());
|
||||
$language = html_sanitize($room->get_language_flag());
|
||||
$name = html_sanitize($room->name);
|
||||
// $name_trunc = truncate($name, 16);
|
||||
$name_trunc = "Community";
|
||||
$desc = html_sanitize($room->description);
|
||||
$users = html_sanitize($room->active_users);
|
||||
$users_cutoff = html_sanitize($room->format_user_cutoff_period());
|
||||
$users_tooltip = $room->read
|
||||
? "$users active users in the last $users_cutoff"
|
||||
: "$users users with read privileges, ??? others";
|
||||
$users = $room->read ? $users : "—";
|
||||
$preview_link = html_sanitize($room->get_preview_url());
|
||||
$join_link = html_sanitize($room->get_join_url());
|
||||
$pubkey = html_sanitize($pubkey);
|
||||
$hostname = html_sanitize($room->server->get_hostname());
|
||||
|
||||
$class_list = ["room-row"];
|
||||
|
||||
if ($room->is_stickied_room()) {
|
||||
$class_list[] = "room-row-stickied";
|
||||
}
|
||||
|
||||
$classname = implode(" ", $class_list);
|
||||
|
||||
/**
|
||||
* Note on refactoring:
|
||||
* Icon is hard to move to JSON because it'd have to be generated by fetching code
|
||||
* Icon safety is depended on by CSS styles
|
||||
*/
|
||||
?>
|
||||
|
||||
<tr class="<?=$classname?>"
|
||||
itemscope
|
||||
itemtype="https://schema.org/EntryPoint"
|
||||
data-id="<?=$id?>"
|
||||
data-icon='<?=room_icon($room, '64x64')?>:<?=$room->icon_safety()?>'
|
||||
>
|
||||
<td class="td_language" title="Language flag for '<?=$name_trunc?>'"><?=$language?></td>
|
||||
<td class="td_name">
|
||||
<a
|
||||
href="<?=$preview_link?>"
|
||||
target="_blank"
|
||||
title="Click here to preview <?=$name_trunc?>"
|
||||
rel="noopener noreferrer external nofollow"
|
||||
itemprop="url"
|
||||
><span itemprop="name"><?=
|
||||
$name
|
||||
?></span></a>
|
||||
<span><?php /* class="tags-container" */ ?>
|
||||
<?php foreach ($room->get_showcased_room_tags() as $tag): ?>
|
||||
<span
|
||||
class="tag <?=$tag->get_tag_classname()?> badge"
|
||||
title="<?=$tag->get_description_sanitized()?>"
|
||||
><?=
|
||||
truncate($tag->get_text_sanitized(), 16)
|
||||
?></span>
|
||||
<?php endforeach; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="td_description"
|
||||
title="Description"
|
||||
itemprop="description"
|
||||
><?=$desc?></td>
|
||||
<td
|
||||
class="td_users"
|
||||
title="<?=$users_tooltip?>."
|
||||
><?=$users?></td>
|
||||
<td class="td_preview">
|
||||
<a
|
||||
href="<?=$preview_link?>"
|
||||
title="Preview <?=$name_trunc?>"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer external nofollow"
|
||||
>
|
||||
<span></span>
|
||||
</a>
|
||||
</td>
|
||||
<td class="td_qr_code">
|
||||
<a
|
||||
href="<?=room_qr_code($room)?>"
|
||||
target="_blank"
|
||||
title="Click here to view details for <?=$name_trunc?>"
|
||||
>
|
||||
<div></div>
|
||||
</a>
|
||||
</td>
|
||||
<td class="td_server_icon"
|
||||
title="Host: <?=$hostname?>"
|
||||
>
|
||||
<?php if (empty($server_icon)): ?>
|
||||
<div class="td_server_icon-circle" style="background-color: <?=$icon_color?>">
|
||||
<span class="td_server_icon-text"><?=$pubkey_shorthand?></span>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="td_server_icon-circle" style="background-image: url('<?=$server_icon?>')"></div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="td_join_url">
|
||||
<div>
|
||||
<span></span><?php /* Join URL preview */ ?>
|
||||
<a
|
||||
class="noscript"
|
||||
href="<?=$join_link?>"
|
||||
title="Right click -> Copy link"
|
||||
rel="external nofollow"
|
||||
>Copy this</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
require_once 'community-row.php';
|
||||
|
||||
/**
|
||||
* @param CommunityRoom[] $rooms
|
||||
*/
|
||||
function renderCommunityRoomTableFragment(array $rooms) {
|
||||
foreach ($rooms as $room) {
|
||||
renderCommunityRoomRow($room);
|
||||
}
|
||||
}
|
||||
?>
|
@ -0,0 +1 @@
|
||||
<h1 id="headline"><span id="headline-01">Session</span><span id="headline-02">Communities</span><span id="headline-03">.online</span></h1>
|
@ -0,0 +1,13 @@
|
||||
<title>Session Communities List — sessioncommunities.online</title>
|
||||
<meta name="description" content="Chat in Session Communities! <?php
|
||||
?>Use our list to join your favorite Community in Session Messenger. <?php
|
||||
?>Copy public Session group links into the Session app!<?php
|
||||
?>">
|
||||
<meta name="keywords" content="session communities,session groups,session group list,session chat">
|
||||
<meta property="og:title" content="Session Communities — Come chat!">
|
||||
<meta
|
||||
property="og:description"
|
||||
content="100+ Session Communities."
|
||||
>
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:locale" content="en_US"/>
|
@ -0,0 +1,133 @@
|
||||
<?php
|
||||
require_once 'php/utils/utils.php';
|
||||
require_once 'php/utils/site-generation.php';
|
||||
require_once 'php/servers/servers-rooms.php';
|
||||
require_once '+components/tbl-communities.php';
|
||||
|
||||
// Set the last-updated timestamp
|
||||
// to the time the server data file was last modified.
|
||||
$time_modified = filemtime($ROOMS_FILE);
|
||||
$time_modified_str = date("Y-m-d H:i:s", $time_modified);
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<?php include "+components/page-head.php" ?>
|
||||
|
||||
<meta name="modified" content="<?=$time_modified_str?>">
|
||||
<meta name="timestamp" content="<?=$time_modified?>">
|
||||
<link rel="stylesheet" href="/index.css?<?=md5_file("$DOCUMENT_ROOT/index.css")?>">
|
||||
<link rel="stylesheet" href="/css/banner.css?<?=md5_file("$DOCUMENT_ROOT/css/banner.css")?>">
|
||||
<script type="module" src="/main.js?<?=md5_file("$DOCUMENT_ROOT/main.js")?>"></script>
|
||||
<link rel="modulepreload" href="/js/util.js">
|
||||
<link rel="preload" href="/servers.json" as="fetch" crossorigin="anonymous"/>
|
||||
<link rel="preload" href="/tags.json" as="fetch" crossorigin="anonymous"/>
|
||||
<link rel="help" href="/instructions/">
|
||||
|
||||
<noscript>
|
||||
<style>
|
||||
.js-only {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</noscript>
|
||||
|
||||
<?php include "+components/communities-json-ld.php"; ?>
|
||||
</head>
|
||||
<body>
|
||||
<input type="checkbox" id="toggle-theme-switch">
|
||||
<div id="theming-root">
|
||||
<?php include "+components/index-header.php" ?>
|
||||
|
||||
<a
|
||||
href="#"
|
||||
class="non-anchorstyle"
|
||||
><?php include SiteGeneration::getOwnSubDocumentPath('h1'); ?></a>
|
||||
|
||||
<?php include "+components/issue-banner.php" ?>
|
||||
|
||||
<?php include "+components/communities-search.php"; ?>
|
||||
|
||||
<?php include "+components/qr-modals.php" ?>
|
||||
|
||||
<?php renderCommunityRoomTable($rooms); ?>
|
||||
|
||||
<gap></gap>
|
||||
|
||||
<hr id="footer-divider">
|
||||
|
||||
<aside id="summary" itemid="<?=$SITE_CANONICAL_URL?>" itemtype="https://schema.org/WebSite">
|
||||
<p id="server_summary">
|
||||
<?=count($room_database->rooms)?> unique Session Communities
|
||||
on <?=count($room_database->servers)?> servers have been found.
|
||||
<?php if (SiteGeneration::getTargetDocumentRoute() == '/'): ?>
|
||||
<noscript>
|
||||
<span>
|
||||
(Viewing <?=count($rooms)?>;
|
||||
<a
|
||||
href="/groups/all"
|
||||
title="Full list of Communities"
|
||||
>full list</a>.)
|
||||
</span>
|
||||
</noscript>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<p id="last_checked">
|
||||
Last checked <span id="last_checked_value" itemprop="dateModified" value="<?=$time_modified_str?>">
|
||||
<?=$time_modified_str?> (UTC)
|
||||
</span>.
|
||||
</p>
|
||||
</aside>
|
||||
<aside id="details">
|
||||
<details>
|
||||
<summary class="carousel-label aside__h2 h2-like">What is Session Messenger?</summary>
|
||||
<p class="carousel-target">
|
||||
<a href="https://getsession.org/" rel="external">Session</a>
|
||||
is a private messaging app that protects your meta-data,
|
||||
encrypts your communications, and makes sure your messaging activities
|
||||
leave no digital trail behind. <a href="/about/" title="About page">Read more.</a>
|
||||
</p>
|
||||
</details>
|
||||
<details>
|
||||
<summary class="carousel-label aside__h2 h2-like">What are Session Communities?</summary>
|
||||
<p class="carousel-target">
|
||||
Session Communities are public Session chat rooms accessible from within Session Messenger.
|
||||
This web project crawls known sources of Session Communities, and
|
||||
displays information about them as a static HTML page. <a href="/about/" title="About page">Read more.</a>
|
||||
</p>
|
||||
</details>
|
||||
<p>Disclaimer:</p>
|
||||
<p id="content-disclaimer">
|
||||
Session chat rooms shown on this list are fetched automatically from
|
||||
<a
|
||||
href="<?=$REPOSITORY_CANONICAL_URL?>#which-sources-are-crawled"
|
||||
target="_blank"
|
||||
>various sources</a>.
|
||||
<br>
|
||||
<span class="js-only">
|
||||
We make an attempt to hide Communities containing
|
||||
objectionable or illegal content, but
|
||||
you should still proceed with caution.
|
||||
</span>
|
||||
<noscript>
|
||||
<span>
|
||||
Proceed with caution when joining unofficial Communities.
|
||||
As JavaScript is disabled, no Communities are filtered from the list.
|
||||
</span>
|
||||
</noscript>
|
||||
</p>
|
||||
<noscript>
|
||||
<p>
|
||||
SessionCommunities.online works fine without JavaScript.
|
||||
However, some interactive features are
|
||||
only available with JS enabled.
|
||||
</p>
|
||||
</noscript>
|
||||
</aside>
|
||||
<?php include "+components/footer.php"; ?>
|
||||
|
||||
<div id="copy-snackbar"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,116 @@
|
||||
<?php
|
||||
require_once 'php/servers/servers-rooms.php';
|
||||
require_once 'php/utils/utils.php';
|
||||
|
||||
class RoomSieve {
|
||||
/**
|
||||
* @var CommunityRoom[] $rooms;
|
||||
*/
|
||||
private array $rooms;
|
||||
|
||||
/**
|
||||
* @var CommunityRoom[] $stickied
|
||||
*/
|
||||
private array $stickies;
|
||||
|
||||
/**
|
||||
* @param CommunityRoom[] $rooms
|
||||
* @param CommunityRoom[] $stickied
|
||||
*/
|
||||
private function __construct(array $rooms, array $stickied = []) {
|
||||
$this->rooms = $rooms;
|
||||
$this->stickies = $stickied;
|
||||
}
|
||||
|
||||
public const TOP_DEFAULT = 35;
|
||||
|
||||
/**
|
||||
* @param CommunityRoom[] $rooms
|
||||
*/
|
||||
public static function takeRooms(array $rooms) {
|
||||
return new RoomSieve($rooms);
|
||||
}
|
||||
|
||||
public function saveStickies() {
|
||||
$stickied = CommunityRoom::get_stickied_rooms($this->rooms, $rest);
|
||||
$rooms = $rest;
|
||||
return new RoomSieve($rooms, $stickied);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CommunityRoom[] $rooms
|
||||
*/
|
||||
public function addRooms(array $rooms) {
|
||||
return new RoomSieve(array_merge($this->rooms, $rooms), $this->stickies);
|
||||
}
|
||||
|
||||
public function apply(Closure $filter) {
|
||||
return new RoomSieve($filter($this->rooms), $this->stickies);
|
||||
}
|
||||
|
||||
public function getWithStickies() {
|
||||
return [...$this->stickies, ...$this->rooms];
|
||||
}
|
||||
|
||||
public function getWithoutStickies() {
|
||||
return $this->saveStickies()->getRooms();
|
||||
}
|
||||
|
||||
public function getRooms() {
|
||||
return $this->rooms;
|
||||
}
|
||||
|
||||
public function onlyTop(int $count = RoomSieve::TOP_DEFAULT) {
|
||||
$rooms = $this->rooms;
|
||||
return new RoomSieve(array_slice(array_reverse($rooms), 0, $count), $this->stickies);
|
||||
}
|
||||
|
||||
public function exceptTop(int $count = RoomSieve::TOP_DEFAULT) {
|
||||
$rooms = $this->rooms;
|
||||
CommunityRoom::sort_rooms_num($rooms, 'active_users');
|
||||
return new RoomSieve(array_slice(array_reverse($rooms), $count), $this->stickies);
|
||||
}
|
||||
|
||||
private static function isIndexApproved(CommunityRoom $room): bool {
|
||||
return (
|
||||
!$room->rated_nsfw() &&
|
||||
$room->write &&
|
||||
!$room->has_poor_staff_rating() &&
|
||||
!empty($room->description)
|
||||
);
|
||||
}
|
||||
|
||||
public function applyStandardSort() {
|
||||
$rooms = $this->rooms;
|
||||
CommunityRoom::sort_rooms_str($rooms, 'name');
|
||||
CommunityRoom::sort_rooms_by_server($rooms);
|
||||
return new RoomSieve($rooms, $this->stickies);
|
||||
}
|
||||
|
||||
public function applyPreferentialSort() {
|
||||
$rooms = $this->rooms;
|
||||
CommunityRoom::sort_rooms_num($rooms,'created');
|
||||
usort($rooms, function($a, $b) {
|
||||
return empty($b->description) - empty($a->description);
|
||||
});
|
||||
usort($rooms, function(CommunityRoom $a, CommunityRoom $b) {
|
||||
return sign($a->get_numeric_staff_rating() - $b->get_numeric_staff_rating());
|
||||
});
|
||||
return new RoomSieve(array_reverse($rooms), $this->stickies);
|
||||
}
|
||||
|
||||
public function indexApproved() {
|
||||
$rooms = array_values(array_filter($this->rooms, function($room) {
|
||||
return RoomSieve::isIndexApproved($room);
|
||||
}));
|
||||
return new RoomSieve($rooms, $this->stickies);
|
||||
}
|
||||
|
||||
public function indexNonApproved() {
|
||||
$rooms = array_values(array_filter($this->rooms, function($room) {
|
||||
return !RoomSieve::isIndexApproved($room);
|
||||
}));
|
||||
return new RoomSieve($rooms, $this->stickies);
|
||||
}
|
||||
}
|
||||
?>
|
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
require_once '+getenv.php';
|
||||
require_once 'php/utils/getopt.php';
|
||||
require_once 'php/servers/room-database.php';
|
||||
require_once 'sites/_fragment/+room-sieve.php';
|
||||
require_once "sites/+components/table/table-fragment.php";
|
||||
|
||||
$room_database = CommunityDatabase::read_from_file($ROOMS_FILE)->fetch_assets();
|
||||
$rooms =
|
||||
RoomSieve::takeRooms($room_database->rooms)
|
||||
->indexApproved()
|
||||
->exceptTop()
|
||||
->addRooms(
|
||||
RoomSieve::takeRooms($room_database->rooms)
|
||||
->indexNonApproved()
|
||||
->getWithoutStickies()
|
||||
)
|
||||
->applyPreferentialSort()
|
||||
->getWithoutStickies();
|
||||
|
||||
renderCommunityRoomTableFragment($rooms);
|
||||
?>
|
@ -0,0 +1 @@
|
||||
<h1 id="headline">Full list of Session Communities</h1>
|
@ -0,0 +1,13 @@
|
||||
<title>All Communities — sessioncommunities.online</title>
|
||||
<meta name="description" content="Chat in Session Communities! <?php
|
||||
?>Use our list to join your favorite Community in Session Messenger. <?php
|
||||
?>Copy public Session group links into the Session app!<?php
|
||||
?>">
|
||||
<meta name="keywords" content="session communities,session groups,session group list,session chat">
|
||||
<meta property="og:title" content="Session Communities — Come chat!">
|
||||
<meta
|
||||
property="og:description"
|
||||
content="100+ Session Communities."
|
||||
>
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:locale" content="en_US"/>
|
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
require_once '+getenv.php';
|
||||
require_once 'php/utils/getopt.php';
|
||||
require_once 'php/servers/room-database.php';
|
||||
require_once 'sites/_fragment/+room-sieve.php';
|
||||
|
||||
$room_database = CommunityDatabase::read_from_file($ROOMS_FILE)->fetch_assets();
|
||||
$rooms =
|
||||
RoomSieve::takeRooms($room_database->rooms)
|
||||
->saveStickies()
|
||||
->applyStandardSort()
|
||||
->getWithStickies();
|
||||
|
||||
include "+templates/index.php";
|
||||
?>
|
Loading…
Reference in New Issue