feat: make author clickable

This commit is contained in:
2023-08-12 18:32:56 +02:00
parent d2a02fcf34
commit 2b4173d759
27 changed files with 257 additions and 174 deletions

View File

@ -37,6 +37,15 @@ export default function App({ Component }: AppProps) {
--background: rgb(43, 41, 48);
--foreground: rgb(129, 129, 129);
}
.custom-grid {
grid-template-columns: repeat(auto-fit, minmax(37vw, 1fr)) ;
}
@media(min-width: 640px){
.custom-grid {
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) ;
}
}
/* work-sans-regular - latin */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */

View File

@ -9,7 +9,7 @@ import {
import { parseMediaType } from "https://deno.land/std@0.175.0/media_types/parse_media_type.ts";
import * as cache from "@lib/cache/image.ts";
import { SILVERBULLET_SERVER } from "@lib/env.ts";
import { PromiseQueue } from "@lib/promise.ts";
import { ConcurrentPromiseQueue, PromiseQueue } from "@lib/promise.ts";
import { BadRequestError } from "@lib/errors.ts";
import { createLogger } from "@lib/log.ts";
@ -109,7 +109,7 @@ function parseParams(reqUrl: URL) {
};
}
const queue = new PromiseQueue();
const queue = new ConcurrentPromiseQueue(2);
async function processImage(imageUrl: string, params: ImageParams) {
const remoteImage = await getRemoteImage(imageUrl);
@ -165,20 +165,21 @@ const GET = async (
processImage(imageUrl, params)
);
const clonedImage = resizedImage.slice();
setTimeout(() => {
cache.setImage(resizedImage.slice(), {
cache.setImage(clonedImage, {
url: imageUrl,
width: params.width,
height: params.height,
mediaType: mediaType,
});
}, 10);
}, 50);
log.debug("not-cached", { imageUrl });
cache.getThumbhash({ url: imageUrl }).then((hash) => {
cache.getThumbhash({ url: imageUrl }).then(([hash]) => {
if (!hash) {
cache.createThumbhash(resizedImage.slice(), imageUrl).catch((_err) => {
cache.createThumbhash(clonedImage.slice(), imageUrl).catch((_err) => {
//
});
}

View File

@ -8,8 +8,11 @@ import { IconArrowLeft } from "@components/icons.tsx";
import { RedirectSearchHandler } from "@islands/Search.tsx";
import { parseResourceUrl, searchResource } from "@lib/search.ts";
import { SearchResult } from "@lib/types.ts";
import { ResourceCard } from "@components/Card.tsx";
export const handler: Handlers<Article[] | null> = {
export const handler: Handlers<
{ articles: Article[] | null; searchResults?: SearchResult }
> = {
async GET(req, ctx) {
const articles = await getAllArticles();
const searchParams = parseResourceUrl(req.url);
@ -44,16 +47,12 @@ export default function Greet(
<RedirectSearchHandler />
<KMenu type="main" context={{ type: "article" }} />
<Grid>
{articles?.map((doc) => {
return (
<Card
image={doc?.meta?.image || "/placeholder.svg"}
thumbnail={doc?.meta?.thumbnail}
link={`/articles/${doc.id}`}
title={doc.name}
/>
);
})}
{articles?.map((doc) => (
<ResourceCard
sublink="articles"
res={doc}
/>
))}
</Grid>
</MainLayout>
);

View File

@ -15,8 +15,9 @@ export default function Home(props: PageProps) {
<RedirectSearchHandler />
<KMenu type="main" context={false} />
<MainLayout url={props.url}>
<div class="flex flex-wrap items-center gap-4 px-4">
{Object.values(resources).map((m) => {
<h1 class="text-4xl mb-4 mt-3 text-white">Resources</h1>
<div class="flex flex-wrap items-center gap-4">
{Object.values(resources).filter((v) => v.link !== "/").map((m) => {
return (
<Card
title={`${m.name}`}

View File

@ -29,7 +29,13 @@ export default function Greet(
<KMenu type="main" context={movie} />
<RecipeHero
data={movie}
subline={[author, date.toString()]}
subline={[
author && {
title: author,
href: `/movies?q=${encodeURIComponent(author)}`,
},
date.toString(),
]}
editLink={session
? `https://notes.max-richter.dev/Media/movies/${movie.id}`
: ""}

View File

@ -1,7 +1,7 @@
import { Handlers, PageProps } from "$fresh/server.ts";
import { MainLayout } from "@components/layouts/main.tsx";
import { getAllMovies, Movie } from "@lib/resource/movies.ts";
import { MovieCard } from "@components/MovieCard.tsx";
import { ResourceCard } from "@components/Card.tsx";
import { Grid } from "@components/Grid.tsx";
import { IconArrowLeft } from "@components/icons.tsx";
import { KMenu } from "@islands/KMenu.tsx";
@ -9,7 +9,9 @@ import { RedirectSearchHandler } from "@islands/Search.tsx";
import { parseResourceUrl, searchResource } from "@lib/search.ts";
import { SearchResult } from "@lib/types.ts";
export const handler: Handlers<Movie[] | null> = {
export const handler: Handlers<
{ movies: Movie[] | null; searchResults?: SearchResult }
> = {
async GET(req, ctx) {
const movies = await getAllMovies();
const searchParams = parseResourceUrl(req.url);
@ -46,7 +48,7 @@ export default function Greet(
</header>
<Grid>
{movies?.map((doc) => {
return <MovieCard movie={doc} />;
return <ResourceCard res={doc} />;
})}
</Grid>
</MainLayout>

View File

@ -1,5 +1,4 @@
import { Handlers, PageProps } from "$fresh/server.ts";
import { RecipeCard } from "@components/RecipeCard.tsx";
import { MainLayout } from "@components/layouts/main.tsx";
import { getAllRecipes, Recipe } from "@lib/resource/recipes.ts";
import { Grid } from "@components/Grid.tsx";
@ -8,8 +7,11 @@ import { KMenu } from "@islands/KMenu.tsx";
import { RedirectSearchHandler } from "@islands/Search.tsx";
import { parseResourceUrl, searchResource } from "@lib/search.ts";
import { SearchResult } from "@lib/types.ts";
import { ResourceCard } from "@components/Card.tsx";
export const handler: Handlers<Recipe[] | null> = {
export const handler: Handlers<
{ recipes: Recipe[] | null; searchResults?: SearchResult }
> = {
async GET(req, ctx) {
const recipes = await getAllRecipes();
const searchParams = parseResourceUrl(req.url);
@ -45,7 +47,7 @@ export default function Greet(
</header>
<Grid>
{recipes?.map((doc) => {
return <RecipeCard recipe={doc} />;
return <ResourceCard sublink="recipes" res={doc} />;
})}
</Grid>
</MainLayout>

View File

@ -7,7 +7,7 @@ import { getSeries, Series } from "@lib/resource/series.ts";
import { RedirectSearchHandler } from "@islands/Search.tsx";
import { KMenu } from "@islands/KMenu.tsx";
export const handler: Handlers<Series | null> = {
export const handler: Handlers<{ serie: Series; session: unknown }> = {
async GET(_, ctx) {
const serie = await getSeries(ctx.params.name);
return ctx.render({ serie, session: ctx.state.session });

View File

@ -5,11 +5,13 @@ import { IconArrowLeft } from "@components/icons.tsx";
import { getAllSeries, Series } from "@lib/resource/series.ts";
import { RedirectSearchHandler } from "@islands/Search.tsx";
import { KMenu } from "@islands/KMenu.tsx";
import { MovieCard } from "@components/MovieCard.tsx";
import { ResourceCard } from "@components/Card.tsx";
import { parseResourceUrl, searchResource } from "@lib/search.ts";
import { SearchResult } from "@lib/types.ts";
export const handler: Handlers<Series[] | null> = {
export const handler: Handlers<
{ series: Series[] | null; searchResults?: SearchResult }
> = {
async GET(req, ctx) {
const series = await getAllSeries();
const searchParams = parseResourceUrl(req.url);
@ -46,7 +48,7 @@ export default function Greet(
</header>
<Grid>
{series?.map((doc) => {
return <MovieCard sublink="series" movie={doc} />;
return <ResourceCard sublink="series" res={doc} />;
})}
</Grid>
</MainLayout>