body{
/* https://www.color-hex.com/color/d3d3d3 */
background-color: #fff; /*#f6f6f6, EBEBD3, fafafa*/
font-family: Bungee Outline;
font-weight: 900;
overflow: hidden;
animation: blur 0.5s ease-out;
}
*{
outline: none;
border: none;
padding: 0;
margin: 0;
box-sizing: border-box;
}
#title_container{
width: 100%;
height: 225px;
display: flex;
justify-content: center;
align-items: center;
background-color: #D64045;/*#467599;*/
border-bottom: 5px solid #fff;
box-shadow: 0 0 30px -18px #D64045;
}
#title_inner_container{
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
/* background-color: #083D77; */
border-radius: 200px;
}
#title{
display: inline-block;
color: #fff;/*EBEBD3, C5283D*/
font-size: 55px;
letter-spacing: 2px;
user-select: none;
}
#join_container{
width: 100%;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
float: left;
margin-top: 80px;
}
#join_inner_container{
width: 50%;
height: 100%;
}
#join_input_container{
width: 100%;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
float: left;
}
#join_input{
width: 60%;
height: 40px;
color: #1D3354;
font-family: Varela Round;
font-size: 15px;
font-weight: bold;
text-align: center;
background-color: Transparent;
border-bottom: 2px dashed #1D3354;
}
#join_input:focus{
box-shadow: 0 10px 30px -17px #1D3354;
}
#join_button_container{
width: 100%;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
float: left;
}
#join_button{
width: 60%;
height: 40px;
font-family: Varela Round;
font-size: 15px;
font-weight: bold;
text-align: center;
color: #fff;
}
#chat_container{
width: 100%;
height: 450px;
display: flex;
justify-content: center;
float: left;
margin-top: 40px;
/* Fade in container */
animation: fadeIn 1s linear;
}
#chat_inner_container{
width: 40%;
height: 100%;
}
#chat_content_container{
width: 100%;
height: 90%;
float: left;
overflow-y: auto;
font-family: Varela Round;
padding-left: 15px;
padding-right: 15px;
}
#chat_input_container{
width: 100%;
height: 10%;
float: left;
border-bottom: 2px dashed #1D3354;
background-color: Transparent;
padding-left: 15px;
padding-right: 15px;
font-family: Varela Round;
margin-top: 10px;
}
#chat_input{
width: 95%;
height: 100%;
float: left;
background-color: Transparent;
color: #1D3354;
font-size: 15px;
}
#chat_input_send{
width: 5%;
height: 100%;
float: left;
font-size: 18px;
background-color: Transparent;
text-align: right;
color: #330300;
}
#chat_input_send.enabled{
color: #D64045;
background-color: Transparent;
cursor: pointer;
}
#chat_logout_container{
width: 100%;
display: inline-block;
display: flex;
justify-content: center;
align-items: center;
float: left;
margin-top: 20px;
}
#chat_logout{
color: #D64045;
cursor: pointer;
}
#chat_logout:hover{
text-decoration: underline;
}
.message_container{
width: 100%;
display: inline-block;
margin-bottom: 20px;
}
.message_inner_container{
width: 100%;
display: inline-block;
color: #1D3354;
}
.message_user_container{
width: 100%;
display: inline-block;
}
.message_user{
font-weight: bold;
font-size: 14px;
}
.message_content_container{
width: 100%;
display: inline-block;
white-space: pre-wrap;
word-wrap: break-word;
}
.message_content{
font-weight: normal;
font-size: 14px;
margin-top: 5px;
}
.enabled{
transition: background-color 0.5s;
color: #fff;
background-color: #D64045; /*#5B7553;*/
cursor: pointer;
}
#title_container.chat_title_container{
transition: 0.8s;
transition-timing-function: ease-in-out;
height: 100px;
}
#title.chat_title{
transition: 0.8s;
font-size: 47px;
}
.loader_container{
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.loader {
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
border-top: 6px solid #D64045;
border-bottom: 6px solid #1D3354;
border-left: 6px solid #E9FFF9;
border-right: 6px solid #E9FFF9;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@keyframes fadeIn {
0% {opacity: 0;}
100% {opacity: 1;}
}
@keyframes blur {
0% {filter: blur(5px);}
100% {}
}
::selection {
background-color: #D64045;
color: #fff;
}
/* width */
::-webkit-scrollbar {
width: 6px;
}
/* Track */
::-webkit-scrollbar-track {
background: #cccs;
}
/* Handle */
::-webkit-scrollbar-thumb {
background: #D64045;
border-radius: 5px;
}
Campus Chat
// We enclose this in window.onload.
// So we don't have ridiculous errors.
window.onload = function() {
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "AIzaSyAtYy9LU8Zc0Uw_Lk8j7eg8ukuXEePUSuk",
authDomain: "mn-university---campus-chat.firebaseapp.com",
projectId: "mn-university---campus-chat",
storageBucket: "mn-university---campus-chat.appspot.com",
messagingSenderId: "643089777993",
appId: "1:643089777993:web:23b40f13af647141ca4698"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
// This is very IMPORTANT!! We're going to use "db" a lot.
var db = firebase.database()
// We're going to use oBjEcT OrIeNtEd PrOgRaMmInG. Lol
class CAMPUS_CHAT{
// Home() is used to create the home page
home(){
// First clear the body before adding in
// a title and the join form
document.body.innerHTML = ''
this.create_title()
this.create_join_form()
}
// chat() is used to create the chat page
chat(){
this.create_title()
this.create_chat()
}
// create_title() is used to create the title
create_title(){
// This is the title creator. 🎉
var title_container = document.createElement('div')
title_container.setAttribute('id', 'title_container')
var title_inner_container = document.createElement('div')
title_inner_container.setAttribute('id', 'title_inner_container')
var title = document.createElement('h1')
title.setAttribute('id', 'title')
title.textContent = 'Campus Chat'
title_inner_container.append(title)
title_container.append(title_inner_container)
document.body.append(title_container)
}
// create_join_form() creates the join form
create_join_form(){
// YOU MUST HAVE (PARENT = THIS). OR NOT. I'M NOT YOUR BOSS!😂
var parent = this;
var join_container = document.createElement('div')
join_container.setAttribute('id', 'join_container')
var join_inner_container = document.createElement('div')
join_inner_container.setAttribute('id', 'join_inner_container')
var join_button_container = document.createElement('div')
join_button_container.setAttribute('id', 'join_button_container')
var join_button = document.createElement('button')
join_button.setAttribute('id', 'join_button')
join_button.innerHTML = 'Join '
var join_input_container = document.createElement('div')
join_input_container.setAttribute('id', 'join_input_container')
var join_input = document.createElement('input')
join_input.setAttribute('id', 'join_input')
join_input.setAttribute('maxlength', 15)
join_input.placeholder = 'No.... It\'s Patrick Star'
// Every time we type into the join_input
join_input.onkeyup = function(){
// If the input we have is longer that 0 letters
if(join_input.value.length > 0){
// Make the button light up
join_button.classList.add('enabled')
// Allow the user to click the button
join_button.onclick = function(){
// Save the name to local storage. Passing in
// the join_input.value
parent.save_name(join_input.value)
// Remove the join_container. So the site doesn't look weird.
join_container.remove()
// parent = this. But it is not the join_button
// It is (MEME_CHAT = this).
parent.create_chat()
}
}else{
// If the join_input is empty then turn off the
// join button
join_button.classList.remove('enabled')
}
}
// Append everything to the body
join_button_container.append(join_button)
join_input_container.append(join_input)
join_inner_container.append(join_input_container, join_button_container)
join_container.append(join_inner_container)
document.body.append(join_container)
}
// create_load() creates a loading circle that is used in the chat container
create_load(container_id){
// YOU ALSO MUST HAVE (PARENT = THIS). BUT IT'S WHATEVER THO.
var parent = this;
// This is a loading function. Something cool to have.
var container = document.getElementById(container_id)
container.innerHTML = ''
var loader_container = document.createElement('div')
loader_container.setAttribute('class', 'loader_container')
var loader = document.createElement('div')
loader.setAttribute('class', 'loader')
loader_container.append(loader)
container.append(loader_container)
}
// create_chat() creates the chat container and stuff
create_chat(){
// Again! You need to have (parent = this)
var parent = this;
// GET THAT MEMECHAT HEADER OUTTA HERE
var title_container = document.getElementById('title_container')
var title = document.getElementById('title')
title_container.classList.add('chat_title_container')
// Make the title smaller by making it 'chat_title'
title.classList.add('chat_title')
var chat_container = document.createElement('div')
chat_container.setAttribute('id', 'chat_container')
var chat_inner_container = document.createElement('div')
chat_inner_container.setAttribute('id', 'chat_inner_container')
var chat_content_container = document.createElement('div')
chat_content_container.setAttribute('id', 'chat_content_container')
var chat_input_container = document.createElement('div')
chat_input_container.setAttribute('id', 'chat_input_container')
var chat_input_send = document.createElement('button')
chat_input_send.setAttribute('id', 'chat_input_send')
chat_input_send.setAttribute('disabled', true)
chat_input_send.innerHTML = ``
var chat_input = document.createElement('input')
chat_input.setAttribute('id', 'chat_input')
// Only a max message length of 1000
chat_input.setAttribute('maxlength', 1000)
// Get the name of the user
chat_input.placeholder = `${parent.get_name()}. Say something...`
chat_input.onkeyup = function(){
if(chat_input.value.length > 0){
chat_input_send.removeAttribute('disabled')
chat_input_send.classList.add('enabled')
chat_input_send.onclick = function(){
chat_input_send.setAttribute('disabled', true)
chat_input_send.classList.remove('enabled')
if(chat_input.value.length <= 0){
return
}
// Enable the loading circle in the 'chat_content_container'
parent.create_load('chat_content_container')
// Send the message. Pass in the chat_input.value
parent.send_message(chat_input.value)
// Clear the chat input box
chat_input.value = ''
// Focus on the input just after
chat_input.focus()
}
}else{
chat_input_send.classList.remove('enabled')
}
}
var chat_logout_container = document.createElement('div')
chat_logout_container.setAttribute('id', 'chat_logout_container')
var chat_logout = document.createElement('button')
chat_logout.setAttribute('id', 'chat_logout')
chat_logout.textContent = `${parent.get_name()} • logout`
// "Logout" is really just deleting the name from the localStorage
chat_logout.onclick = function(){
localStorage.clear()
// Go back to home page
parent.home()
}
chat_logout_container.append(chat_logout)
chat_input_container.append(chat_input, chat_input_send)
chat_inner_container.append(chat_content_container, chat_input_container, chat_logout_container)
chat_container.append(chat_inner_container)
document.body.append(chat_container)
// After creating the chat. We immediatly create a loading circle in the 'chat_content_container'
parent.create_load('chat_content_container')
// then we "refresh" and get the chat data from Firebase
parent.refresh_chat()
}
// Save name. It literally saves the name to localStorage
save_name(name){
// Save name to localStorage
localStorage.setItem('name', name)
}
// Sends message/saves the message to firebase database
send_message(message){
var parent = this
// if the local storage name is null and there is no message
// then return/don't send the message. The user is somehow hacking
// to send messages. Or they just deleted the
// localstorage themselves. But hacking sounds cooler!!
if(parent.get_name() == null && message == null){
return
}
// Get the firebase database value
db.ref('chats/').once('value', function(message_object) {
// This index is mortant. It will help organize the chat in order
var index = parseFloat(message_object.numChildren()) + 1
db.ref('chats/' + `message_${index}`).set({
name: parent.get_name(),
message: message,
index: index
})
.then(function(){
// After we send the chat refresh to get the new messages
parent.refresh_chat()
})
})
}
// Get name. Gets the username from localStorage
get_name(){
// Get the name from localstorage
if(localStorage.getItem('name') != null){
return localStorage.getItem('name')
}else{
this.home()
return null
}
}
// Refresh chat gets the message/chat data from firebase
refresh_chat(){
var chat_content_container = document.getElementById('chat_content_container')
// Get the chats from firebase
db.ref('chats/').on('value', function(messages_object) {
// When we get the data clear chat_content_container
chat_content_container.innerHTML = ''
// if there are no messages in the chat. Retrun . Don't load anything
if(messages_object.numChildren() == 0){
return
}
// OK! SO IF YOU'RE A ROOKIE CODER. THIS IS GOING TO BE
// SUPER EASY-ISH! I THINK. MAYBE NOT. WE'LL SEE!
// convert the message object values to an array.
var messages = Object.values(messages_object.val());
var guide = [] // this will be our guide to organizing the messages
var unordered = [] // unordered messages
var ordered = [] // we're going to order these messages
for (var i, i = 0; i < messages.length; i++) {
// The guide is simply an array from 0 to the messages.length
guide.push(i+1)
// unordered is the [message, index_of_the_message]
unordered.push([messages[i], messages[i].index]);
}
// Now this is straight up from stack overflow 🤣
// Sort the unordered messages by the guide
guide.forEach(function(key) {
var found = false
unordered = unordered.filter(function(item) {
if(!found && item[1] == key) {
// Now push the ordered messages to ordered array
ordered.push(item[0])
found = true
return false
}else{
return true
}
})
})
// Now we're done. Simply display the ordered messages
ordered.forEach(function(data) {
var name = data.name
var message = data.message
var message_container = document.createElement('div')
message_container.setAttribute('class', 'message_container')
var message_inner_container = document.createElement('div')
message_inner_container.setAttribute('class', 'message_inner_container')
var message_user_container = document.createElement('div')
message_user_container.setAttribute('class', 'message_user_container')
var message_user = document.createElement('p')
message_user.setAttribute('class', 'message_user')
message_user.textContent = `${name}`
var message_content_container = document.createElement('div')
message_content_container.setAttribute('class', 'message_content_container')
var message_content = document.createElement('p')
message_content.setAttribute('class', 'message_content')
message_content.textContent = `${message}`
message_user_container.append(message_user)
message_content_container.append(message_content)
message_inner_container.append(message_user_container, message_content_container)
message_container.append(message_inner_container)
chat_content_container.append(message_container)
});
// Go to the recent message at the bottom of the container
chat_content_container.scrollTop = chat_content_container.scrollHeight;
})
}
}
var app = new CAMPUS_CHAT()
// If we have a name stored in localStorage.
// Then use that name. Otherwise , if not.
// Go to home.
if(app.get_name() != null){
app.chat()
}
}