From e381b9a77ba607b22c59d86ac0831d7e642cf56a Mon Sep 17 00:00:00 2001 From: Claudio Promptoso Date: Mon, 6 Jul 2026 11:54:01 +0000 Subject: [PATCH 1/4] feat(server-commands): add presentation.insertPages command Add a plugin server-command that inserts pages into the current presentation at a 1-based position. A null content inserts a single blank page; out-of-range positions are clamped server-side. - enum: PRESENTATION_INSERT_PAGES_COMMAND - types: InsertPagesCommandArguments, insertPages on ServerCommandsPresentationObject - commands: insertPages(position, content?, mimeType?, filename?) dispatcher --- src/server-commands/index.ts | 3 ++ src/server-commands/presentation/commands.ts | 33 +++++++++++++++++++- src/server-commands/presentation/enum.ts | 1 + src/server-commands/presentation/types.ts | 12 +++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/server-commands/index.ts b/src/server-commands/index.ts index 9c50b54b..15c8efd7 100644 --- a/src/server-commands/index.ts +++ b/src/server-commands/index.ts @@ -1,9 +1,12 @@ export { CaptionCommandsEnum, CaptionsTypeEnum } from './caption/enum'; export { ChatCommandsEnum } from './chat/enum'; +export { PresentationCommandsEnum } from './presentation/enum'; export { UploadPresentationBase64Content, UploadPresentationBlobContent, UploadPresentationFileContent, UploadPresentationDataUrlContent, UploadPresentationContent, + UploadPresentationCommandArguments, + InsertPagesCommandArguments, } from './presentation/types'; diff --git a/src/server-commands/presentation/commands.ts b/src/server-commands/presentation/commands.ts index 41039252..0a243838 100644 --- a/src/server-commands/presentation/commands.ts +++ b/src/server-commands/presentation/commands.ts @@ -1,5 +1,9 @@ import { PresentationCommandsEnum } from './enum'; -import { UploadPresentationCommandArguments } from './types'; +import { + InsertPagesCommandArguments, + UploadPresentationCommandArguments, + UploadPresentationContent, +} from './types'; export const presentation = { /** @@ -17,4 +21,31 @@ export const presentation = { }), ); }, + + /** + * Inserts pages into the current presentation at a given position (if presenter, + * ignores otherwise). + * + * @param position 1-based position where the pages are inserted. Out-of-range + * values are clamped by the server (1 prepends, totalPages + 1 appends). + * @param content The file to convert into pages. Pass `null` (or omit) to insert a + * single blank page. + * @param mimeType Optional mime type of the content (e.g. `application/pdf`). + * @param filename Optional original filename. + */ + insertPages: (position: number, content: UploadPresentationContent | null = null, + mimeType?: string, filename?: string) => { + window.dispatchEvent( + new CustomEvent< + InsertPagesCommandArguments + >(PresentationCommandsEnum.INSERT_PAGES, { + detail: { + position, + content, + mimeType, + filename, + }, + }), + ); + }, }; diff --git a/src/server-commands/presentation/enum.ts b/src/server-commands/presentation/enum.ts index 39ddae1d..acf42b71 100644 --- a/src/server-commands/presentation/enum.ts +++ b/src/server-commands/presentation/enum.ts @@ -1,3 +1,4 @@ export enum PresentationCommandsEnum { UPLOAD = 'PRESENTATION_UPLOAD_COMMAND', + INSERT_PAGES = 'PRESENTATION_INSERT_PAGES_COMMAND', } diff --git a/src/server-commands/presentation/types.ts b/src/server-commands/presentation/types.ts index 4b03582b..0cafca60 100644 --- a/src/server-commands/presentation/types.ts +++ b/src/server-commands/presentation/types.ts @@ -26,6 +26,18 @@ export interface UploadPresentationCommandArguments { filename?: string; } +export interface InsertPagesCommandArguments { + // 1-based position where the new pages are inserted. Out-of-range values are + // clamped by the server (1 -> prepend, totalPages + 1 -> append). + position: number; + // The file to convert into pages. `null` inserts a single blank page. + content: UploadPresentationContent | null; + mimeType?: string; + filename?: string; +} + export interface ServerCommandsPresentationObject { upload: (uploadPresentationCommandArguments: UploadPresentationCommandArguments) => void; + insertPages: (position: number, content?: UploadPresentationContent | null, + mimeType?: string, filename?: string) => void; } From fa102a67773052d960c63b77428412ef4bea6ed8 Mon Sep 17 00:00:00 2001 From: Claudio Promptoso Date: Thu, 6 Aug 2026 16:57:34 +0000 Subject: [PATCH 2/4] fix(eslint): reorder insertPages params to satisfy default-param-last Move the defaulted `content` parameter to the end of the `insertPages` signature so optional params (`mimeType`, `filename`) come first, and break the params across lines to satisfy function-paren-newline. Update the JSDoc and the ServerCommandsPresentationObject type to match. --- src/server-commands/presentation/commands.ts | 12 ++++++++---- src/server-commands/presentation/types.ts | 8 ++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/server-commands/presentation/commands.ts b/src/server-commands/presentation/commands.ts index 0a243838..90f51408 100644 --- a/src/server-commands/presentation/commands.ts +++ b/src/server-commands/presentation/commands.ts @@ -28,13 +28,17 @@ export const presentation = { * * @param position 1-based position where the pages are inserted. Out-of-range * values are clamped by the server (1 prepends, totalPages + 1 appends). - * @param content The file to convert into pages. Pass `null` (or omit) to insert a - * single blank page. * @param mimeType Optional mime type of the content (e.g. `application/pdf`). * @param filename Optional original filename. + * @param content The file to convert into pages. Pass `null` (or omit) to insert a + * single blank page. */ - insertPages: (position: number, content: UploadPresentationContent | null = null, - mimeType?: string, filename?: string) => { + insertPages: ( + position: number, + mimeType?: string, + filename?: string, + content: UploadPresentationContent | null = null, + ) => { window.dispatchEvent( new CustomEvent< InsertPagesCommandArguments diff --git a/src/server-commands/presentation/types.ts b/src/server-commands/presentation/types.ts index 0cafca60..5bae98ef 100644 --- a/src/server-commands/presentation/types.ts +++ b/src/server-commands/presentation/types.ts @@ -38,6 +38,10 @@ export interface InsertPagesCommandArguments { export interface ServerCommandsPresentationObject { upload: (uploadPresentationCommandArguments: UploadPresentationCommandArguments) => void; - insertPages: (position: number, content?: UploadPresentationContent | null, - mimeType?: string, filename?: string) => void; + insertPages: ( + position: number, + mimeType?: string, + filename?: string, + content?: UploadPresentationContent | null, + ) => void; } From 4e112d3c850f602b70268e8c82ed3de9179bc1a2 Mon Sep 17 00:00:00 2001 From: Claudio Promptoso Date: Thu, 6 Aug 2026 17:06:51 +0000 Subject: [PATCH 3/4] fix(server-commands): make content the second insertPages parameter The previous ordering pushed content behind mimeType and filename to avoid the default-param-last lint rule, which forced insertPages(2, undefined, undefined, { file }) for the primary use case. The rule only flags default-value parameters, so declaring content as an optional parameter with no default keeps the positional (position, content) contract and still lints clean. The dispatched detail now normalizes an omitted content to null, which core reads as a blank page. --- src/server-commands/presentation/commands.ts | 8 ++++---- src/server-commands/presentation/types.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/server-commands/presentation/commands.ts b/src/server-commands/presentation/commands.ts index 90f51408..a95cc3e9 100644 --- a/src/server-commands/presentation/commands.ts +++ b/src/server-commands/presentation/commands.ts @@ -28,16 +28,16 @@ export const presentation = { * * @param position 1-based position where the pages are inserted. Out-of-range * values are clamped by the server (1 prepends, totalPages + 1 appends). - * @param mimeType Optional mime type of the content (e.g. `application/pdf`). - * @param filename Optional original filename. * @param content The file to convert into pages. Pass `null` (or omit) to insert a * single blank page. + * @param mimeType Optional mime type of the content (e.g. `application/pdf`). + * @param filename Optional original filename. */ insertPages: ( position: number, + content?: UploadPresentationContent | null, mimeType?: string, filename?: string, - content: UploadPresentationContent | null = null, ) => { window.dispatchEvent( new CustomEvent< @@ -45,7 +45,7 @@ export const presentation = { >(PresentationCommandsEnum.INSERT_PAGES, { detail: { position, - content, + content: content ?? null, mimeType, filename, }, diff --git a/src/server-commands/presentation/types.ts b/src/server-commands/presentation/types.ts index 5bae98ef..c9a320fe 100644 --- a/src/server-commands/presentation/types.ts +++ b/src/server-commands/presentation/types.ts @@ -40,8 +40,8 @@ export interface ServerCommandsPresentationObject { upload: (uploadPresentationCommandArguments: UploadPresentationCommandArguments) => void; insertPages: ( position: number, + content?: UploadPresentationContent | null, mimeType?: string, filename?: string, - content?: UploadPresentationContent | null, ) => void; } From 9146f620aa849e6de5685012cbd0209d7fb9dd1d Mon Sep 17 00:00:00 2001 From: Claudio Promptoso Date: Thu, 6 Aug 2026 17:15:15 +0000 Subject: [PATCH 4/4] docs(server-commands): document presentation.insertPages Add the insertPages entry to the server commands namespace list, with an example usage that inserts the pages of a PDF file at a given position. Also deduplicate the presentation block: it was listed twice, verbatim, as a leftover of the v0.0.x into v0.1.x merges, and both copies were indented as children of the caption namespace instead of being a sibling of it. --- README.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a9b8b36a..005ec30d 100644 --- a/README.md +++ b/README.md @@ -869,11 +869,9 @@ So the idea is that we have a `uiCommands` object and at a point, there will be - save: this function saves the given text, locale and caption type - addLocale: this function sends a locale to be added to the available options - - presentation: - - upload: uploads a new presentation to BigBlueButton; - - - presentation: - - upload: uploads a new presentation to BigBlueButton; +- presentation: + - upload: uploads a new presentation to BigBlueButton; + - insertPages: inserts pages into the current presentation at a given 1-based position (out-of-range values are clamped by the server: 1 prepends, totalPages + 1 appends). The content is the file to convert into pages; omitting it (or passing null) inserts a single blank page; **Example usage:** @@ -933,6 +931,15 @@ So the idea is that we have a `uiCommands` object and at a point, there will be }); }, }), + new ActionButtonDropdownOption({ + label: 'Insert pages', + icon: 'copy', + onClick: () => { + // Insert the pages of a PDF file at position 2 of the current presentation + // (pdfFile is a File object, e.g. taken from an input of type file) + pluginApi.serverCommands.presentation.insertPages(2, { file: pdfFile }); + }, + }), ]); }, []);