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>
|
</div>
|
||||||
|
|
||||||
<script>
|
<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 backLink = document.querySelector<HTMLButtonElement>("#app-back");
|
||||||
const submitBtn = document.querySelector<HTMLButtonElement>("#submit");
|
const submitBtn = document.querySelector<HTMLButtonElement>("#submit");
|
||||||
const urlInput = document.querySelector<HTMLInputElement>("#app-url");
|
const urlInput = document.querySelector<HTMLInputElement>("#app-url");
|
||||||
const settings = document.querySelector<HTMLDivElement>("#app-settings");
|
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
|
// if js is enabled, show the back and settings button
|
||||||
backLink?.setAttribute("style", "display: block");
|
backLink?.setAttribute("style", "display: block");
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
import Serialize from '@ayco/astro-resume';
|
import Serialize from '@ayco/astro-resume';
|
||||||
export interface Props {
|
export interface Props {
|
||||||
routerOutlet: string,
|
|
||||||
skipSave?: boolean
|
skipSave?: boolean
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
@ -14,7 +13,8 @@ export interface Props {
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {deserialize} from '@ayco/astro-resume';
|
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'
|
import { getPostCard, renderPost } from '../utils/library'
|
||||||
const cache = await caches.open('cozy-reader');
|
const cache = await caches.open('cozy-reader');
|
||||||
let url= new URL(window.location.href);
|
let url= new URL(window.location.href);
|
||||||
|
@ -24,7 +24,8 @@ export interface Props {
|
||||||
url = new URL(`${url.origin}/?url=${urlParam}`);
|
url = new URL(`${url.origin}/?url=${urlParam}`);
|
||||||
}
|
}
|
||||||
const response = await cache.match(url);
|
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)
|
const includesAppURL = urlParam?.includes(window.location.origin)
|
||||||
|
|
||||||
if (!response && !skipSave && !includesAppURL) {
|
if (!response && !skipSave && !includesAppURL) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
|
import Serialize from "@ayco/astro-resume";
|
||||||
import { ArticleData, extract } from "@extractus/article-extractor";
|
import { ArticleData, extract } from "@extractus/article-extractor";
|
||||||
import AddressBar from "../components/AddressBar.astro";
|
import AddressBar from "../components/AddressBar.astro";
|
||||||
import Post from "../components/Post.astro";
|
import Post from "../components/Post.astro";
|
||||||
|
@ -6,6 +7,11 @@ import Layout from "../layouts/Layout.astro";
|
||||||
import Library from "../components/Library.astro";
|
import Library from "../components/Library.astro";
|
||||||
import Footer from "../components/Footer.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 url = Astro.url.searchParams.get('url');
|
||||||
let article: ArticleData | null = {url: '/'};
|
let article: ArticleData | null = {url: '/'};
|
||||||
|
|
||||||
|
@ -20,13 +26,14 @@ if (url)
|
||||||
article = null;
|
article = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const routerOutletID = "router-outlet";
|
|
||||||
---
|
---
|
||||||
<Layout article={article}>
|
<Layout article={article}>
|
||||||
<AddressBar url={url} />
|
<AddressBar url={url} />
|
||||||
<div slot="post" id={routerOutletID}>
|
<div slot="post" id={appConfig.routerOutlet}>
|
||||||
<Post article={article} />
|
<Post article={article} />
|
||||||
</div>
|
</div>
|
||||||
<Library slot="library" skipSave={article === null} routerOutlet={routerOutletID}/>
|
<Library slot="library" skipSave={article === null} />
|
||||||
<Footer slot="footer" />
|
<Footer slot="footer" />
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
|
<Serialize id="app-config" data={appConfig} />
|
|
@ -47,16 +47,24 @@ export function getPostCard(html: HTMLHtmlElement) {
|
||||||
return postCard;
|
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 postDiv = document.querySelector<HTMLDivElement>(`#${postDivSelector}`);
|
||||||
const html = document.createElement('html');
|
let postText = '';
|
||||||
html.innerHTML = responseText;
|
let cozyUrl = '/';
|
||||||
const newPost = html.querySelector('body')?.querySelector('#post');
|
let cozyTitle = 'Cozy';
|
||||||
if (postDiv && newPost?.innerHTML) {
|
if (responseText) {
|
||||||
postDiv.innerHTML = newPost.innerHTML
|
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 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 homeBtn = document.querySelector<HTMLButtonElement>('#app-home');
|
||||||
const backBtn = document.querySelector<HTMLButtonElement>('#app-back');
|
const backBtn = document.querySelector<HTMLButtonElement>('#app-back');
|
||||||
const submitBtn = document.querySelector<HTMLButtonElement>('#app-submit');
|
const submitBtn = document.querySelector<HTMLButtonElement>('#app-submit');
|
||||||
|
@ -65,7 +73,7 @@ export function renderPost(responseText, url, postDivSelector: string, preventPu
|
||||||
backBtn?.removeAttribute('disabled');
|
backBtn?.removeAttribute('disabled');
|
||||||
submitBtn?.removeAttribute('disabled');
|
submitBtn?.removeAttribute('disabled');
|
||||||
homeBtn?.removeAttribute('disabled');
|
homeBtn?.removeAttribute('disabled');
|
||||||
document.title = `${getCozyTitle(html)} | Cozy`;
|
document.title = cozyTitle;
|
||||||
} else {
|
} else {
|
||||||
appUrl.value = '';
|
appUrl.value = '';
|
||||||
backBtn?.setAttribute('disabled', 'true');
|
backBtn?.setAttribute('disabled', 'true');
|
||||||
|
|
Loading…
Reference in a new issue