screenshot api

This commit is contained in:
ozakione 2024-04-20 19:25:11 +02:00
parent 510539fc96
commit c8b7e6d5df
8 changed files with 108 additions and 32 deletions

View file

@ -31,7 +31,15 @@ export default async function pluginContentShowcase(
): Promise<Plugin<ShowcaseItems>> {
const {siteDir, localizationDir} = context;
// todo check for better naming of path: sitePath
const {include, exclude, tags, routeBasePath, path: sitePath, id} = options;
const {
include,
exclude,
tags,
routeBasePath,
path: sitePath,
id,
screenshotApi,
} = options;
const contentPaths: ShowcaseContentPaths = {
contentPath: path.resolve(siteDir, sitePath),
@ -81,6 +89,7 @@ export default async function pluginContentShowcase(
await processContentLoaded({
content,
tags: validatedTags,
screenshotApi,
routeBasePath,
addRoute,
});

View file

@ -15,11 +15,13 @@ export async function processContentLoaded({
content,
tags,
routeBasePath,
screenshotApi,
addRoute,
}: {
content: ShowcaseItems;
routeBasePath: string;
tags: TagsOption;
screenshotApi: string;
addRoute: PluginContentLoadedActions['addRoute'];
}): Promise<void> {
addRoute({
@ -28,6 +30,7 @@ export async function processContentLoaded({
props: {
items: content.items,
tags,
screenshotApi,
},
exact: true,
});

View file

@ -256,6 +256,7 @@ declare module '@theme/Showcase' {
export type Props = {
items: ShowcaseItem[];
tags: TagsOption;
screenshotApi: string;
};
export default function Showcase(props: Props): JSX.Element;

View file

@ -10,7 +10,10 @@ import clsx from 'clsx';
import Link from '@docusaurus/Link';
import Translate from '@docusaurus/Translate';
import {sortBy} from '@docusaurus/plugin-content-showcase/client';
import {useShowcaseTags} from '@docusaurus/theme-common/internal';
import {
useShowcaseTags,
useShowcaseApiScreenshot,
} from '@docusaurus/theme-common/internal';
import Heading from '@theme/Heading';
import FavoriteIcon from '@theme/Showcase/FavoriteIcon';
import type {ShowcaseItem, TagType} from '@docusaurus/plugin-content-showcase';
@ -36,6 +39,7 @@ function TagItem({
);
}
// TODO move tag reorder logic into hook
function ShowcaseCardTag({tags}: {tags: TagType[]}) {
const Tags = useShowcaseTags();
const TagList = Object.keys(Tags) as TagType[];
@ -56,18 +60,13 @@ function ShowcaseCardTag({tags}: {tags: TagType[]}) {
);
}
function getCardImage(item: ShowcaseItem): string {
return (
item.preview ??
// TODO make it configurable
`https://slorber-api-screenshot.netlify.app/${encodeURIComponent(
item.website,
)}/showcase`
);
function getCardImage(item: ShowcaseItem, api: string): string {
return item.preview ?? `${api}/${encodeURIComponent(item.website)}/showcase`;
}
function ShowcaseCard({item}: {item: ShowcaseItem}) {
const image = getCardImage(item);
const api = useShowcaseApiScreenshot();
const image = getCardImage(item, api);
return (
<li key={item.title} className="card shadow--md">
<div className={clsx('card__image', styles.showcaseCardImage)}>

View file

@ -7,7 +7,7 @@
import Translate, {translate} from '@docusaurus/Translate';
import Link from '@docusaurus/Link';
import {TagsProvider, ItemsProvider} from '@docusaurus/theme-common/internal';
import {ShowcaseProvider} from '@docusaurus/theme-common/internal';
import Layout from '@theme/Layout';
import Heading from '@theme/Heading';
import ShowcaseSearchBar from '@theme/Showcase/ShowcaseSearchBar';
@ -37,8 +37,10 @@ function ShowcaseHeader() {
export default function Showcase(props: Props): JSX.Element {
return (
<ItemsProvider items={props.items}>
<TagsProvider tags={props.tags}>
<ShowcaseProvider
items={props.items}
tags={props.tags}
screenshotApi={props.screenshotApi}>
<Layout title={TITLE} description={DESCRIPTION}>
<main className="margin-vert--lg">
<ShowcaseHeader />
@ -51,7 +53,6 @@ export default function Showcase(props: Props): JSX.Element {
<ShowcaseCards />
</main>
</Layout>
</TagsProvider>
</ItemsProvider>
</ShowcaseProvider>
);
}

View file

@ -12,18 +12,31 @@ import type {
TagsOption,
} from '@docusaurus/plugin-content-showcase';
// duplicated from theme classic showcase
type Props = {
items: ShowcaseItem[];
tags: TagsOption;
screenshotApi: string;
children: ReactNode;
};
const ItemsContext = React.createContext<ShowcaseItem[] | null>(null);
const ApiContext = React.createContext<string | null>(null);
const TagsContext = React.createContext<TagsOption | null>(null);
function useItemsContextValue(content: ShowcaseItem[]): ShowcaseItem[] {
return useMemo(() => content, [content]);
}
function useApiScreenshotContextValue(content: string): string {
return useMemo(() => content, [content]);
}
function useTagsContextValue(tags: TagsOption): TagsOption {
return useMemo(() => tags, [tags]);
}
export function ItemsProvider({
function ItemsProvider({
children,
items,
}: {
@ -38,7 +51,20 @@ export function ItemsProvider({
);
}
export function TagsProvider({
function ApiScreenshotProvider({
children,
api,
}: {
children: ReactNode;
api: string;
}): JSX.Element {
const contextValue = useApiScreenshotContextValue(api);
return (
<ApiContext.Provider value={contextValue}>{children}</ApiContext.Provider>
);
}
function TagsProvider({
children,
tags,
}: {
@ -51,6 +77,23 @@ export function TagsProvider({
);
}
export function ShowcaseProvider({
items,
tags,
screenshotApi,
children,
}: Props): JSX.Element {
return (
<ItemsProvider items={items}>
<TagsProvider tags={tags}>
<ApiScreenshotProvider api={screenshotApi}>
{children}
</ApiScreenshotProvider>
</TagsProvider>
</ItemsProvider>
);
}
export function useShowcaseItems(): ShowcaseItem[] {
const showcaseItems = useContext(ItemsContext);
if (showcaseItems === null) {
@ -59,6 +102,14 @@ export function useShowcaseItems(): ShowcaseItem[] {
return showcaseItems;
}
export function useShowcaseApiScreenshot(): string {
const showcaseItems = useContext(ApiContext);
if (showcaseItems === null) {
throw new ReactContextError('ItemsProvider');
}
return showcaseItems;
}
export function useShowcaseTags(): TagsOption {
const tags = useContext(TagsContext);
if (tags === null) {

View file

@ -27,10 +27,10 @@ export {DocsSidebarProvider, useDocsSidebar} from './contexts/docsSidebar';
export {DocProvider, useDoc, type DocContextValue} from './contexts/doc';
export {
ItemsProvider,
TagsProvider,
useShowcaseItems,
useShowcaseTags,
useShowcaseApiScreenshot,
ShowcaseProvider,
} from './contexts/showcase';
export {
BlogPostProvider,

12
website/showcase/tags.yml Normal file
View file

@ -0,0 +1,12 @@
favorite:
label: 'Favorite'
description:
message: 'Our favorite Docusaurus sites that you must absolutely check out!'
id: 'showcase.tag.favorite.description'
color: '#e9669e'
opensource:
label: 'Open Source'
description:
message: 'These sites are open source, so you can learn from them!'
id: 'showcase.tag.opensource.description'
color: '#f6993f'