Implement block content ref

This commit is contained in:
Samy Pessé
2023-11-03 21:23:41 -04:00
parent 84dd482430
commit df84dda36a
8 changed files with 106 additions and 56 deletions
+1 -4
View File
@@ -27,10 +27,7 @@ export default async function PDFHTMLOutput(props: {
const { params, searchParams } = props;
const { spaceId } = params;
const [space, revision] = await Promise.all([
getSpace(spaceId),
getCurrentRevision(spaceId),
]);
const [space, revision] = await Promise.all([getSpace(spaceId), getCurrentRevision(spaceId)]);
const pages = selectPages(revision, searchParams).slice(0, 4); // TODO: remove slice
+1 -4
View File
@@ -20,10 +20,7 @@ export interface PageIdParams extends SpaceParams {
export async function fetchPageData(params: PagePathParams | PageIdParams) {
const { spaceId } = params;
const [space, revision] = await Promise.all([
getSpace(spaceId),
getCurrentRevision(spaceId),
]);
const [space, revision] = await Promise.all([getSpace(spaceId), getCurrentRevision(spaceId)]);
const page =
'pageId' in params && params.pageId
+6 -1
View File
@@ -16,6 +16,7 @@ import { Embed } from './Embed';
import { Quote } from './Quote';
import {
DocumentBlockCode,
DocumentBlockContentRef,
DocumentBlockDivider,
DocumentBlockDrawing,
DocumentBlockEmbed,
@@ -43,6 +44,7 @@ import { ListTasks } from './ListTasks';
import { Divider } from './Divider';
import assertNever from 'assert-never';
import { Drawing } from './Drawing';
import { BlockContentRef } from './BlockContentRef';
export type SupportedBlock =
| DocumentBlockParagraph
@@ -64,7 +66,8 @@ export type SupportedBlock =
| DocumentBlockMath
| DocumentBlockFile
| DocumentBlockDivider
| DocumentBlockDrawing;
| DocumentBlockDrawing
| DocumentBlockContentRef;
export type AncestorBlock = SupportedBlock | DocumentBlockTabsItem;
@@ -118,6 +121,8 @@ export function Block<T extends SupportedBlock>(props: BlockProps<T>) {
return <Divider {...props} {...contextProps} block={block} />;
case 'drawing':
return <Drawing {...props} {...contextProps} block={block} />;
case 'content-ref':
return <BlockContentRef {...props} {...contextProps} block={block} />;
default:
assertNever(block);
}
@@ -0,0 +1,41 @@
import { resolveContentRef } from '@/lib/references';
import { DocumentBlockContentRef } from '@gitbook/api';
import { BlockProps } from './Block';
import { tcls } from '@/lib/tailwind';
import IconFile from '@geist-ui/icons/file';
export async function BlockContentRef(props: BlockProps<DocumentBlockContentRef>) {
const { block, context, style } = props;
const resolved = await resolveContentRef(block.data.ref, context);
if (!resolved) {
return null;
}
return (
<a
href={resolved.href}
className={tcls(
'flex',
'flex-row',
'items-center',
'rounded',
'border',
'border-slate-200',
'hover:border-slate-300',
'px-5',
'py-2',
'text-slate-500',
'hover:text-slate-700',
style,
)}
>
<div className={tcls('mr-5')}>
<IconFile className={tcls('w-6', 'h-6')} />
</div>
<div>
<div className={tcls('text-base')}>{resolved.text}</div>
</div>
</a>
);
}
+3 -1
View File
@@ -3,7 +3,9 @@ import { Inline } from './Inline';
import { DocumentContextProps } from './DocumentView';
import { DocumentInlinesRich } from '@gitbook/api';
export function Inlines<T extends DocumentInlinesRich>(props: DocumentContextProps & { nodes: T[] }) {
export function Inlines<T extends DocumentInlinesRich>(
props: DocumentContextProps & { nodes: T[] },
) {
const { nodes, ...contextProps } = props;
return (
+22 -19
View File
@@ -2,29 +2,32 @@ import { RevisionPageLink } from '@gitbook/api';
import { tcls } from '@/lib/tailwind';
import Link from 'next/link';
export function PageLinkItem(props: {
page: RevisionPageLink;
}) {
export function PageLinkItem(props: { page: RevisionPageLink }) {
const { page } = props;
return (
<li className={tcls('flex', 'flex-col', 'mb-0.5')}>
<Link href={
page.href ?? '#todo' // TODO: Will be fixed soon as the `target`
}
className={tcls(
'flex',
'flex-row',
'justify-between',
'rounded',
'px-2',
'py-1.5',
'text-sm',
'transition-colors',
'duration-100',
'hover:bg-slate-100', 'text-slate-500', 'font-normal',
)}
>{page.title}</Link>
<Link
href={
page.href ?? '#todo' // TODO: Will be fixed soon as the `target`
}
className={tcls(
'flex',
'flex-row',
'justify-between',
'rounded',
'px-2',
'py-1.5',
'text-sm',
'transition-colors',
'duration-100',
'hover:bg-slate-100',
'text-slate-500',
'font-normal',
)}
>
{page.title}
</Link>
</li>
);
}
+1 -6
View File
@@ -25,12 +25,7 @@ export function PagesList(props: {
/>
);
} else if (page.type === 'link') {
return (
<PageLinkItem
key={page.id}
page={page}
/>
);
return <PageLinkItem key={page.id} page={page} />;
}
return (
+31 -21
View File
@@ -22,32 +22,42 @@ export function api(): GitBookAPI {
/**
* Get a space by its ID.
*/
export const getSpace = unstable_cache(async (spaceId: string) => {
const { data } = await api().spaces.getSpaceById(spaceId);
return data;
}, ['api', 'spaces'], {
tags: ['api', 'spaces']
});
export const getSpace = unstable_cache(
async (spaceId: string) => {
const { data } = await api().spaces.getSpaceById(spaceId);
return data;
},
['api', 'spaces'],
{
tags: ['api', 'spaces'],
},
);
/**
* Get the current revision of a space
*/
export const getCurrentRevision = unstable_cache(async (spaceId: string) => {
const { data } = await api().spaces.getCurrentRevision(spaceId);
return data;
}, ['api', 'revisions'], {
tags: ['api', 'revisions']
});
export const getCurrentRevision = unstable_cache(
async (spaceId: string) => {
const { data } = await api().spaces.getCurrentRevision(spaceId);
return data;
},
['api', 'revisions'],
{
tags: ['api', 'revisions'],
},
);
/**
* Get the document for a page.
*/
export const getPageDocument = unstable_cache(async (spaceId: string, revisionId: string, pageId: string) => {
const { data } = await api().spaces.getPageInRevisionById(spaceId, revisionId, pageId);
// @ts-ignore
return data.document as JSONDocument;
}, ['api', 'documents'], {
tags: ['api', 'documents']
});
export const getPageDocument = unstable_cache(
async (spaceId: string, revisionId: string, pageId: string) => {
const { data } = await api().spaces.getPageInRevisionById(spaceId, revisionId, pageId);
// @ts-ignore
return data.document as JSONDocument;
},
['api', 'documents'],
{
tags: ['api', 'documents'],
},
);