Skip to content

Instantly share code, notes, and snippets.

@egillespie
Last active March 25, 2021 23:46
Show Gist options
  • Save egillespie/942cc3aed19977590b431c10333736c2 to your computer and use it in GitHub Desktop.
Save egillespie/942cc3aed19977590b431c10333736c2 to your computer and use it in GitHub Desktop.
Woofer - Anonymous messaging
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>🐾 Woofer</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main class="container">
<header class="main row text-center">
<h1>Woofer 🐾</h1>
<div class="input-group pull-right">
<input id="woof-text" type="text" class="form-control" placeholder="Type something here...">
<span class="input-group-btn">
<button id="woof-button" class="btn btn-primary" type="button">Woof!</button>
</span>
</div>
</header>
<article class="page-header row">
<h2>Recent woofs</h2>
<div id="woofs"></div>
</article>
</main>
<script src="https://momentjs.com/downloads/moment.min.js"></script>
<script src="woofer-ui.js"></script>
<script src="woofer-db.js"></script>
<template id="woof-template">
<div class="row">
<span class="pull-right">
<button type="button" class="close btn-delete" aria-label="Delete">
<small><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></small>
</button>
<button type="button" class="close btn-edit" aria-label="Edit">
<small><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span></small>
</button>
</span>
<span class="woof">
<div class="text show"></div>
<div class="hidden">
<input type="text" class="form-control">
<small>Press Enter to save or Escape to cancel.</small>
</div>
<span class="created-at"></span>
</span>
</div>
</template>
</body>
</html>
{
"woofs": {
"b09d3e0974d05": {
"created_at": 1491613778000,
"text": "That homework looks hard. Want me to eat it?"
}
}
}
main.container > .main {
background-color: #effbfb;
}
.row {
padding: 10px;
}
.row:nth-child(odd) {
background-color: #f7f7f9;
}
.row .woof {
display: inline-block;
}
.woof .text {
margin: 0;
}
.woof .created-at {
font-style: italic;
font-size: smaller;
color: darkgray;
}
button {
outline: none;
}
button.close {
margin-left: 10px;
}
button.btn-edit,
button.btn-edit:focus {
color: #4cae4c;
}
button.btn-edit:active,
button.btn-edit:hover {
color: #398439;
}
button.btn-delete,
button.btn-delete:focus {
color: #d43f3a;
}
button.btn-delete:active,
button.btn-delete:hover {
color: #ac2925;
}
/* global firebase addWoofRow updateWoofRow deleteWoofRow */
// NOTE:
// Ignore the comments with "eslint" -- those comments are telling
// the linter it can safely hide the errors on those lines.
// TODO Sign into Firestore
// CREATE a new woof in the database
function createWoofInDatabase (woof) { // eslint-disable-line no-unused-vars
// TODO create a new document in the collection
}
// READ from Firestore when woofs are added, modified, or removed
// Call one of the following functions for each changed document:
// 1. addWoofRow(<woofKey>, <woof>)
// 2. updateWoofRow(<woofKey>, <woof>)
// 3. deleteWoofRow(<woofKey>)
// Make sure to pass the correct parameters!
function readWoofsInDatabase () {
// TODO read added, modified, and removed documents
}
// UPDATE the woof in the database
function updateWoofInDatabase (woofKey, woofText) { // eslint-disable-line no-unused-vars
// TODO update the document in the collection
}
// DELETE the woof from the database
function deleteWoofFromDatabase (woofKey) { // eslint-disable-line no-unused-vars
// TODO delete the document from the collection
}
// Load all of the data
readWoofsInDatabase()
//
//
// !!!!!!!! WARNING !!!!!!!!
//
// This file has all the functions you need to update the
// page, but you don't need to make any changes to this
// file to complete the project. Do so at your own risk!
//
//
const woofText = document.getElementById('woof-text')
const woofs = document.getElementById('woofs')
const woofCreate = document.getElementById('woof-button')
// Adds a new row to the list of woofs
function addWoofRow (woofKey, woof) { // eslint-disable-line no-unused-vars
const template = document.getElementById('woof-template')
const clone = document.importNode(template.content, true)
clone.querySelector('.row').id = woofKey
clone.querySelector('.created-at').textContent = moment(woof.created_at).calendar() // eslint-disable-line no-undef
clone.querySelector('.text').textContent = woof.text
clone.querySelector('.btn-edit').addEventListener('click', showWoofTextbox)
clone.querySelector('.btn-delete').addEventListener('click', deleteWoof)
clone.querySelector('input').addEventListener('keyup', editWoof)
woofs.insertBefore(clone, woofs.firstChild)
woofText.value = ''
}
// Get woof text from input and pass it to addWoof
function createWoof () {
const text = woofText.value || ''
if (!text.trim().length) return
createWoofInDatabase({ // eslint-disable-line no-undef
created_at: new Date().getTime(),
text: text
})
}
// Make the textbox to edit a woof appear
function showWoofTextbox () {
const row = this.parentElement.parentElement
const textbox = row.querySelector('input')
const form = textbox.parentElement
const text = row.querySelector('.text')
textbox.value = row.querySelector('.text').textContent
text.className = text.className.replace('show', 'hidden')
form.className = form.className.replace('hidden', 'show')
textbox.focus()
textbox.select()
}
// If Enter was pressed, update woof in database,
// If Escape was pressed, hide the textbox
function editWoof (event) {
const row = this.parentElement.parentElement.parentElement
const textbox = row.querySelector('input')
const form = textbox.parentElement
const text = row.querySelector('.text')
if (event.key === 'Enter') {
// Enter key pressed
updateWoofInDatabase(row.id, textbox.value) // eslint-disable-line no-undef
} else if (event.key === 'Escape') {
// Escape key pressed
form.className = form.className.replace('show', 'hidden')
text.className = text.className.replace('hidden', 'show')
}
}
// Update the woof text in a row on the page
function updateWoofRow (woofKey, woof) { // eslint-disable-line no-unused-vars
const row = document.getElementById(woofKey)
const form = row.querySelector('input').parentElement
const text = row.querySelector('.text')
form.className = form.className.replace('show', 'hidden')
row.querySelector('.text').textContent = woof.text
text.className = text.className.replace('hidden', 'show')
}
// Remove a woof row from the page
function deleteWoofRow (woofKey) { // eslint-disable-line no-unused-vars
const row = document.getElementById(woofKey)
row.parentElement.removeChild(row)
}
// Remove the clicked woof from the database
function deleteWoof () {
const row = this.parentElement.parentElement
deleteWoofFromDatabase(row.id) // eslint-disable-line no-undef
}
// Event listeners to add a new woof
woofCreate.addEventListener('click', createWoof)
woofText.addEventListener('keypress', function (event) {
if (event.key === 'Enter') createWoof()
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment