194 lines
No EOL
5.6 KiB
Text
194 lines
No EOL
5.6 KiB
Text
---
|
|
export interface Props {
|
|
postDivSelector: string,
|
|
skipSave?: boolean
|
|
}
|
|
|
|
const {postDivSelector, skipSave = false} = Astro.props;
|
|
---
|
|
<div id="library">
|
|
<h2></h2>
|
|
<ul id="post-list"></ul>
|
|
</div>
|
|
|
|
<input value={postDivSelector} name="postDivSelector" id="postDivSelector" hidden />
|
|
<input type="checkbox" id="skipSave" name="skipSave" checked={skipSave} hidden />
|
|
|
|
<script>
|
|
const cache = await caches.open('cozy-reader');
|
|
const url = new URL(window.location.href);
|
|
const response = await cache.match(url)
|
|
const postDivSelector = document.getElementById('postDivSelector') as HTMLInputElement;
|
|
const skipSave = document.getElementById('skipSave') as HTMLInputElement;
|
|
const postDiv = document.querySelector(postDivSelector?.value);
|
|
|
|
if (!response && !skipSave?.checked) {
|
|
console.log('skip?', skipSave?.checked)
|
|
await cache.add(url);
|
|
}
|
|
|
|
const cachedResponses = await cache.keys();
|
|
const list = document.querySelector('#post-list');
|
|
|
|
if(cachedResponses?.length) {
|
|
const headingEl = document.querySelector('#library h2');
|
|
if(headingEl)
|
|
headingEl.innerHTML = 'Previously Viewed';
|
|
|
|
cachedResponses
|
|
.filter(request => {
|
|
const urlObj = new URL(request.url);
|
|
return urlObj.search !== '';
|
|
})
|
|
.reverse()
|
|
.forEach(async (request) => {
|
|
const {url} = request;
|
|
const link = document.createElement('a');
|
|
|
|
let responseText;
|
|
|
|
const fullResponse = await cache.match(url)
|
|
fullResponse?.text().then(data => {
|
|
responseText = data;
|
|
const html = document.createElement('html');
|
|
html.innerHTML = responseText;
|
|
const title = html.querySelector('title');
|
|
const postCard = getPostCard(html);
|
|
link.innerHTML = postCard;
|
|
});
|
|
|
|
link.href = url;
|
|
link.onclick = async (e) => {
|
|
e.preventDefault();
|
|
scroll(0,0);
|
|
const html = document.createElement('html');
|
|
html.innerHTML = responseText;
|
|
const newPost = html.querySelector('body')?.querySelector('#post');
|
|
if (postDiv && newPost?.innerHTML) {
|
|
postDiv.innerHTML = newPost.innerHTML
|
|
}
|
|
}
|
|
const item = document.createElement('li');
|
|
item.appendChild(link);
|
|
list?.appendChild(item);
|
|
});
|
|
}
|
|
|
|
|
|
function getPostCard(html: HTMLHtmlElement) {
|
|
const title
|
|
= html.querySelector('meta[property="cozy:title"]')?.getAttribute('content')
|
|
||html.querySelector('title')?.innerHTML?.replace('Cozy 🧸 | ', '');
|
|
|
|
const description = html.querySelector('meta[property="cozy:description"]')?.getAttribute('content');
|
|
const image = html.querySelector('meta[property="cozy:image"]')?.getAttribute('content');
|
|
const url = html.querySelector('meta[property="cozy:url"]')?.getAttribute('content');
|
|
const source = html.querySelector('meta[property="cozy:source"]')?.getAttribute('content');
|
|
const published = html.querySelector('meta[property="cozy:published"]')?.getAttribute('content');
|
|
|
|
const postCard = `
|
|
<div class="post-card">
|
|
<div class="post-card__image">
|
|
${
|
|
image ? `
|
|
<img src="${image}" alt="${title} | ${description}" />
|
|
`
|
|
: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/><path fill="currentColor" d="M14 17H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z"/></svg>'
|
|
}
|
|
</div>
|
|
<div class="post-card__content">
|
|
<div class="post-card__meta">
|
|
${
|
|
source ? `
|
|
<p class="post-card__source">${source}</p>
|
|
`
|
|
: ''
|
|
}
|
|
${
|
|
published ? `
|
|
<p class="post-card__published">${new Date(published).toLocaleDateString()}</p>
|
|
`
|
|
: ''
|
|
}
|
|
|
|
</div>
|
|
<h3 class="post-card__title">${title}</h3>
|
|
${
|
|
description ? `
|
|
<p class="post-card__description">${description}</p>`
|
|
: ''
|
|
}
|
|
</div>
|
|
</div>
|
|
`;
|
|
return postCard;
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
#library {
|
|
:global(h2) {
|
|
text-align: center;
|
|
}
|
|
}
|
|
#post-list {
|
|
:global(li) {
|
|
list-style: none;
|
|
display: block;
|
|
float: left;
|
|
width: calc(100% + 40px);
|
|
margin-left: -40px;
|
|
padding: 1rem;
|
|
border-bottom: 1px solid #eee;
|
|
|
|
:global(a) {
|
|
text-decoration: none;
|
|
color: #000;
|
|
|
|
:global(h3) {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
:global(.post-card) {
|
|
:global(.post-card__image) {
|
|
float: left;
|
|
margin-right: 0.5rem;
|
|
margin: 0.5rem 1rem 0 0;
|
|
|
|
:global(img, svg) {
|
|
width: 60px;
|
|
height: 60px;
|
|
object-fit: cover;
|
|
border-radius: 50%;
|
|
border: 3px solid #eee;
|
|
}
|
|
:global(svg) {
|
|
color: #888;
|
|
padding: 0.5rem;
|
|
}
|
|
}
|
|
}
|
|
:global(.post-card__title, .post-card__description) {
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 2;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
:global(.post-card__meta) {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
font-size: smaller;
|
|
color: #555;
|
|
|
|
* {
|
|
flex: 1;
|
|
}
|
|
|
|
:global(.post-card__source) {
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style> |