Made the babblebox a live, reactive component
This commit is contained in:
parent
1b9106fadb
commit
faefbb37d4
|
@ -2,6 +2,10 @@
|
|||
--font-size: 12px;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: var(--font-size);
|
||||
font-family: sans-serif;
|
||||
|
@ -200,3 +204,26 @@ div.stat-bar > div {
|
|||
position: absolute;
|
||||
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';
|
||||
|
||||
// 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->get('/', function() {
|
||||
|
@ -39,14 +45,14 @@ $r->get('/character', 'show_character_info');
|
|||
$r->get('/character/:id', 'show_character_info');
|
||||
$r->get('/showmap', 'showmap');
|
||||
$r->form('/babblebox', 'babblebox');
|
||||
$r->get('/babblebox/messages', 'babblebox_messages');
|
||||
|
||||
// [code, handler, params, middleware]
|
||||
$l = $r->lookup($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']);
|
||||
|
||||
if (is_int($l)) exit("Error: $l");
|
||||
if (!empty($l['middleware'])) foreach ($l['middleware'] as $middleware) $middleware();
|
||||
$content = $l['handler'](...$l['params'] ?? []);
|
||||
if (is_htmx()) {
|
||||
if (is_htmx() && $uri[0] !== 'babblebox') {
|
||||
$content .= Render\debug_db_info();
|
||||
if ($GLOBALS['state']['user-state-changed'] ?? false) {
|
||||
$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()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$safecontent = make_safe($_POST["babble"]);
|
||||
if (!empty($safecontent)) {
|
||||
$content = trim($_POST["babble"]);
|
||||
if (!empty($content)) {
|
||||
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');
|
||||
} elseif (file_exists(('../.installed')) && $uri[0] === 'install') {
|
||||
redirect('/');
|
||||
} elseif (file_exists(('../.installed')) && $uri[0] !== 'install') {
|
||||
} else {
|
||||
$controlrow = get_control_row();
|
||||
|
||||
if (!$controlrow["gameopen"]) {
|
||||
|
|
|
@ -38,3 +38,8 @@ function right_nav(): string
|
|||
if (is_htmx()) $template = '<section id="right" hx-swap-oob="true">'.$template."</section>";
|
||||
return $template;
|
||||
}
|
||||
|
||||
function babblebox(): string
|
||||
{
|
||||
return render('babblebox', ['messages' => babblebox_messages()]);
|
||||
}
|
||||
|
|
|
@ -1,58 +1,29 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<title>Babblebox</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-image: url('/img/background.jpg');
|
||||
color: black;
|
||||
font: 11px verdana;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
<div id="babblebox">
|
||||
<div class="messages" hx-get="/babblebox/messages" hx-trigger="every 5s">
|
||||
<?= $messages ?>
|
||||
</div>
|
||||
|
||||
div {
|
||||
padding: 2px;
|
||||
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>
|
||||
<form hx-post="/babblebox" hx-target="#babblebox > .messages" style="margin-top: 1rem;">
|
||||
<input type="text" name="babble" maxlength="255"><br>
|
||||
<input type="submit" name="submit" value="Babble">
|
||||
<input type="reset" name="reset" value="Clear">
|
||||
</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>
|
||||
document.addEventListener("updateTitle", (event) => {
|
||||
const title = event.detail?.title;
|
||||
const title = event.detail?.title
|
||||
if (title) {
|
||||
console.log('New title:', title);
|
||||
document.title = title;
|
||||
}
|
||||
});
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
</div>
|
||||
|
||||
<div class="babblebox">
|
||||
<?= $town['babblebox'] ?>
|
||||
<div class="title">Babblebox</div>
|
||||
<?= Render\babblebox() ?>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue
Block a user