feat: progressively enhanced home link

- global app config via serializer/deserializer
- home link becomes router link if js enabled
This commit is contained in:
Ayo 2023-08-15 23:07:19 +02:00
parent 03543a30d3
commit cc36a859d3
4 changed files with 40 additions and 14 deletions

View file

@ -56,10 +56,20 @@ const { url } = Astro.props;
</div>
<script>
import { deserialize } from "@ayco/astro-resume";
import type { AppConfig } from "../pages/index.astro";
import { renderPost } from "../utils/library";
const backLink = document.querySelector<HTMLButtonElement>("#app-back");
const submitBtn = document.querySelector<HTMLButtonElement>("#submit");
const urlInput = document.querySelector<HTMLInputElement>("#app-url");
const settings = document.querySelector<HTMLDivElement>("#app-settings");
const homeLink = document.querySelector<HTMLAnchorElement>("#app-home");
const { routerOutlet } = deserialize<AppConfig>('app-config');
homeLink?.addEventListener('click', (e) => {
e.preventDefault();
renderPost(null, '/', routerOutlet)
})
// if js is enabled, show the back and settings button
backLink?.setAttribute("style", "display: block");

View file

@ -1,7 +1,6 @@
---
import Serialize from '@ayco/astro-resume';
export interface Props {
routerOutlet: string,
skipSave?: boolean
}
---
@ -14,7 +13,8 @@ export interface Props {
<script>
import {deserialize} from '@ayco/astro-resume';
import {Props} from './Library.astro';
import type { Props } from './Library.astro';
import type { AppConfig } from '../pages/index.astro';
import { getPostCard, renderPost } from '../utils/library'
const cache = await caches.open('cozy-reader');
let url= new URL(window.location.href);
@ -24,7 +24,8 @@ export interface Props {
url = new URL(`${url.origin}/?url=${urlParam}`);
}
const response = await cache.match(url);
const {routerOutlet, skipSave} = deserialize<Props>('preferences');
const { skipSave } = deserialize<Props>('preferences');
const { routerOutlet } = deserialize<AppConfig>('app-config');
const includesAppURL = urlParam?.includes(window.location.origin)
if (!response && !skipSave && !includesAppURL) {

View file

@ -1,4 +1,5 @@
---
import Serialize from "@ayco/astro-resume";
import { ArticleData, extract } from "@extractus/article-extractor";
import AddressBar from "../components/AddressBar.astro";
import Post from "../components/Post.astro";
@ -6,6 +7,11 @@ import Layout from "../layouts/Layout.astro";
import Library from "../components/Library.astro";
import Footer from "../components/Footer.astro";
const appConfig = {
routerOutlet: 'router-outlet',
};
export type AppConfig = typeof appConfig;
let url = Astro.url.searchParams.get('url');
let article: ArticleData | null = {url: '/'};
@ -20,13 +26,14 @@ if (url)
article = null;
}
const routerOutletID = "router-outlet";
---
<Layout article={article}>
<AddressBar url={url} />
<div slot="post" id={routerOutletID}>
<div slot="post" id={appConfig.routerOutlet}>
<Post article={article} />
</div>
<Library slot="library" skipSave={article === null} routerOutlet={routerOutletID}/>
<Library slot="library" skipSave={article === null} />
<Footer slot="footer" />
</Layout>
<Serialize id="app-config" data={appConfig} />

View file

@ -47,16 +47,24 @@ export function getPostCard(html: HTMLHtmlElement) {
return postCard;
}
export function renderPost(responseText, url, postDivSelector: string, preventPushState = false) {
export function renderPost(responseText: string | null, url, postDivSelector: string, preventPushState = false) {
const postDiv = document.querySelector<HTMLDivElement>(`#${postDivSelector}`);
const html = document.createElement('html');
html.innerHTML = responseText;
const newPost = html.querySelector('body')?.querySelector('#post');
if (postDiv && newPost?.innerHTML) {
postDiv.innerHTML = newPost.innerHTML
let postText = '';
let cozyUrl = '/';
let cozyTitle = 'Cozy';
if (responseText) {
const html = document.createElement('html');
html.innerHTML = responseText;
const newPost = html.querySelector('body')?.querySelector('#post');
postText = newPost?.innerHTML || '';
cozyUrl = html.querySelector('meta[property="cozy:url"]')?.getAttribute('content') ?? '/';
cozyTitle = `${getCozyTitle(html)} | Cozy`;
}
if (postDiv) {
postDiv.innerHTML = postText;
const appUrl = document.getElementById('app-url') as HTMLInputElement;
const cozyUrl = html.querySelector('meta[property="cozy:url"]')?.getAttribute('content');
const homeBtn = document.querySelector<HTMLButtonElement>('#app-home');
const backBtn = document.querySelector<HTMLButtonElement>('#app-back');
const submitBtn = document.querySelector<HTMLButtonElement>('#app-submit');
@ -65,7 +73,7 @@ export function renderPost(responseText, url, postDivSelector: string, preventPu
backBtn?.removeAttribute('disabled');
submitBtn?.removeAttribute('disabled');
homeBtn?.removeAttribute('disabled');
document.title = `${getCozyTitle(html)} | Cozy`;
document.title = cozyTitle;
} else {
appUrl.value = '';
backBtn?.setAttribute('disabled', 'true');