Merge branch 'main' of lokilocker.com:SomeGuy/sessioncommunities.online

dev
mdPlusPlus 1 year ago
commit cef10a3a57

@ -16,4 +16,6 @@
// do not report warnings (timeouts, SSL/TLS errors)
error_reporting(E_ALL & ~E_WARNING);
date_default_timezone_set('UTC');
?>

@ -6,7 +6,7 @@ export const dom = {
tbl_communities: () => document.getElementById("tbl_communities"),
last_checked: () => document.getElementById("last_checked_value"),
qr_modal: (communityID) => document.getElementById(`modal_${communityID}`),
join_urls: () => document.getElementsByClassName("td_join_url"),
join_urls: () => document.getElementsByClassName("join_url_container"),
servers_hidden: () => document.getElementById("servers_hidden"),
snackbar: () => document.getElementById("copy-snackbar")
}
@ -57,3 +57,29 @@ export function columnIsNumeric(column) {
].includes(column);
}
/**
* Creates an element, and adds attributes and elements to it.
* @param {string} tag - HTML Tag name.
* @param {Object|HTMLElement} args - Array of child elements, may start with props.
* @returns {HTMLElement}
*/
function createElement(tag, ...args) {
const element = document.createElement(tag);
if (args.length === 0) return element;
const propsCandidate = args[0];
if (typeof propsCandidate !== "string" && !(propsCandidate instanceof Element)) {
// args[0] is not child element or text node
// must be props object
Object.assign(element, propsCandidate);
args.shift();
}
element.append(...args);
return element;
}
export const element = new Proxy({}, {
get(_, key) {
return (...args) => createElement(key, ...args)
}
});

@ -17,7 +17,7 @@
import {
dom, COLUMN, COLUMN_LITERAL, COMPARISON, ATTRIBUTES,
columnAscendingByDefault, columnIsSortable, columnNeedsCasefold,
columnIsNumeric
columnIsNumeric, element
} from './js/constants.js';
// Hidden communities for transparency.
@ -50,12 +50,13 @@ const filteredCommunities = {
// This can be achieved with `text-overflow: ellipsis` instead
// and generated entirely server-side.
const transformJoinURL = (join_link) =>
`${join_link.substring(0, 31)}...
<button class="copy_button" onclick="copyToClipboard('${join_link}')">
Copy
</button>
`.trim();
const transformJoinURL = (join_link) => {
return element.button({
textContent: "Copy",
className: "copy_button",
onclick: () => copyToClipboard(join_link)
});
}
function onLoad(timestamp) {
setLastChecked(timestamp);
@ -78,7 +79,7 @@ function createJoinLinkButtons() {
Array.from(join_URLs).forEach((td_url) => {
const a_href = td_url.querySelector('a'); // get first (only) <a> element
const join_link = a_href.getAttribute("href"); // get link
td_url.innerHTML = transformJoinURL(join_link); // add interactive content
td_url.append(transformJoinURL(join_link)); // add interactive content
});
}
@ -131,7 +132,7 @@ function setLastChecked(last_checked) {
const time_passed_in_minutes =
Math.floor(time_passed_in_seconds / 60); // time in minutes, rounded down
const timestamp_element = dom.last_checked();
timestamp_element.innerText = `${time_passed_in_minutes} minutes`;
timestamp_element.innerText = `${time_passed_in_minutes} minutes ago`;
}
/**
@ -279,6 +280,9 @@ 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, {

@ -1,60 +1,98 @@
html {
font-size: clamp(10px, 2vw, 18px);
}
html.js .noscript {
display: none;
}
/* Dead style */
html:not(.js) .js-only {
display: none;
}
header {
display: flex;
direction: row;
/* Push items as far apart as possible */
justify-content: space-between;
display: flex;
direction: row;
/* Push items as far apart as possible */
justify-content: space-between;
}
#headline {
text-align: center;
flex-grow: 1;
text-align: center;
flex-grow: 1;
}
#tbl_communities { width:100%; }
#th_identifier { width:9%; }
.td_identifier { font-family: monospace; }
#th_name { width:13%; }
#th_language { width:0% }
/* Hide the identifier column before removal. */
#th_identifier { display: none; }
.td_identifier { display: none; font-family: monospace; }
.td_language:empty::after {
content: "\2753";
}
#th_description { }
.td_description {
overflow: hidden;
text-overflow: ellipsis;
display:
-webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
}
#th_users { width:0% }
.td_users { text-align: right; }
#th_preview { max-width:5%; }
.td_preview { text-align: center; }
#th_qr { width:0%; }
#th_join_url { width:15%; }
.td_join_url {
font-family: monospace;
white-space: nowrap;
font-size: .8em;
}
.copy_button { }
.join_url {
/* Apply margin against copy button or link. */
/* URL now guaranteed to have interactive element to right when present. */
margin-right: 1em;
}
@media (max-width: 950px) {
/* Only current width breakpoint; */
/* Would follow w4 and precede w6. */
.show-from-w5 {
display: none;
}
}
.join_url_container {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.copy_button { font-size: inherit }
footer {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
text-align: center;
}
footer p {
width: 75%;
margin: .5em;
text-align: center;
width: 75%;
margin: .5em;
text-align: center;
}
footer nav a {
margin: 0 .5ch;
display: inline-block;
margin: .25em;
white-space: nowrap;
}
/* <Colors> */
@ -73,8 +111,8 @@ footer nav a {
display: inline-block;
font-family: monospace;
border-radius: 4px;
padding: .25em .05em;
width: 6ch;
line-height: 22px;
text-align: center;
}
.protocol-http { background-color:lightgray }
@ -170,3 +208,4 @@ footer nav a {
from {bottom: 30px; opacity: 1;}
to {bottom: 0; opacity: 0;}
}

@ -18,6 +18,12 @@
return count($servers);
}
function truncate($url, $len) {
return (strlen($url) > $len + 3)
? substr($url, 0, $len).'...'
: $string;
}
/*
* Helper function for reduce_servers
*/

@ -1,2 +1,3 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/svg+xml" href="favicon.svg" sizes="any">

@ -53,27 +53,29 @@
// file_exists($QR_CODES) or mkdir($QR_CODES, 0700); // @Deprecated
?>
<div id="modal-container">
<?php foreach ($rooms as $id => $room): ?>
<div id="modal_<?=$id?>" class="qr-code-modal">
<div class="qr-code-modal-content">
<span class="qr-code-modal-close" onclick='hideQRModal("<?=$id?>")'>
&times;
</span>
<!--
<img
src="data:image/png;base64,<?=base64_qr_code($id, $room->join_link)?>"
alt="Community join link encoded as QR code"
class="qr-code"
loading="lazy"
>
-->
<img
src="<?=room_qr_code_native($room->join_link)?>"
alt="Community join link encoded as QR code"
class="qr-code"
loading="lazy"
referrerpolicy="no-referrer"
>
<div id="modal_<?=$id?>" class="qr-code-modal">
<div class="qr-code-modal-content">
<span class="qr-code-modal-close" onclick='hideQRModal("<?=$id?>")'>
&times;
</span>
<!--
<img
src="data:image/png;base64,<?=base64_qr_code($id, $room->join_link)?>"
alt="Community join link encoded as QR code"
class="qr-code"
loading="lazy"
>
-->
<img
src="<?=room_qr_code_native($room->join_link)?>"
alt="Community join link encoded as QR code"
class="qr-code"
loading="lazy"
referrerpolicy="no-referrer"
>
</div>
</div>
</div>
<?php endforeach; ?>
</div>

@ -1,4 +1,6 @@
<?php
<?php
require_once "$PROJECT_ROOT/php/utils/server-utils.php";
// Once handlers are attached in JS, this check ceases to be useful.
function column_sortable($id) {
return $id != "qr";
@ -37,10 +39,8 @@
<td class="td_identifier"><?=$id?></td>
<td class="td_language"><?=$room->language?></td>
<td class="td_name"><?=$room->name?></td>
<td class="td_description">
<?=$room->description?>
</td>
<td class="td_description"
><?=$room->description?></td>
<td class="td_users"><?=$room->active_users?></td>
<td class="td_preview">
<a href="<?=$room->preview_link?>" target="_blank" rel="noopener noreferrer">
@ -61,10 +61,12 @@
>
</td>
<td class="td_join_url">
<a href="<?=$room->join_link?>">
<?=$room->join_link?>
</a>
<div class="join_url_container">
<a class="join_url show-from-w5" title="<?=$room->join_link?>"
><?=truncate($room->join_link, 32)?></a>
<a class="noscript" href="<?=$room->join_link?>"
>Copy link</a>
</div>
</td>
</tr>
<?php endforeach; ?>

@ -42,7 +42,9 @@
<span id="servers_hidden">(None hidden as JS is off)</span>
</p>
<p id="last_checked">
Last checked <span id="last_checked_value"></span> ago.
Last checked <span id="last_checked_value">
<?=date("Y-m-d H:i:s", $timestamp)?> (UTC)
</span>.
</p>
<p id="disclaimer">
This site is not affiliated with
@ -55,13 +57,11 @@
objectionable or illegal content, but
you should still proceed with caution.
</p>
<noscript>
<p>
This site works fine without JavaScript.
However, some interactive features are
only available with JS enabled.
</p>
</noscript>
<p class="noscript">
This site works fine without JavaScript.
However, some interactive features are
only available with JS enabled.
</p>
<nav>
<a
href="https://lokilocker.com/Mods/Session-Groups/wiki/Session-Closed-Groups"

Loading…
Cancel
Save