From e81055fd6e8e94202967f73ef84c8c76a33bf001 Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Mon, 9 Jan 2023 18:23:29 -0600 Subject: [PATCH] move slide type out to notebook plugin --- js/jupyterlab-deck/src/notebook/plugin.ts | 89 ++++++++++++++++++++++- js/jupyterlab-deck/src/tokens.ts | 2 + 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/js/jupyterlab-deck/src/notebook/plugin.ts b/js/jupyterlab-deck/src/notebook/plugin.ts index 3a20e62..ca8e1e8 100644 --- a/js/jupyterlab-deck/src/notebook/plugin.ts +++ b/js/jupyterlab-deck/src/notebook/plugin.ts @@ -1,21 +1,36 @@ import { JupyterFrontEnd, JupyterFrontEndPlugin } from '@jupyterlab/application'; -import { INotebookTools } from '@jupyterlab/notebook'; +import { ICommandPalette, IPaletteItem } from '@jupyterlab/apputils'; +import { INotebookTools, INotebookTracker } from '@jupyterlab/notebook'; +import { LabIcon } from '@jupyterlab/ui-components'; -import { NS, IDeckManager } from '../tokens'; +import { ICONS } from '../icons'; +import { + NS, + IDeckManager, + CommandIds, + CATEGORY, + META, + TSlideType, + SLIDE_TYPES, +} from '../tokens'; import { NotebookDeckExtension } from './extension'; import { NotebookPresenter } from './presenter'; export const notebookPlugin: JupyterFrontEndPlugin = { id: `${NS}:notebooks`, - requires: [INotebookTools, IDeckManager], + requires: [INotebookTracker, INotebookTools, IDeckManager], + optional: [ICommandPalette], autoStart: true, activate: ( app: JupyterFrontEnd, + notebooks: INotebookTracker, notebookTools: INotebookTools, - decks: IDeckManager + decks: IDeckManager, + palette?: ICommandPalette ) => { const { commands } = app; + const { __ } = decks; const presenter = new NotebookPresenter({ manager: decks, notebookTools, @@ -27,5 +42,71 @@ export const notebookPlugin: JupyterFrontEndPlugin = { 'Notebook', new NotebookDeckExtension({ commands, presenter }) ); + + commands.addCommand(CommandIds.setSlideType, { + label: (args: any) => __(`Slide Type: ${args.slideType}`), + isVisible: () => !!notebooks.activeCell, + icon: (args: any): LabIcon => { + const slideType = args.slideType || 'null'; + return ICONS.slideshow[slideType] || ICONS.deckStart; + }, + execute: (args: any) => { + const { activeCell } = notebooks; + if (!activeCell) { + return; + } + + const slideType = args.slideType || null; + + let cells = [activeCell]; + + const { currentWidget } = notebooks; + + if (currentWidget) { + const selection = notebooks.currentWidget?.content.getContiguousSelection(); + + if (selection && selection.head != null && selection.anchor != null) { + cells = currentWidget.content.widgets.slice( + selection.anchor, + selection.head + 1 + ); + } + } + + for (const cell of cells) { + let meta = { + ...((cell.model.metadata.get(META.slideshow) as Record) || {}), + }; + + if (slideType == null || slideType == 'null') { + delete meta[META.slideType]; + } else { + meta[META.slideType] = slideType; + } + + if (!Object.keys(meta)) { + cell.model.metadata.delete(META.slideshow); + } else { + cell.model.metadata.set(META.slideshow, meta); + } + } + }, + }); + + if (palette) { + const category = __(CATEGORY); + const command = CommandIds.setSlideType; + const isPalette = true; + function makeSlideTypeItem(slideType: TSlideType): IPaletteItem { + return { + category, + command, + args: { slideType, isPalette }, + }; + } + for (const slideType of SLIDE_TYPES) { + palette.addItem(makeSlideTypeItem(slideType)); + } + } }, }; diff --git a/js/jupyterlab-deck/src/tokens.ts b/js/jupyterlab-deck/src/tokens.ts index da7971d..2d33388 100644 --- a/js/jupyterlab-deck/src/tokens.ts +++ b/js/jupyterlab-deck/src/tokens.ts @@ -258,6 +258,8 @@ export namespace CommandIds { /* layover */ export const showLayover = 'deck:show-layover'; export const hideLayover = 'deck:hide-layover'; + /* notebook */ + export const setSlideType = 'deck:set-slide-type'; } export namespace META {