feat: progressively enhanced home link
- global app config via serializer/deserializer - home link becomes router link if js enabled
This commit is contained in:
parent
03543a30d3
commit
cc36a859d3
4 changed files with 40 additions and 14 deletions
|
@ -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");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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} />
|
|
@ -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');
|
||||
|
|
Loading…
Reference in a new issue