feat: make author clickable
This commit is contained in:
@ -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. */
|
||||
|
@ -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) => {
|
||||
//
|
||||
});
|
||||
}
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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}`}
|
||||
|
@ -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}`
|
||||
: ""}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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 });
|
||||
|
@ -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>
|
||||
|
Reference in New Issue
Block a user