hype/components/news-summary.js

137 lines
4.1 KiB
JavaScript

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