🍱(frontend) manage export emoji locally

We now use exported emoji from emoji-datasource-apple
package instead of relying on a CDN.
During a build or dev command, the emoji images
are copied from node_modules to the public assets
folder. They are not versionned.
This commit is contained in:
Anthony LC
2025-10-06 14:54:25 +02:00
parent db7ae350ec
commit 93227466d2
8 changed files with 48 additions and 5 deletions

View File

@@ -11,6 +11,7 @@ import {
verifyDocName,
waitForLanguageSwitch,
} from './utils-common';
import { openSuggestionMenu, writeInEditor } from './utils-editor';
import { createRootSubPage } from './utils-sub-pages';
test.beforeEach(async ({ page }) => {
@@ -153,11 +154,13 @@ test.describe('Doc Export', () => {
await verifyDocName(page, randomDoc);
await page.locator('.ProseMirror.bn-editor').click();
await page.locator('.ProseMirror.bn-editor').fill('Hello World');
await writeInEditor({
page,
text: 'Hello World 😃🎉🚀🙋‍♀️🧑🏿‍❤️‍💋‍🧑🏾',
});
await page.keyboard.press('Enter');
await page.locator('.bn-block-outer').last().fill('/');
await openSuggestionMenu({ page });
await page.getByText('Resizable image with caption').click();
const fileChooserPromise = page.waitForEvent('filechooser');

View File

@@ -37,4 +37,6 @@ yarn-error.log*
service-worker.js
# Font embedding
public/assets/fonts/emoji/*
!public/assets/fonts/emoji/fallback.png
public/assets/fonts/Marianne/*

View File

@@ -47,12 +47,21 @@ const nextConfig = {
config.plugins.push(
new CopyPlugin({
patterns: [
{
from: path.resolve(
__dirname,
'../../node_modules/emoji-datasource-apple/img/apple/64',
),
to: path.resolve(__dirname, 'public/assets/fonts/emoji'),
force: true,
},
{
from: path.resolve(
__dirname,
'../../node_modules/@gouvfr-lasuite/ui-kit/dist/assets/fonts/Marianne',
),
to: path.resolve(__dirname, 'public/assets/fonts/Marianne'),
force: true,
},
],
}),

View File

@@ -43,6 +43,7 @@
"cmdk": "1.1.1",
"crisp-sdk-web": "1.0.25",
"docx": "9.5.0",
"emoji-datasource-apple": "16.0.0",
"emoji-mart": "5.6.0",
"emoji-regex": "10.5.0",
"i18next": "25.5.2",

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -10,6 +10,7 @@ import {
useToastProvider,
} from '@openfun/cunningham-react';
import { DocumentProps, pdf } from '@react-pdf/renderer';
import jsonemoji from 'emoji-datasource-apple' assert { type: 'json' };
import i18next from 'i18next';
import { cloneElement, isValidElement, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
@@ -95,6 +96,20 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
if (format === DocDownloadFormat.PDF) {
const exporter = new PDFExporter(editor.schema, pdfDocsSchemaMappings, {
resolveFileUrl: async (url) => exportCorsResolveFileUrl(doc.id, url),
emojiSource: {
format: 'png',
builder(code) {
const emoji = jsonemoji.find((e) =>
e.unified.toLocaleLowerCase().includes(code.toLowerCase()),
);
if (emoji) {
return `/assets/fonts/emoji/${emoji.image}`;
}
return '/assets/fonts/emoji/fallback.png';
},
},
});
const rawPdfDocument = (await exporter.toReactPDFDocument(
exportDocument,
@@ -150,7 +165,6 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
color="secondary"
fullWidth
onClick={() => onClose()}
disabled={isExporting}
>
{t('Cancel')}
</Button>