This is a parody of leetcode.com for designers. It's being developed live on Twitch.tv/zedashaw to demonstrate how to make a parody of a website.
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.
pixelperfectionist/client/components/DiscordReplay.svelte

171 lines
3.8 KiB

<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>