Adding articles preview to the main homepage, changing the API for articles to return with cap on max pages and max articles env variables, and formatting code text.

This commit is contained in:
Bradley Shellnut 2023-02-15 16:12:30 -08:00
parent b92de5c112
commit a309229c51
8 changed files with 142 additions and 24 deletions

View file

@ -15,6 +15,7 @@
},
"devDependencies": {
"@iconify-icons/material-symbols": "^1.2.27",
"@iconify-icons/mdi": "^1.2.41",
"@iconify-icons/radix-icons": "^1.2.8",
"@iconify-icons/simple-icons": "^1.2.42",
"@leveluptuts/svelte-side-menu": "^1.0.5",

View file

@ -2,6 +2,7 @@ lockfileVersion: 5.4
specifiers:
'@iconify-icons/material-symbols': ^1.2.27
'@iconify-icons/mdi': ^1.2.41
'@iconify-icons/radix-icons': ^1.2.8
'@iconify-icons/simple-icons': ^1.2.42
'@leveluptuts/svelte-side-menu': ^1.0.5
@ -42,6 +43,7 @@ specifiers:
devDependencies:
'@iconify-icons/material-symbols': 1.2.27
'@iconify-icons/mdi': 1.2.41
'@iconify-icons/radix-icons': 1.2.8
'@iconify-icons/simple-icons': 1.2.42
'@leveluptuts/svelte-side-menu': 1.0.5
@ -565,6 +567,12 @@ packages:
'@iconify/types': 2.0.0
dev: true
/@iconify-icons/mdi/1.2.41:
resolution: {integrity: sha512-duqTSmY0H+e/LdSZD5B8PxnJfdfh6qdLVnrI6klHGSSykz23d1KdvoPpfFpgF8mWWDm4UlHIO+rrvsqMLEb3NQ==}
dependencies:
'@iconify/types': 2.0.0
dev: true
/@iconify-icons/radix-icons/1.2.8:
resolution: {integrity: sha512-bZqRIbeqe6yNSLPgcQOyOl86C2P/apaY9Dq/BddWxitN8olbTp2MLuDJenNF+wxbQGgKkQFfm3vb6Z+4Nbhk+g==}
dependencies:

View file

@ -0,0 +1,105 @@
<script lang="ts">
import OpenInNew from '@iconify-icons/mdi/open-in-new';
import type { Article } from "$root/lib/types/article";
export let articles: Article[];
export let totalArticles: number;
export let compact: boolean = false;
</script>
<div>
<h2>Favorite Articles</h2>
<div style="display: grid;">
{#each articles as article}
<article class="articleStyles card">
<section>
<h3>
<a
target="_blank"
aria-label={`Link to ${article.title}`}
href={article.url.toString()}
rel="noreferrer"
>
{#if compact}
{article.title.substring(0, 50).trim()}&#8230;
{:else}
{article.title}
{/if}
<iconify-icon icon={OpenInNew} width="24" height="24" role="img" title="Open Article Externally" />
</a>{' '}
</h3>
</section>
<section>
<p>Reading time: {article.reading_time} minutes</p>
<div class="tagsStyles">
<p>Tags:</p>
{#each article.tags as tag}
<p>{tag}</p>
{/each}
</div>
</section>
</article>
{/each}
</div>
<div class="moreArticlesStyles">
<a href="/articles">{`${totalArticles} more articles`}</a>
<a href="/articles" aria-label={`${totalArticles} more articles`}>
<iconify-icon icon="material-symbols:arrow-right-alt-rounded"></iconify-icon>
</a>
</div>
</div>
<style lang="postcss">
.articleStyles {
display: grid;
grid-template-rows: repeat(1fr, 3);
gap: 0.5rem;
margin: 1.5rem 0;
a {
overflow-wrap: anywhere;
}
p {
margin: 0.4rem 0.25rem;
}
}
.tagsStyles {
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: left;
align-items: center;
p + p {
background-color: var(--linkHover);
color: var(--buttonTextColor);
padding: 0.25rem 0.5rem;
margin: 0.5rem;
border-radius: 2px;
font-size: 1.2rem;
}
}
.moreArticlesStyles {
margin: 1.7rem;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
gap: 1rem;
a {
font-size: 2rem;
svg {
text-decoration: none;
}
}
@media (max-width: 1000px) {
font-size: 1.5rem;
}
}
</style>

View file

@ -1,12 +1,17 @@
import type { PageServerLoad } from './lib/$types';
import { PAGE_SIZE } from '$env/static/private';
import { fetchBandcampAlbums } from '$root/lib/util/fetchBandcampAlbums';
export const load: PageServerLoad = async ({ setHeaders }) => {
const albums = await fetchBandcampAlbums();
export const load: PageServerLoad = async ({ fetch, setHeaders }) => {
const albums = async () => await fetchBandcampAlbums();
const articles = async () => await fetch(`/api/articles?page=1&limit=3`);
// const art = articles.
// console.log(`Articles: ${JSON.stringify(await (await articles()).json())}`);
setHeaders({
'cache-control': 'max-age=43200'
});
return {
albums
albums: albums(),
articlesData: (await articles()).json()
};
};

View file

@ -1,12 +1,20 @@
<script lang="ts">
import type { PageData } from './$types';
import Bandcamp from '$lib/components/bandcamp/index.svelte';
import Articles from '$lib/components/articles/index.svelte';
import SEO from '$lib/components/SEO.svelte';
import type { Album } from '$root/lib/types/album';
import type { Album } from '$lib/types/album';
import type { Article } from '$lib/types/article';
import type { ArticlePageLoad } from './articles/[page]/+page.server';
export let data: PageData;
let albums: Album[];
$: ({ albums } = data);
let articlesData: ArticlePageLoad;
let articles: Article[];
let totalArticles: number;
$: ({ albums, articlesData } = data);
$: ({ articles, totalArticles } = articlesData);
$: console.log(`All data: ${JSON.stringify(articlesData)}`);
const userNames = {
github: 'BradNut',
@ -64,7 +72,7 @@
</div>
<div class="social-info">
<Bandcamp {albums} />
<!-- <Articles /> -->
<Articles {articles} {totalArticles} compact={true} />
</div>
</div>

View file

@ -5,7 +5,8 @@ import {
WALLABAG_PASSWORD,
WALLABAG_URL,
WALLABAG_MAX_PAGES,
PAGE_SIZE
PAGE_SIZE,
WALLABAG_MAX_ARTICLES
} from '$env/static/private';
import intersect from 'just-intersect';
import type { Article, WallabagArticle } from '$root/lib/types/article';
@ -41,7 +42,7 @@ export async function fetchArticlesApi(
const pageQuery: PageQuery = {
sort: 'updated',
perPage: +PAGE_SIZE,
perPage: +queryParams?.limit || +PAGE_SIZE,
since: 0,
page: +queryParams?.page || 1,
tags: 'programming',
@ -104,25 +105,12 @@ export async function fetchArticlesApi(
}
});
// if (!entries._links.next) {
// return;
// }
// console.log(`Links next ${JSON.stringify(entries._links.next)}`);
// const response = await fetch(entries._links.next.href, {
// method: 'GET',
// headers: {
// Authorization: `Bearer ${auth.access_token}`
// }
// });
// entries = await response.json();
// } while (entries._links.next);
return {
articles,
currentPage: page,
totalPages: pages <= WALLABAG_MAX_PAGES ? pages : WALLABAG_MAX_PAGES,
totalPages: pages > +WALLABAG_MAX_PAGES ? +WALLABAG_MAX_PAGES : pages,
limit,
totalArticles: total > limit * WALLABAG_MAX_PAGES ? limit * WALLABAG_MAX_PAGES : total,
totalArticles: total > +WALLABAG_MAX_ARTICLES ? +WALLABAG_MAX_ARTICLES : total,
cacheControl
};
}

View file

@ -10,7 +10,8 @@ export const GET: RequestHandler = async ({ url, setHeaders }: RequestEvent) =>
throw new Error('Page does not exist');
}
const response = await fetchArticlesApi('get', `fetchArticles`, {
page
page,
limit: url?.searchParams?.get('limit') || '6'
});
if (response?.articles) {
@ -26,6 +27,7 @@ export const GET: RequestHandler = async ({ url, setHeaders }: RequestEvent) =>
}
}
console.log(`API response ${JSON.stringify(response)}`);
return json(response);
}
} catch (e) {

View file

@ -21,6 +21,7 @@ export const load: PageServerLoad = async ({ fetch, params }) => {
const resp = await fetch(`/api/articles?page=${page}`);
const { articles, currentPage, totalPages, limit, totalArticles }: ArticlePageLoad =
await resp.json();
return {
articles,
currentPage,