Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ and this project adheres to

- 馃泜(backend) let users allowed to comment list each other's accesses #2447
- 猬嗭笍(frontend) update BlockNote preview packages to 83153fda2e
- 馃悰(frontend) adapt to the BlockNote 0.56 editor and exporter APIs
- 鈾伙笍(frontend) restore bounded editor history through native yhub rollback
- 鈾伙笍(frontend) use standalone YHub version storage and history extension
- 鈾伙笍(frontend) migrate the history panel to RenderInPortalElement
Expand Down
9 changes: 8 additions & 1 deletion deploy/dev-instance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,14 @@ pull request.
cd src/frontend && yarn install --ignore-engines
```

`yarn.lock` must change only the `@blocknote/*` entries.
`yarn.lock` must change only the `@blocknote/*` entries. A new BlockNote
version can change its API, and the deploy fails in the frontend build.
So type-check before you open the pull request:

```bash
cd src/frontend/apps/impress && npx tsc --noEmit -p .
```

4. Commit as `猬嗭笍(frontend) update BlockNote preview packages to <new sha>`
(signed off), open a pull request against `dev`, and merge it. The merge
deploys.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
blockTypeSelectItems,
getFormattingToolbarItems,
useBlockNoteEditor,
useDictionary,
} from '@blocknote/react';
import dynamic from 'next/dynamic';
import React, { useCallback, useMemo, useState } from 'react';
Expand Down Expand Up @@ -34,15 +33,14 @@ const AIToolbarButton = BlockNoteAI?.AIToolbarButton;

export const BlockNoteToolbar = ({ aiAllowed }: { aiAllowed: boolean }) => {
const editor = useBlockNoteEditor();
const dict = useDictionary();
const [confirmOpen, setIsConfirmOpen] = useState(false);
const [onConfirm, setOnConfirm] = useState<() => void | Promise<void>>();
const { t } = useTranslation();
const { data: conf } = useConfig();

const toolbarItems = useMemo(() => {
let toolbarItems = getFormattingToolbarItems([
...blockTypeSelectItems(dict),
...blockTypeSelectItems(editor),
getCalloutFormattingToolbarItems(t),
...getMathBlockTypeSelectItems(editor),
...getDiagramBlockTypeSelectItems(editor),
Expand Down Expand Up @@ -81,7 +79,7 @@ export const BlockNoteToolbar = ({ aiAllowed }: { aiAllowed: boolean }) => {
});

return toolbarItems;
}, [dict, editor, t]);
}, [editor, t]);

const formattingToolbar = useCallback(() => {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,19 @@ export const createSafeCodeBlockSpec = (): ReturnType<
> => {
const spec = createCodeBlockSpec(codeBlockOptions);
const baseRender = spec.implementation.render;
if (!baseRender) {
throw new Error('The BlockNote code block spec has no render function');
}
type Render = NonNullable<typeof spec.implementation.render>;

return {
...spec,
implementation: {
...spec.implementation,
render(
this: ThisParameterType<typeof baseRender>,
...args: Parameters<typeof baseRender>
): ReturnType<typeof baseRender> {
this: ThisParameterType<Render>,
...args: Parameters<Render>
): ReturnType<Render> {
const [block, editor] = args;
const language = resolveCodeBlockLanguage(block.props.language);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,50 +25,53 @@ const imageBoxStyle = {
* @returns A react-pdf View element, or an empty View when the blob is not an
* image or the conversion fails.
*/
export const blockMappingImagePDF: DocsExporterPDF['mappings']['blockMapping']['image'] =
async (block, exporter) => {
const blob = await exporter.resolveFile(block.props.url);
let result: { png: string; width: number; height: number } | undefined;
const previewWidth = block.props.previewWidth
? Math.min(block.props.previewWidth, MAX_WIDTH)
: undefined;
// The plain function form of the mapping, so that tests can call it directly.
export const blockMappingImagePDF: Extract<
DocsExporterPDF['mappings']['blockMapping']['image'],
(...args: never[]) => unknown
> = async (block, exporter) => {
const blob = await exporter.resolveFile(block.props.url);
let result: { png: string; width: number; height: number } | undefined;
const previewWidth = block.props.previewWidth
? Math.min(block.props.previewWidth, MAX_WIDTH)
: undefined;

if (!blob.type.includes('image')) {
return <View wrap={false} />;
}
if (!blob.type.includes('image')) {
return <View wrap={false} />;
}

try {
if (blob.type.includes('svg')) {
const svgText = await blob.text();
result = await convertSvgToPng(svgText, previewWidth);
} else {
result = await convertBlobToPng(blob, previewWidth);
}
} catch {
return <View wrap={false} />;
try {
if (blob.type.includes('svg')) {
const svgText = await blob.text();
result = await convertSvgToPng(svgText, previewWidth);
} else {
result = await convertBlobToPng(blob, previewWidth);
}
} catch {
return <View wrap={false} />;
}

if (!result || !result.png) {
return <View wrap={false} />;
}
if (!result || !result.png) {
return <View wrap={false} />;
}

// Ensure the final width never exceeds MAX_WIDTH to prevent images
// from overflowing the page width in the exported document
const finalWidth = Math.min(previewWidth || result.width, MAX_WIDTH);
// Ensure the final width never exceeds MAX_WIDTH to prevent images
// from overflowing the page width in the exported document
const finalWidth = Math.min(previewWidth || result.width, MAX_WIDTH);

return (
<View wrap={false} style={imageBoxStyle}>
<Image
src={result.png}
style={{
width: finalWidth * PIXELS_PER_POINT,
maxWidth: '100%',
}}
/>
{caption(block.props)}
</View>
);
};
return (
<View wrap={false} style={imageBoxStyle}>
<Image
src={result.png}
style={{
width: finalWidth * PIXELS_PER_POINT,
maxWidth: '100%',
}}
/>
{caption(block.props)}
</View>
);
};

/**
* Renders an optional caption below an image in the PDF.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const getDocxDocsSchemaMappings = (
quote: blockMappingQuoteDocx,
image: blockMappingImageDocx,
uploadLoader: blockMappingUploadLoaderDocx,
table: (block, exporter, nestedLevel, numberedListIndex, children) => {
table: (block, exporter, nestedLevel, numberedListIndex) => {
/**
* Nan values are not supported, so we need to replace them with undefined
* to avoid issues during the export.
Expand All @@ -47,13 +47,17 @@ export const getDocxDocsSchemaMappings = (
);
}

return docxDefaultSchemaMappings.blockMapping.table(
block,
exporter,
nestedLevel,
numberedListIndex,
children,
);
const tableMapping = docxDefaultSchemaMappings.blockMapping.table;
// A table has no child blocks.
return typeof tableMapping === 'function'
? tableMapping(block, exporter, nestedLevel, numberedListIndex)
: tableMapping.withChildren(
block,
exporter,
nestedLevel,
numberedListIndex,
[],
);
},
},
inlineContentMapping: {
Expand Down
Loading