initial commit

This commit is contained in:
Geoff Doty 2020-02-04 10:56:40 -05:00
commit 062fc37c80
4 changed files with 335 additions and 0 deletions

0
README.md Normal file
View File

157
bootleg.css Normal file
View File

@ -0,0 +1,157 @@
:root {
--clarity: 1;
--theme: #c3202f;
--white: #FFF;
--black: #000;
--tint: #ACACAC;
--background: #EEE;
--surface: #FFF;
--primary: var(--theme);
}
/* CSS Reset */
html {
box-sizing: border-box;
font-family: "Roboto", georgia, serif;
font-size: 16px;
line-height: 1.4em;
color: #474747;
-webkit-font-smoothing: antialiased;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
html,
body {
height: 100%;
}
body,
html,
span,
div {
margin: 0;
padding: 0;
font-weight: normal;
}
ol,
ul {
list-style: none;
}
img,
embed,
iframe,
object,
audio,
video {
height: auto;
max-width: 100%;
border: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
input[type="checkbox"],
input[type="radio"] {
margin-right: .5em;
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* Nav */
.nav {
background: var(--theme);
color: var(--white);
}
.nav a {color: var(--white)}
/* Layout */
.row {
display: flex;
direction: row;
align-items: center;
align-content: space-between;
justify-content: space-between;
}
.col, .col-1, .col-2, .col-3, .col-4, .col-5 {
display: flex;
direction: column;
}
.col-1 {flex: 1}
.col-2 {flex: 2}
.col-3 {flex: 3}
.col-4 {flex: 4}
.col-5 {flex: 5}
.content {
padding: .5em;
}
.box {
padding: .5em;
margin: .5em;
border: 1px solid var(--primary);
}
.title {
font-size: 1.1rem;
font-weight: bold;
margin: 0;
}
.weak {color: #727272}
h1 {font-size: 2.4em}
h2 {font-size: 1.8em}
h3 {font-size: 1.6em}
h4 {font-size: 1.4em}
h5 {font-size: 1.2em}
h6 {font-size: 1em}
/* utility */
.capitalized {text-transform: capitalize}
.uppercased {text-transform: uppercase}
.lowercased {text-transform: lowercase}
.inline {display: inline;}
.shadowed {
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
.surfaced {
background-color: var(--surface);
margin-bottom: .5rem;
border-bottom: 1px solid var(--tint);
}
.right {float: right}
.left {float: left}
.centered {text-align: center;}

136
components/news-summary.js Normal file
View File

@ -0,0 +1,136 @@
const html = (content) => {
let template = document.createElement("template");
template.innerHTML = content;
return template.content
};
class NewsSummary extends HTMLElement {
constructor() {
super();
this.cache = true;
this.state = {};
}
async read(part, id) {
let hn = "https://hacker-news.firebaseio.com/v0";
switch(part) {
case "list":
return await fetch(`${hn}/topstories.json`).then(r => r.json()).then(r => r);
case "details":
return await fetch(`${hn}/item/${id}.json`).then(r => r.json()).then(r => r);
default:
return {}
}
}
/**
* Returns a value or false
*
* useful for truthy expressions where objects or arrays are defined, but empty
*
* @param {Any} val
*/
_exists(val) {
// console.log('typeof', val, typeof val);
if(typeof val !== 'object' || val === null) {
return !!val ? val : false;
} else {
if(typeof val === "object") {
if(val.length !== 'undefined') {
return !!val.length ? val : false;
} else {
return (Object.getOwnPropertyNames(val).length > 0) ? val : false;
}
}
}
}
/**
* Local Storage Helper
*/
_store() {
return {
get: (key) => {
return this._exists(JSON.parse(window.localStorage.getItem(key)));
},
set: (key, val) => {
return this._exists(window.localStorage.setItem(key, JSON.stringify(val)));
}
}
}
async connectedCallback() {
console.log('connected');
// get identifiers list
if(this.cache) {
console.log('cache enabled...');
if(this._store().get("list")) {
console.log('found in cache...');
this.state.list = this._store().get("list");
} else {
console.log('building cache...');
let list = await this.read("list");
this.state.list = list;
this._store().set("list", list);
}
}
// get details from idenifiers list
if (this.cache) {
console.log('cache enabled...');
if (this._store().get("details")) {
console.log('found in cache...');
this.state.details = this._store().get("details");
} else {
console.log('building cache...');
this.state.details = [];
for (let i =0; i < 15; i++) {
let item = await this.read("details", this.state.list[i]);
this.state.details.push(item);
}
this._store().set("details", this.state.details);
}
console.log('...done');
}
this._render();
}
// _template() {
// return html`
// <section class="surfaced">
// <h6 class="inline capitalized title"><a href="${item.url}">${item.title}</a></h6>
// <div class="weak is-sm">[ hype: ${item.score} | topic: <a href="">${item.type}</a> | source: <a href="">${item.by}</a> | <a href="">${item.kids.length} comments</a> ]</div>
// </section>
// `;
// }
_render() {
this.innerHTML = `
${this.state.details.map(item => `
<div class="surfaced" style="margin-bottom: 8px;">
<h6 class="inline capitalized title"><a href="${item.url}">${item.title}</a></h6>
<div>
<small class="weak">[ hype: ${item.score} | topic: <a href="">${item.type}</a> | source: <a href="">${item.by}</a> | <a href="">${(item.kids || []).length} comments</a> ]</small>
</div>
</div>
`).join('')}
`;
}
}
customElements.define('news-summary', NewsSummary);

42
index.html Normal file
View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Bootleg</title>
<link href="https://fonts.googleapis.com/css?family=Roboto&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.css">
<link rel="stylesheet" href="bootleg.css">
</head>
<body>
<div class="container">
<header>
<nav class="nav content row">
<div>
<a class="content" href=""><strong>[H]YPE</strong></a>
<a href="">new</a> |
<a href="">past</a> |
<a href="">comments</a> |
<a href="">ask</a> |
<a href="">show</a> |
<a href="">jobs</a> |
<button>
<i class="fa fa-check"></i>
submit
</button>
</div>
<a class="content right" href="">login</a>
</nav>
</header>
<div class="content">
<news-summary item="{}"></news-summary>
</div>
<footer>
</footer>
<script src="components/news-summary.js"></script>
</div>
</body>
</html>