initial commit
This commit is contained in:
commit
062fc37c80
|
@ -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;}
|
||||
|
||||
|
|
@ -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);
|
|
@ -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>
|
Loading…
Reference in New Issue