This is the code that runs https://bandolier.learnjsthehardway.com/ for you to review. It uses the https://git.learnjsthehardway.com/learn-javascript-the-hard-way/bandolier-template to create the documentation for the project.
https://bandolier.learnjsthehardway.com/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
171 lines
3.8 KiB
171 lines
3.8 KiB
2 years ago
|
<script>
|
||
|
import { user } from "$/client/stores.js";
|
||
|
import { configure_socket, reconnect_socket } from '$/client/websocket.js';
|
||
|
import { onMount, afterUpdate } from 'svelte';
|
||
|
import { fade } from 'svelte/transition';
|
||
|
|
||
|
let socket;
|
||
|
|
||
|
let admin_top = {initials: '@',
|
||
|
admin: true,
|
||
|
size_at: 0,
|
||
|
text: 'Messages are from the private discord server.'
|
||
|
}
|
||
|
|
||
|
const messages_height = 11;
|
||
|
|
||
|
let admin_messages = [admin_top];
|
||
|
let messages = [admin_top];
|
||
|
|
||
|
$: if(admin_top && !admin_top.display_at && messages.length - admin_top.size_at > messages_height) {
|
||
|
// mark the new one for display
|
||
|
admin_top.display = true;
|
||
|
// kick off a timer to hide it after 10 seconds on top
|
||
|
admin_top.display_at = new Date();
|
||
|
}
|
||
|
|
||
|
afterUpdate(() => {
|
||
|
let msg_scroll = document.getElementById('messages');
|
||
|
msg_scroll.scrollTop = msg_scroll.scrollHeight;
|
||
|
});
|
||
|
|
||
|
const setup_socket = async () => {
|
||
|
await configure_socket();
|
||
|
socket = reconnect_socket();
|
||
|
socket.on("/chat/message", (data) => {
|
||
|
data.size_at = messages.length;
|
||
|
messages.push(data);
|
||
|
messages = messages;
|
||
|
|
||
|
if(data.admin) {
|
||
|
admin_messages.push(data);
|
||
|
admin_top = admin_messages[admin_messages.length - 1];
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
onMount(async () => {
|
||
|
if($user.authenticated) {
|
||
|
// the socket connection sometimes isn't actually
|
||
|
// authenticated to just reconnect if the users is auth
|
||
|
await setup_socket();
|
||
|
}
|
||
|
|
||
|
window.setInterval(() => {
|
||
|
if(admin_top && admin_top.display) {
|
||
|
// see if this is old and kick it off
|
||
|
const live_time = Date.now() - admin_top.display_at;
|
||
|
if(live_time > 10000) {
|
||
|
admin_top.display = false;
|
||
|
}
|
||
|
}
|
||
|
}, 1000);
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
|
||
|
<style>
|
||
|
chat {
|
||
|
display: flex;
|
||
|
flex-direction: column;
|
||
|
font-size: 0.8em;
|
||
|
position: relative;
|
||
|
height: 100%;
|
||
|
}
|
||
|
|
||
|
chat messages {
|
||
|
display: flex;
|
||
|
flex-direction: column;
|
||
|
overflow-y: hidden;
|
||
|
overflow-x: hidden;
|
||
|
height: 100%;
|
||
|
margin-bottom: 0px;
|
||
|
}
|
||
|
|
||
|
chat messages:hover {
|
||
|
overflow-y: auto;
|
||
|
}
|
||
|
|
||
|
chat messages message from {
|
||
|
margin-right: 0.9rem;
|
||
|
background-color: #555;
|
||
|
color: #fff;
|
||
|
padding: 0.2rem;
|
||
|
border-radius: 50%;
|
||
|
font-size: 0.5em;
|
||
|
border: 1px solid var(--color-accent);
|
||
|
}
|
||
|
|
||
|
chat messages message {
|
||
|
padding: 0.3rem;
|
||
|
}
|
||
|
|
||
|
chat message.persistent {
|
||
|
padding: 0.3rem;
|
||
|
box-shadow: var(--box-shadow) var(--color-shadow);
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
left: 0;
|
||
|
right: 0;
|
||
|
margin: 2px;
|
||
|
}
|
||
|
|
||
|
chat message.admin {
|
||
|
background-color: var(--color-bg-tertiary);
|
||
|
padding-top: 0.5rem;
|
||
|
padding-bottom: 0.5rem;
|
||
|
font-size: 0.9rem;
|
||
|
}
|
||
|
|
||
|
chat form {
|
||
|
display: flex;
|
||
|
border: unset;
|
||
|
padding: unset;
|
||
|
justify-content: space-evenly;
|
||
|
max-width: unset;
|
||
|
min-width: unset;
|
||
|
flex-direction: column;
|
||
|
}
|
||
|
|
||
|
chat-input form {
|
||
|
box-shadow: unset;
|
||
|
}
|
||
|
|
||
|
chat-input form input {
|
||
|
border: 1px solid var(--color-accent);
|
||
|
margin-bottom: unset;
|
||
|
width: 100%;
|
||
|
max-width: unset;
|
||
|
padding: 4px !important;
|
||
|
background: var(--color-bg-secondary);
|
||
|
box-sizing: border-box;
|
||
|
color: var(--color-text);
|
||
|
}
|
||
|
|
||
|
input#login-to-chat {
|
||
|
border: 1px solid #222;
|
||
|
margin-bottom: unset;
|
||
|
border-radius: 0px 0px 0px 0px;
|
||
|
}
|
||
|
|
||
|
input#login-to-chat:hover {
|
||
|
cursor: progress;
|
||
|
}
|
||
|
</style>
|
||
|
|
||
|
<chat data-testid="chat-panel">
|
||
|
{#if admin_top && admin_top.display }
|
||
|
<message in:fade out:fade class="admin persistent">
|
||
|
<from>{admin_top.initials}</from><span>{admin_top.text}</span>
|
||
|
</message>
|
||
|
{/if}
|
||
|
|
||
|
<messages id="messages">
|
||
|
{#each messages as message, i}
|
||
|
<message in:fade class:admin={ message.admin }>
|
||
|
<from>{message.initials}</from><span>{message.text}</span>
|
||
|
</message>
|
||
|
{/each}
|
||
|
</messages>
|
||
|
</chat>
|