Made the babblebox a live, reactive component
This commit is contained in:
parent
1b9106fadb
commit
faefbb37d4
|
@ -2,6 +2,10 @@
|
||||||
--font-size: 12px;
|
--font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
font-size: var(--font-size);
|
font-size: var(--font-size);
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
@ -200,3 +204,26 @@ div.stat-bar > div {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#babblebox > .messages {
|
||||||
|
max-height: 200px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#babblebox > .messages .message {
|
||||||
|
padding: 0.25rem;
|
||||||
|
background-color: #eee;
|
||||||
|
|
||||||
|
&:nth-child(even) {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#babblebox > form {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
|
||||||
|
& > input[type="text"] {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,12 @@
|
||||||
|
|
||||||
require_once '../src/bootstrap.php';
|
require_once '../src/bootstrap.php';
|
||||||
|
|
||||||
|
// Do an early return with babblebox data if that's what's being requested
|
||||||
|
if ($uri[0] === 'babblebox' && (isset($uri[1]) && $uri[1] === 'messages')) {
|
||||||
|
echo babblebox_messages();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
$r = new Router;
|
$r = new Router;
|
||||||
|
|
||||||
$r->get('/', function() {
|
$r->get('/', function() {
|
||||||
|
@ -39,14 +45,14 @@ $r->get('/character', 'show_character_info');
|
||||||
$r->get('/character/:id', 'show_character_info');
|
$r->get('/character/:id', 'show_character_info');
|
||||||
$r->get('/showmap', 'showmap');
|
$r->get('/showmap', 'showmap');
|
||||||
$r->form('/babblebox', 'babblebox');
|
$r->form('/babblebox', 'babblebox');
|
||||||
|
$r->get('/babblebox/messages', 'babblebox_messages');
|
||||||
|
|
||||||
// [code, handler, params, middleware]
|
// [code, handler, params, middleware]
|
||||||
$l = $r->lookup($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']);
|
$l = $r->lookup($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']);
|
||||||
|
|
||||||
if (is_int($l)) exit("Error: $l");
|
if (is_int($l)) exit("Error: $l");
|
||||||
if (!empty($l['middleware'])) foreach ($l['middleware'] as $middleware) $middleware();
|
|
||||||
$content = $l['handler'](...$l['params'] ?? []);
|
$content = $l['handler'](...$l['params'] ?? []);
|
||||||
if (is_htmx()) {
|
if (is_htmx() && $uri[0] !== 'babblebox') {
|
||||||
$content .= Render\debug_db_info();
|
$content .= Render\debug_db_info();
|
||||||
if ($GLOBALS['state']['user-state-changed'] ?? false) {
|
if ($GLOBALS['state']['user-state-changed'] ?? false) {
|
||||||
$content .= Render\right_nav();
|
$content .= Render\right_nav();
|
||||||
|
@ -113,22 +119,36 @@ function showmap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Either render the latest 40 chats to the babblebox, or add a chat to it and redirect. This is used
|
* ...
|
||||||
* within an iframe.
|
|
||||||
*/
|
*/
|
||||||
function babblebox()
|
function babblebox()
|
||||||
{
|
{
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
$safecontent = make_safe($_POST["babble"]);
|
$content = trim($_POST["babble"]);
|
||||||
if (!empty($safecontent)) {
|
if (!empty($content)) {
|
||||||
db()->query('INSERT INTO babble (posttime, author, babble) VALUES (CURRENT_TIMESTAMP, ?, ?);',
|
db()->query('INSERT INTO babble (posttime, author, babble) VALUES (CURRENT_TIMESTAMP, ?, ?);',
|
||||||
[user()->username, $safecontent]);
|
[user()->username, $content]);
|
||||||
}
|
}
|
||||||
redirect('/babblebox');
|
return babblebox_messages();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$query = db()->query('SELECT * FROM babble ORDER BY id DESC LIMIT 40;');
|
/**
|
||||||
echo render('babblebox', ['messages' => $query]);
|
* Is the handler for the HTMX get request for messages.
|
||||||
|
*/
|
||||||
|
function babblebox_messages(): string
|
||||||
|
{
|
||||||
|
if (user() === false) return '';
|
||||||
|
|
||||||
|
$query = db()->query('SELECT * FROM babble ORDER BY id ASC LIMIT 40;');
|
||||||
|
$has_chats = false;
|
||||||
|
$messages = '';
|
||||||
|
while ($row = $query->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
$has_chats = true;
|
||||||
|
$messages .= '<div class="message">[<b>' . $row['author'] . '</b>] ' . make_safe($row['babble']) . '</div>';
|
||||||
|
}
|
||||||
|
if (!$has_chats) $messages = 'There are no messages. :(';
|
||||||
|
return $messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,7 +27,7 @@ if (!file_exists('../.installed') && $uri[0] !== 'install') {
|
||||||
redirect('/install');
|
redirect('/install');
|
||||||
} elseif (file_exists(('../.installed')) && $uri[0] === 'install') {
|
} elseif (file_exists(('../.installed')) && $uri[0] === 'install') {
|
||||||
redirect('/');
|
redirect('/');
|
||||||
} elseif (file_exists(('../.installed')) && $uri[0] !== 'install') {
|
} else {
|
||||||
$controlrow = get_control_row();
|
$controlrow = get_control_row();
|
||||||
|
|
||||||
if (!$controlrow["gameopen"]) {
|
if (!$controlrow["gameopen"]) {
|
||||||
|
|
|
@ -38,3 +38,8 @@ function right_nav(): string
|
||||||
if (is_htmx()) $template = '<section id="right" hx-swap-oob="true">'.$template."</section>";
|
if (is_htmx()) $template = '<section id="right" hx-swap-oob="true">'.$template."</section>";
|
||||||
return $template;
|
return $template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function babblebox(): string
|
||||||
|
{
|
||||||
|
return render('babblebox', ['messages' => babblebox_messages()]);
|
||||||
|
}
|
||||||
|
|
|
@ -1,58 +1,29 @@
|
||||||
<html lang="en">
|
<div id="babblebox">
|
||||||
<head>
|
<div class="messages" hx-get="/babblebox/messages" hx-trigger="every 5s">
|
||||||
<title>Babblebox</title>
|
<?= $messages ?>
|
||||||
<style type="text/css">
|
</div>
|
||||||
body {
|
|
||||||
background-image: url('/img/background.jpg');
|
|
||||||
color: black;
|
|
||||||
font: 11px verdana;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div {
|
<form hx-post="/babblebox" hx-target="#babblebox > .messages" style="margin-top: 1rem;">
|
||||||
padding: 2px;
|
<input type="text" name="babble" maxlength="255"><br>
|
||||||
border: solid 1px black;
|
|
||||||
margin: 2px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #663300;
|
|
||||||
text-decoration: none;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
color: #330000;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.message {
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.message:nth-child(even) {
|
|
||||||
background-color: #eeeeee;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body onload="window.scrollTo(0, 99999)">
|
|
||||||
<?php
|
|
||||||
$has_chats = false;
|
|
||||||
while ($row = $messages->fetchArray(SQLITE3_ASSOC)):
|
|
||||||
$has_chats = true;
|
|
||||||
?>
|
|
||||||
<div class="message">[<b><?= $row['author'] ?></b>] <?= $row['babble'] ?></div>
|
|
||||||
<?php
|
|
||||||
endwhile;
|
|
||||||
if (!$has_chats) echo 'There are no messages. :(';
|
|
||||||
?>
|
|
||||||
|
|
||||||
<form action="/babblebox" method="post" style="margin-top: 1rem;">
|
|
||||||
<input type="text" name="babble" maxlength="255" style="width: 100%;"><br>
|
|
||||||
<input type="submit" name="submit" value="Babble">
|
<input type="submit" name="submit" value="Babble">
|
||||||
<input type="reset" name="reset" value="Clear">
|
<input type="reset" name="reset" value="Clear">
|
||||||
</form>
|
</form>
|
||||||
</body>
|
|
||||||
</html>
|
<script>
|
||||||
|
const chatBox = document.querySelector('#babblebox > .messages')
|
||||||
|
let isUserAtBottom = true
|
||||||
|
if (chatBox !== null) {
|
||||||
|
chatBox.scrollTop = chatBox.scrollHeight;
|
||||||
|
const isAtBottom = () => chatBox.scrollHeight - chatBox.scrollTop === chatBox.clientHeight
|
||||||
|
|
||||||
|
const scrollChatToBottom = () => {
|
||||||
|
if (isUserAtBottom) chatBox.scrollTop = chatBox.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
const observer = new MutationObserver(scrollChatToBottom)
|
||||||
|
observer.observe(chatBox, { childList: true, subtree: true })
|
||||||
|
|
||||||
|
chatBox.addEventListener('scroll', () => isUserAtBottom = isAtBottom())
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
|
@ -55,12 +55,12 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("updateTitle", (event) => {
|
document.addEventListener("updateTitle", (event) => {
|
||||||
const title = event.detail?.title;
|
const title = event.detail?.title
|
||||||
if (title) {
|
if (title) {
|
||||||
console.log('New title:', title);
|
console.log('New title:', title);
|
||||||
document.title = title;
|
document.title = title;
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="babblebox">
|
<div class="babblebox">
|
||||||
<?= $town['babblebox'] ?>
|
<div class="title">Babblebox</div>
|
||||||
|
<?= Render\babblebox() ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user