diff --git a/editors/demo/src/HHMI/config/config.js b/editors/demo/src/HHMI/config/config.js index 2d3edda9e2bb2df0c4be3a61b24ec3a11e62a0ac..a124dfeaf9b924e9a1feaad106dc8f98de7d02c0 100644 --- a/editors/demo/src/HHMI/config/config.js +++ b/editors/demo/src/HHMI/config/config.js @@ -22,12 +22,11 @@ import { EssayService, MatchingService, MultipleDropDownService, - AnyStyleService, + ExternalAPIContentService, } from 'wax-prosemirror-services'; import { DefaultSchema } from 'wax-prosemirror-core'; import invisibles, { hardBreak } from '@guardian/prosemirror-invisibles'; -const API_KEY = ''; async function ExternalAPIContentTransformation(prompt) { const response = await fetch('https://api.openai.com/v1/chat/completions', { @@ -125,7 +124,7 @@ export default { toolGroups: ['MultipleDropDown'], }, ], - AnyStyleService: { + ExternalAPIContentService: { ExternalAPIContentTransformation: ExternalAPIContentTransformation, }, @@ -135,7 +134,7 @@ export default { PmPlugins: [columnResizing(), tableEditing(), invisibles([hardBreak()])], services: [ - new AnyStyleService(), + new ExternalAPIContentService(), new MatchingService(), new FillTheGapQuestionService(), new MultipleChoiceQuestionService(), diff --git a/wax-prosemirror-services/index.js b/wax-prosemirror-services/index.js index ef7a4b2f8c0b6ac21bef18e8510ed99c6169cc08..f58d39841de99d028fcd65b3eaf3f57e7d52f012 100644 --- a/wax-prosemirror-services/index.js +++ b/wax-prosemirror-services/index.js @@ -39,7 +39,7 @@ export { default as MultipleDropDownService } from './src/MultipleDropDownServic export { default as OENContainersService } from './src/OENContainersService/OENContainersService'; export { default as YjsService } from './src/YjsService/YjsService'; -export { default as AnyStyleService } from './src/AnyStyleService/AnyStyleService'; +export { default as ExternalAPIContentService } from './src/ExternalAPIContentService/ExternalAPIContentService'; /* ToolGroups */ diff --git a/wax-prosemirror-services/src/AnyStyleService/AnyStyleService.js b/wax-prosemirror-services/src/AnyStyleService/AnyStyleService.js deleted file mode 100644 index c1a1ed47e1e6df6b8c9900d82ed4ea2deff8f3cd..0000000000000000000000000000000000000000 --- a/wax-prosemirror-services/src/AnyStyleService/AnyStyleService.js +++ /dev/null @@ -1,24 +0,0 @@ -import { Service } from 'wax-prosemirror-core'; -import AnyStyleTool from './AnyStyleTool'; -import AnyStyleToolGroupService from './AnyStyleToolGroupService/AnyStyleToolGroupService'; -import AnyStylePlaceHolderPlugin from './plugins/AnyStylePlaceHolderPlugin'; -import './anyStyle.css'; - -class AnyStyleService extends Service { - name = 'AnyStyleService'; - - boot() { - this.app.PmPlugins.add( - 'anyStylePlaceHolder', - AnyStylePlaceHolderPlugin('anyStylePlaceHolder'), - ); - } - - register() { - this.container.bind('AnyStyleTool').to(AnyStyleTool); - } - - dependencies = [new AnyStyleToolGroupService()]; -} - -export default AnyStyleService; diff --git a/wax-prosemirror-services/src/AnyStyleService/AnyStyleTool.js b/wax-prosemirror-services/src/AnyStyleService/AnyStyleTool.js deleted file mode 100644 index 619646470d017d59422b1e7455e0611fbb88ef4f..0000000000000000000000000000000000000000 --- a/wax-prosemirror-services/src/AnyStyleService/AnyStyleTool.js +++ /dev/null @@ -1,69 +0,0 @@ -import React, { useContext } from 'react'; -import { v4 as uuidv4 } from 'uuid'; -import { isEmpty } from 'lodash'; -import { injectable } from 'inversify'; -import { WaxContext, Commands, Tools } from 'wax-prosemirror-core'; -import AnyStyleButton from './components/AnyStyleButton'; -import replaceText from './replaceText'; - -@injectable() -class AnyStyleTool extends Tools { - title = 'ChatGPT'; - name = 'ChatGPT'; - label = 'ChatGPT'; - - get run() { - return true; - } - - select = activeView => { - return true; - }; - - get enable() { - return state => { - return true; - }; - } - - renderTool(view) { - if (isEmpty(view)) return null; - const context = useContext(WaxContext); - const anyStyle = replaceText( - view, - this.config.get('config.AnyStyleService') - .ExternalAPIContentTransformation, - this.pmplugins.get('anyStylePlaceHolder'), - context, - ); - return this.isDisplayed() ? ( - <AnyStyleButton - anyStyle={anyStyle} - item={this.toJSON()} - key={uuidv4()} - view={view} - /> - ) : null; - } - - // renderTool(view) { - // if (isEmpty(view)) return null; - // const context = useContext(WaxContext); - // const upload = fileUpload( - // view, - // this.config.get('fileUpload'), - // this.pmplugins.get('imagePlaceHolder'), - // context, - // ); - // return this.isDisplayed() ? ( - // <ImageUpload - // fileUpload={upload} - // item={this.toJSON()} - // key={uuidv4()} - // view={view} - // /> - // ) : null; - // } -} - -export default AnyStyleTool; diff --git a/wax-prosemirror-services/src/AnyStyleService/AnyStyleToolGroupService/AnyStyle.js b/wax-prosemirror-services/src/AnyStyleService/AnyStyleToolGroupService/AnyStyle.js deleted file mode 100644 index 57217fd6791e37ede78b30d4b9dbd810b7ac6db3..0000000000000000000000000000000000000000 --- a/wax-prosemirror-services/src/AnyStyleService/AnyStyleToolGroupService/AnyStyle.js +++ /dev/null @@ -1,13 +0,0 @@ -import { injectable, inject } from 'inversify'; -import { ToolGroup } from 'wax-prosemirror-core'; - -@injectable() -class Anystyle extends ToolGroup { - tools = []; - constructor(@inject('AnyStyleTool') anyStyleTool) { - super(); - this.tools = [anyStyleTool]; - } -} - -export default Anystyle; diff --git a/wax-prosemirror-services/src/AnyStyleService/AnyStyleToolGroupService/AnyStyleToolGroupService.js b/wax-prosemirror-services/src/AnyStyleService/AnyStyleToolGroupService/AnyStyleToolGroupService.js deleted file mode 100644 index 703a4688e34d31d57045cc56121d6d0dfdec993b..0000000000000000000000000000000000000000 --- a/wax-prosemirror-services/src/AnyStyleService/AnyStyleToolGroupService/AnyStyleToolGroupService.js +++ /dev/null @@ -1,10 +0,0 @@ -import { Service } from 'wax-prosemirror-core'; -import AnyStyle from './AnyStyle'; - -class AnyStyleToolGroupService extends Service { - register() { - this.container.bind('AnyStyle').to(AnyStyle); - } -} - -export default AnyStyleToolGroupService; diff --git a/wax-prosemirror-services/src/AnyStyleService/anyStyle.css b/wax-prosemirror-services/src/AnyStyleService/anyStyle.css deleted file mode 100644 index ef4885cbd069a2368e985ffe1f2bd90f26447d26..0000000000000000000000000000000000000000 --- a/wax-prosemirror-services/src/AnyStyleService/anyStyle.css +++ /dev/null @@ -1,5 +0,0 @@ -placeholder-any-style:before { - position: relative; - top: 3px; - content: url("data:image/svg+xml; utf8, <svg xmlns='http://www.w3.org/2000/svg' height='24' width='24'><path d='M8 20h8v-3q0-1.65-1.175-2.825Q13.65 13 12 13q-1.65 0-2.825 1.175Q8 15.35 8 17Zm-4 2v-2h2v-3q0-1.525.713-2.863Q7.425 12.8 8.7 12q-1.275-.8-1.987-2.138Q6 8.525 6 7V4H4V2h16v2h-2v3q0 1.525-.712 2.862Q16.575 11.2 15.3 12q1.275.8 1.988 2.137Q18 15.475 18 17v3h2v2Z' /></svg>"); -} \ No newline at end of file diff --git a/wax-prosemirror-services/src/AnyStyleService/components/AnyStyleButton.js b/wax-prosemirror-services/src/AnyStyleService/components/AnyStyleButton.js deleted file mode 100644 index eafacca2053069392faeb6c5ee9c69ba98689d20..0000000000000000000000000000000000000000 --- a/wax-prosemirror-services/src/AnyStyleService/components/AnyStyleButton.js +++ /dev/null @@ -1,58 +0,0 @@ -/* eslint react/prop-types: 0 */ -import React, { useContext, useMemo, useEffect } from 'react'; -import { WaxContext, DocumentHelpers, MenuButton } from 'wax-prosemirror-core'; -import { TextSelection } from 'prosemirror-state'; - -const AnyStyleButton = ({ view = {}, item, anyStyle }) => { - const { active, icon, label, run, select, title } = item; - - const { - app, - pmViews: { main }, - activeViewId, - activeView, - } = useContext(WaxContext); - - const { state } = view; - - const handleMouseDown = (e, editorState) => { - e.preventDefault(); - const { - selection: { $from, $to }, - } = editorState; - /* this is the content that we have to get from the selection */ - const textSelection = new TextSelection($from, $to); - - const content = textSelection.content(); - - anyStyle(content.content.content[0].textContent); - }; - - useEffect(() => {}, []); - - const isActive = !!active(state, activeViewId); - let isDisabled = !select(state, activeViewId, activeView); - - const isEditable = main.props.editable(editable => { - return editable; - }); - if (!isEditable) isDisabled = true; - - const AnyStyleButtonComponent = useMemo( - () => ( - <MenuButton - active={isActive || false} - disabled={isDisabled} - iconName={icon} - label={label} - onMouseDown={e => handleMouseDown(e, view.state, view.dispatch)} - title={title} - /> - ), - [isActive, isDisabled], - ); - - return AnyStyleButtonComponent; -}; - -export default AnyStyleButton; diff --git a/wax-prosemirror-services/src/AnyStyleService/plugins/AnyStylePlaceHolderPlugin.js b/wax-prosemirror-services/src/AnyStyleService/plugins/AnyStylePlaceHolderPlugin.js deleted file mode 100644 index 990b75ee2173d6255fc6091b2210595b30a33f45..0000000000000000000000000000000000000000 --- a/wax-prosemirror-services/src/AnyStyleService/plugins/AnyStylePlaceHolderPlugin.js +++ /dev/null @@ -1,37 +0,0 @@ -/* eslint-disable no-param-reassign */ -import { Plugin, PluginKey } from 'prosemirror-state'; -import { Decoration, DecorationSet } from 'prosemirror-view'; - -export default key => - new Plugin({ - key: new PluginKey(key), - state: { - init: function init() { - return DecorationSet.empty; - }, - apply: function apply(tr, set) { - // Adjust decoration positions to changes made by the transaction - set = set.map(tr.mapping, tr.doc); - // See if the transaction adds or removes any placeholders - const action = tr.getMeta(this); - if (action && action.add) { - const widget = document.createElement('placeholder-any-style'); - const deco = Decoration.widget(action.add.pos, widget, { - id: action.add.id, - }); - - set = set.add(tr.doc, [deco]); - } else if (action && action.remove) { - set = set.remove( - set.find(null, null, spec => spec.id === action.remove.id), - ); - } - return set; - }, - }, - props: { - decorations: function decorations(state) { - return this.getState(state); - }, - }, - }); diff --git a/wax-prosemirror-services/src/AnyStyleService/replaceText.js b/wax-prosemirror-services/src/AnyStyleService/replaceText.js deleted file mode 100644 index e54ae8af27d70ae3fc759af87609544a4e2fe8a2..0000000000000000000000000000000000000000 --- a/wax-prosemirror-services/src/AnyStyleService/replaceText.js +++ /dev/null @@ -1,62 +0,0 @@ -import { v4 as uuidv4 } from 'uuid'; -import { DOMParser } from 'prosemirror-model'; - -const findPlaceholder = (state, id, placeholderPlugin) => { - const decos = placeholderPlugin.getState(state); - const found = decos.find(null, null, spec => spec.id === id); - return found.length ? found[0].from : null; -}; - -const elementFromString = string => { - const wrappedValue = `<body>${string}</body>`; - - return new window.DOMParser().parseFromString(wrappedValue, 'text/html').body; -}; - -export default ( - view, - ExternalAPIContentTransformation, - placeholderPlugin, - context, -) => data => { - const { state } = view; - // A fresh object to act as the ID for this upload - const id = {}; - - // Replace the selection with a placeholder - const { tr } = state; - if (!tr.selection.empty) tr.deleteSelection(); - - tr.setMeta(placeholderPlugin, { - add: { id, pos: tr.selection.from }, - }); - - view.dispatch(tr); - - ExternalAPIContentTransformation(data).then( - text => { - const pos = findPlaceholder(view.state, id, placeholderPlugin); - // If the content around the placeholder has been deleted, drop - // the image - if (pos == null) { - return; - } - const parser = DOMParser.fromSchema( - context.pmViews.main.state.config.schema, - ); - const parsedContent = parser.parse(elementFromString(text)); - // Otherwise, insert it at the placeholder's position, and remove - // the placeholder - context.pmViews[context.activeViewId].dispatch( - context.pmViews[context.activeViewId].state.tr - .replaceWith(pos, pos, parsedContent) - .setMeta(placeholderPlugin, { remove: { id } }), - ); - }, - - () => { - // On failure, just clean up the placeholder - view.dispatch(tr.setMeta(placeholderPlugin, { remove: { id } })); - }, - ); -};