diff --git a/src/client/datascience/interactive-common/interactiveBase.ts b/src/client/datascience/interactive-common/interactiveBase.ts index 477cee6b1792..e4c00f7c83c1 100644 --- a/src/client/datascience/interactive-common/interactiveBase.ts +++ b/src/client/datascience/interactive-common/interactiveBase.ts @@ -11,7 +11,6 @@ import { CancellationToken, ConfigurationTarget, Event, EventEmitter, Memento, P import { Disposable } from 'vscode-jsonrpc'; import { ServerStatus } from '../../../datascience-ui/interactive-common/mainState'; -import { CommonActionType } from '../../../datascience-ui/interactive-common/redux/reducers/types'; import { IApplicationShell, ICommandManager, IDocumentManager, ILiveShareApi, IWebPanelProvider, IWorkspaceService } from '../../common/application/types'; import { CancellationError } from '../../common/cancellation'; import { EXTENSION_ROOT_DIR, PYTHON_LANGUAGE } from '../../common/constants'; @@ -44,7 +43,7 @@ import { JupyterInstallError } from '../jupyter/jupyterInstallError'; import { JupyterSelfCertsError } from '../jupyter/jupyterSelfCertsError'; import { JupyterKernelPromiseFailedError } from '../jupyter/kernels/jupyterKernelPromiseFailedError'; import { LiveKernelModel } from '../jupyter/kernels/types'; -import { CssMessages, SharedMessages } from '../messages'; +import { CssMessages } from '../messages'; import { ProgressReporter } from '../progress/progressReporter'; import { CellState, @@ -74,7 +73,6 @@ import { } from '../types'; import { WebViewHost } from '../webViewHost'; import { InteractiveWindowMessageListener } from './interactiveWindowMessageListener'; -import { BaseReduxActionPayload } from './types'; @injectable() export abstract class InteractiveBase extends WebViewHost implements IInteractiveBase { @@ -178,11 +176,6 @@ export abstract class InteractiveBase extends WebViewHost }; - this.postMessageInternal(syncPayload.type, syncPayload.payload).ignoreErrors(); - break; case InteractiveWindowMessages.GotoCodeCell: this.handleMessage(message, payload, this.gotoCode); break; diff --git a/src/client/datascience/interactive-common/interactiveWindowMessageListener.ts b/src/client/datascience/interactive-common/interactiveWindowMessageListener.ts index 2dfe92e76597..7234c41169ba 100644 --- a/src/client/datascience/interactive-common/interactiveWindowMessageListener.ts +++ b/src/client/datascience/interactive-common/interactiveWindowMessageListener.ts @@ -15,7 +15,6 @@ import { InteractiveWindowMessages, InteractiveWindowRemoteMessages } from './in // This class listens to messages that come from the local Python Interactive window export class InteractiveWindowMessageListener implements IWebPanelMessageListener { - private static handlers = new Map void>(); private postOffice: PostOffice; private disposedCallback: () => void; private callback: (message: string, payload: any) => void; @@ -41,7 +40,6 @@ export class InteractiveWindowMessageListener implements IWebPanelMessageListene this.interactiveWindowMessages.forEach(m => { this.postOffice.registerCallback(m, a => callback(m, a)).ignoreErrors(); }); - InteractiveWindowMessageListener.handlers.set(this, callback); } public async dispose() { @@ -50,20 +48,6 @@ export class InteractiveWindowMessageListener implements IWebPanelMessageListene } public onMessage(message: string, payload: any) { - if (message === InteractiveWindowMessages.Sync) { - // const syncPayload = payload as BaseReduxActionPayload; - Array.from(InteractiveWindowMessageListener.handlers.keys()).forEach(item => { - if (item === this) { - return; - } - // Temporarily disabled. - // const cb = InteractiveWindowMessageListener.handlers.get(item); - // if (cb) { - // cb(InteractiveWindowMessages.Sync, { type: message, payload: syncPayload }); - // } - }); - return; - } // We received a message from the local webview. Broadcast it to everybody if it's a remote message if (InteractiveWindowRemoteMessages.indexOf(message) >= 0) { this.postOffice.postCommand(message, payload).ignoreErrors(); diff --git a/src/client/datascience/interactive-common/synchronization.ts b/src/client/datascience/interactive-common/synchronization.ts index 1907039ada87..2db0a1ba5a46 100644 --- a/src/client/datascience/interactive-common/synchronization.ts +++ b/src/client/datascience/interactive-common/synchronization.ts @@ -1,7 +1,6 @@ import { CommonActionType, CommonActionTypeMapping } from '../../../datascience-ui/interactive-common/redux/reducers/types'; import { CssMessages, SharedMessages } from '../messages'; import { IInteractiveWindowMapping, InteractiveWindowMessages } from './interactiveWindowTypes'; -import { BaseReduxActionPayload } from './types'; // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. @@ -172,11 +171,30 @@ const messageWithMessageTypes: MessageMapping & Messa [SharedMessages.UpdateSettings]: MessageType.userAction }; -export function isActionPerformedByUser(action: BaseReduxActionPayload<{}> | BaseReduxActionPayload) { - return action.messageType === undefined; +/** + * If the original message was a sync message, then do not send messages to extension. + * We allow messages to be sent to extension ONLY when the original message was triggered by the user. + * + * @export + * @param {MessageType} [messageType] + * @returns + */ +export function checkToPostBasedOnOriginalMessageType(messageType?: MessageType): boolean { + if (!messageType) { + return true; + } + if ( + (messageType & MessageType.syncAcrossSameNotebooks) === MessageType.syncAcrossSameNotebooks || + (messageType & MessageType.syncWithLiveShare) === MessageType.syncWithLiveShare + ) { + return false; + } + + return true; } export function shouldRebroadcast(message: keyof IInteractiveWindowMapping): [boolean, MessageType] { + // Get the configured type for this message (whether it should be re-broadcasted or not). const messageType: MessageType | undefined = messageWithMessageTypes[message]; // Support for liveshare is turned off for now, we can enable that later. // I.e. we only support synchronizing across editors in the same session. diff --git a/src/datascience-ui/history-react/redux/actions.ts b/src/datascience-ui/history-react/redux/actions.ts index b8ef4e5bdc16..e32e54cc140f 100644 --- a/src/datascience-ui/history-react/redux/actions.ts +++ b/src/datascience-ui/history-react/redux/actions.ts @@ -2,12 +2,12 @@ // Licensed under the MIT License. 'use strict'; -import { InteractiveWindowMessages } from '../../../client/datascience/interactive-common/interactiveWindowTypes'; +import { IInteractiveWindowMapping, InteractiveWindowMessages } from '../../../client/datascience/interactive-common/interactiveWindowTypes'; import { IJupyterVariable, IJupyterVariablesRequest } from '../../../client/datascience/types'; -import { createIncomingAction, createIncomingActionWithPayload } from '../../interactive-common/redux/helpers'; import { CommonAction, CommonActionType, + CommonActionTypeMapping, ICellAction, ICodeAction, ICodeCreatedAction, @@ -18,6 +18,16 @@ import { } from '../../interactive-common/redux/reducers/types'; import { IMonacoModelContentChangeEvent } from '../../react-common/monacoHelpers'; +// This function isn't made common and not exported, to ensure it isn't used elsewhere. +function createIncomingActionWithPayload(type: K, data: M[K]): CommonAction { + // tslint:disable-next-line: no-any + return { type, payload: { data, messageDirection: 'incoming' } as any } as any; +} +// This function isn't made common and not exported, to ensure it isn't used elsewhere. +function createIncomingAction(type: CommonActionType | InteractiveWindowMessages): CommonAction { + return { type, payload: { messageDirection: 'incoming', data: undefined } }; +} + // See https://react-redux.js.org/using-react-redux/connect-mapdispatch#defining-mapdispatchtoprops-as-an-object export const actionCreators = { restartKernel: (): CommonAction => createIncomingAction(CommonActionType.RESTART_KERNEL), diff --git a/src/datascience-ui/interactive-common/redux/helpers.ts b/src/datascience-ui/interactive-common/redux/helpers.ts index 24a0a807420c..de782c14078a 100644 --- a/src/datascience-ui/interactive-common/redux/helpers.ts +++ b/src/datascience-ui/interactive-common/redux/helpers.ts @@ -5,10 +5,11 @@ import * as Redux from 'redux'; import { IInteractiveWindowMapping, InteractiveWindowMessages } from '../../../client/datascience/interactive-common/interactiveWindowTypes'; +import { checkToPostBasedOnOriginalMessageType, MessageType, shouldRebroadcast } from '../../../client/datascience/interactive-common/synchronization'; import { BaseReduxActionPayload } from '../../../client/datascience/interactive-common/types'; import { CssMessages, SharedMessages } from '../../../client/datascience/messages'; import { QueueAnotherFunc } from '../../react-common/reduxUtils'; -import { CommonAction, CommonActionType, CommonActionTypeMapping } from './reducers/types'; +import { CommonActionType, CommonActionTypeMapping } from './reducers/types'; const AllowedMessages = [...Object.values(InteractiveWindowMessages), ...Object.values(CssMessages), ...Object.values(SharedMessages), ...Object.values(CommonActionType)]; export function isAllowedMessage(message: string) { @@ -19,20 +20,32 @@ export function isAllowedAction(action: Redux.AnyAction) { return isAllowedMessage(action.type); } -export function createIncomingActionWithPayload(type: K, data: M[K]): CommonAction { - // tslint:disable-next-line: no-any - return { type, payload: { data, messageDirection: 'incoming' } as any } as any; -} -export function createIncomingAction(type: CommonActionType | InteractiveWindowMessages): CommonAction { - return { type, payload: { messageDirection: 'incoming', data: undefined } }; -} - type ReducerArg = { // tslint:disable-next-line: no-any queueAction: QueueAnotherFunc; // tslint:disable-next-line: no-any payload?: BaseReduxActionPayload; }; + +export function queueIncomingActionWithPayload( + originalReducerArg: ReducerArg, + type: K, + data: M[K] +): void { + if (!checkToPostBasedOnOriginalMessageType(originalReducerArg.payload?.messageType)) { + return; + } + + // tslint:disable-next-line: no-any + const action = { type, payload: { data, messageDirection: 'incoming' } as any } as any; + originalReducerArg.queueAction(action); +} + +export function queueIncomingAction(originalReducerArg: ReducerArg, type: K): void { + // tslint:disable-next-line: no-any + queueIncomingActionWithPayload(originalReducerArg, type as any, undefined); +} + /** * Post a message to the extension (via dispatcher actions). */ @@ -44,10 +57,15 @@ export function postActionToExtension(originalReducerArg: ReducerArg, message: T, payload?: M[T]): void; // tslint:disable-next-line: no-any export function postActionToExtension(originalReducerArg: ReducerArg, message: any, payload?: any) { + if (!checkToPostBasedOnOriginalMessageType(originalReducerArg.payload?.messageType)) { + return; + } + // tslint:disable-next-line: no-any const newPayload: BaseReduxActionPayload = ({ data: payload, - messageDirection: 'outgoing' + messageDirection: 'outgoing', + messageType: MessageType.userAction // tslint:disable-next-line: no-any } as any) as BaseReduxActionPayload; const action = { type: CommonActionType.PostOutgoingMessage, payload: { payload: newPayload, type: message } }; @@ -61,27 +79,28 @@ export function unwrapPostableAction(action: Redux.AnyAction): { type: keyof IIn } export function reBroadcastMessageIfRequired( - _dispatcher: Function, + dispatcher: Function, message: InteractiveWindowMessages | SharedMessages | CommonActionType | CssMessages, payload?: BaseReduxActionPayload<{}> ) { - if (typeof payload?.messageType === 'number' || message === InteractiveWindowMessages.Sync) { + if ( + message === InteractiveWindowMessages.Sync || + payload?.messageType === MessageType.syncAcrossSameNotebooks || + payload?.messageType === MessageType.syncWithLiveShare || + payload?.messageDirection === 'outgoing' + ) { return; } - if (payload?.messageDirection === 'outgoing') { - return; + // Check if we need to re-broadcast this message to other editors/sessions. + // tslint:disable-next-line: no-any + const result = shouldRebroadcast(message as any); + if (result[0]) { + // Mark message as incoming, to indicate this will be sent into the other webviews. + // tslint:disable-next-line: no-any + const syncPayloadData: BaseReduxActionPayload = { data: payload?.data, messageType: result[1], messageDirection: 'incoming' }; + // tslint:disable-next-line: no-any + const syncPayload = { type: message, payload: syncPayloadData } as any; + // Send this out. + dispatcher(InteractiveWindowMessages.Sync, syncPayload); } - // Temporarily disabled. - // // Check if we need to re-broadcast this message to other editors/sessions. - // // tslint:disable-next-line: no-any - // const result = shouldRebroadcast(message as any); - // if (result[0]) { - // // Mark message as incoming, to indicate this will be sent into the other webviews. - // // tslint:disable-next-line: no-any - // const syncPayloadData: BaseReduxActionPayload = { data: payload?.data, messageType: result[1], messageDirection: 'incoming' }; - // // tslint:disable-next-line: no-any - // const syncPayload = { type: message, payload: syncPayloadData } as any; - // // Send this out. - // dispatcher(InteractiveWindowMessages.Sync, syncPayload); - // } } diff --git a/src/datascience-ui/interactive-common/redux/postOffice.ts b/src/datascience-ui/interactive-common/redux/postOffice.ts index a7831b4eeb8e..206477fa32aa 100644 --- a/src/datascience-ui/interactive-common/redux/postOffice.ts +++ b/src/datascience-ui/interactive-common/redux/postOffice.ts @@ -23,7 +23,7 @@ export function generatePostOfficeSendReducer(postOffice: PostOffice): Redux.Red const payload: BaseReduxActionPayload<{}> | undefined = action.payload; // Do not rebroadcast messages that have been sent through as part of a synchronization packet. // If `messageType` is a number, then its some part of a synchronization packet. - if (payload?.messageDirection === 'incoming' && typeof payload?.messageType !== 'number') { + if (payload?.messageDirection === 'incoming') { // We can delay this, first focus on UX perf. setTimeout(() => { reBroadcastMessageIfRequired(postOffice.sendMessage.bind(postOffice), action.type, action?.payload); diff --git a/src/datascience-ui/interactive-common/redux/reducers/monaco.ts b/src/datascience-ui/interactive-common/redux/reducers/monaco.ts index fc559bcaacfb..3722eed87d0c 100644 --- a/src/datascience-ui/interactive-common/redux/reducers/monaco.ts +++ b/src/datascience-ui/interactive-common/redux/reducers/monaco.ts @@ -20,7 +20,7 @@ import { PostOffice } from '../../../react-common/postOffice'; import { combineReducers, QueuableAction, ReducerArg, ReducerFunc } from '../../../react-common/reduxUtils'; import { IntellisenseProvider } from '../../intellisenseProvider'; import { initializeTokenizer, registerMonacoLanguage } from '../../tokenizer'; -import { createIncomingAction } from '../helpers'; +import { queueIncomingAction } from '../helpers'; import { CommonActionType, ICodeCreatedAction, IEditCellAction } from './types'; export interface IMonacoState { @@ -63,7 +63,7 @@ function finishTokenizer(buffer: ArrayBuffer, tmJson: string, arg: MonacoRedu if (e) { logMessage(`ERROR from onigasm: ${e}`); } - arg.queueAction(createIncomingAction(InteractiveWindowMessages.MonacoReady)); + queueIncomingAction(arg, InteractiveWindowMessages.MonacoReady); }).ignoreErrors(); } diff --git a/src/datascience-ui/interactive-common/redux/store.ts b/src/datascience-ui/interactive-common/redux/store.ts index df0bbb44ac53..c9936bb31df3 100644 --- a/src/datascience-ui/interactive-common/redux/store.ts +++ b/src/datascience-ui/interactive-common/redux/store.ts @@ -6,6 +6,7 @@ import * as Redux from 'redux'; import { createLogger } from 'redux-logger'; import { Identifiers } from '../../../client/datascience/constants'; import { InteractiveWindowMessages } from '../../../client/datascience/interactive-common/interactiveWindowTypes'; +import { MessageType } from '../../../client/datascience/interactive-common/synchronization'; import { BaseReduxActionPayload } from '../../../client/datascience/interactive-common/types'; import { CssMessages } from '../../../client/datascience/messages'; import { CellState } from '../../../client/datascience/types'; @@ -75,7 +76,11 @@ function createSendInfoMiddleware(): Redux.Middleware<{}, IStore> { const afterState = store.getState(); // If the action is part of a sync message, then do not send it to the extension. - if (action.payload && typeof (action.payload as BaseReduxActionPayload).messageType === 'number') { + const messageType = (action?.payload as BaseReduxActionPayload).messageType ?? MessageType.userAction; + const isSyncMessage = + (messageType & MessageType.syncAcrossSameNotebooks) === MessageType.syncAcrossSameNotebooks && + (messageType & MessageType.syncAcrossSameNotebooks) === MessageType.syncWithLiveShare; + if (isSyncMessage) { return res; } @@ -296,10 +301,14 @@ export function createStore(skipDefault: boolean, baseTheme: string, testMode if (isAllowedMessage(message)) { const basePayload: BaseReduxActionPayload = { data: payload }; if (message === InteractiveWindowMessages.Sync) { + // This is a message that has been sent from extension purely for synchronization purposes. // Unwrap the message. message = payload.type; - basePayload.messageType = payload.payload.messageType; + basePayload.messageType = payload.payload.messageType ?? MessageType.syncAcrossSameNotebooks; basePayload.data = payload.payload.data; + } else { + // Messages result of some user action. + basePayload.messageType = basePayload.messageType ?? MessageType.userAction; } store.dispatch({ type: message, payload: basePayload }); } diff --git a/src/datascience-ui/native-editor/redux/actions.ts b/src/datascience-ui/native-editor/redux/actions.ts index 3ec7682b9e1c..18e013a29f88 100644 --- a/src/datascience-ui/native-editor/redux/actions.ts +++ b/src/datascience-ui/native-editor/redux/actions.ts @@ -2,13 +2,13 @@ // Licensed under the MIT License. 'use strict'; import * as uuid from 'uuid/v4'; -import { InteractiveWindowMessages, NativeCommandType } from '../../../client/datascience/interactive-common/interactiveWindowTypes'; +import { IInteractiveWindowMapping, InteractiveWindowMessages, NativeCommandType } from '../../../client/datascience/interactive-common/interactiveWindowTypes'; import { IJupyterVariable, IJupyterVariablesRequest } from '../../../client/datascience/types'; import { CursorPos } from '../../interactive-common/mainState'; -import { createIncomingAction, createIncomingActionWithPayload } from '../../interactive-common/redux/helpers'; import { CommonAction, CommonActionType, + CommonActionTypeMapping, ICellAction, ICellAndCursorAction, ICodeAction, @@ -20,6 +20,16 @@ import { } from '../../interactive-common/redux/reducers/types'; import { IMonacoModelContentChangeEvent } from '../../react-common/monacoHelpers'; +// This function isn't made common and not exported, to ensure it isn't used elsewhere. +function createIncomingActionWithPayload(type: K, data: M[K]): CommonAction { + // tslint:disable-next-line: no-any + return { type, payload: { data, messageDirection: 'incoming' } as any } as any; +} +// This function isn't made common and not exported, to ensure it isn't used elsewhere. +function createIncomingAction(type: CommonActionType | InteractiveWindowMessages): CommonAction { + return { type, payload: { messageDirection: 'incoming', data: undefined } }; +} + // See https://react-redux.js.org/using-react-redux/connect-mapdispatch#defining-mapdispatchtoprops-as-an-object export const actionCreators = { addCell: () => createIncomingActionWithPayload(CommonActionType.ADD_AND_FOCUS_NEW_CELL, { newCellId: uuid() }), diff --git a/src/datascience-ui/native-editor/redux/reducers/creation.ts b/src/datascience-ui/native-editor/redux/reducers/creation.ts index 4f850d67fecc..d85978ddd788 100644 --- a/src/datascience-ui/native-editor/redux/reducers/creation.ts +++ b/src/datascience-ui/native-editor/redux/reducers/creation.ts @@ -6,7 +6,7 @@ import { noop } from '../../../../client/common/utils/misc'; import { IEditorContentChange, ILoadAllCells, NotebookModelChange } from '../../../../client/datascience/interactive-common/interactiveWindowTypes'; import { ICell, IDataScienceExtraSettings } from '../../../../client/datascience/types'; import { createCellVM, createEmptyCell, CursorPos, extractInputText, getSelectedAndFocusedInfo, ICellViewModel, IMainState } from '../../../interactive-common/mainState'; -import { createIncomingActionWithPayload } from '../../../interactive-common/redux/helpers'; +import { queueIncomingActionWithPayload } from '../../../interactive-common/redux/helpers'; import { Helpers } from '../../../interactive-common/redux/reducers/helpers'; import { Transfer } from '../../../interactive-common/redux/reducers/transfer'; import { CommonActionType, IAddCellAction, ICellAction } from '../../../interactive-common/redux/reducers/types'; @@ -41,26 +41,26 @@ export namespace Creation { } export function addAndFocusCell(arg: NativeEditorReducerArg): IMainState { - arg.queueAction(createIncomingActionWithPayload(CommonActionType.ADD_NEW_CELL, { newCellId: arg.payload.data.newCellId })); - arg.queueAction(createIncomingActionWithPayload(CommonActionType.FOCUS_CELL, { cellId: arg.payload.data.newCellId, cursorPos: CursorPos.Current })); + queueIncomingActionWithPayload(arg, CommonActionType.ADD_NEW_CELL, { newCellId: arg.payload.data.newCellId }); + queueIncomingActionWithPayload(arg, CommonActionType.FOCUS_CELL, { cellId: arg.payload.data.newCellId, cursorPos: CursorPos.Current }); return arg.prevState; } export function insertAboveAndFocusCell(arg: NativeEditorReducerArg): IMainState { - arg.queueAction(createIncomingActionWithPayload(CommonActionType.INSERT_ABOVE, { cellId: arg.payload.data.cellId, newCellId: arg.payload.data.newCellId })); - arg.queueAction(createIncomingActionWithPayload(CommonActionType.FOCUS_CELL, { cellId: arg.payload.data.newCellId, cursorPos: CursorPos.Current })); + queueIncomingActionWithPayload(arg, CommonActionType.INSERT_ABOVE, { cellId: arg.payload.data.cellId, newCellId: arg.payload.data.newCellId }); + queueIncomingActionWithPayload(arg, CommonActionType.FOCUS_CELL, { cellId: arg.payload.data.newCellId, cursorPos: CursorPos.Current }); return arg.prevState; } export function insertBelowAndFocusCell(arg: NativeEditorReducerArg): IMainState { - arg.queueAction(createIncomingActionWithPayload(CommonActionType.INSERT_BELOW, { cellId: arg.payload.data.cellId, newCellId: arg.payload.data.newCellId })); - arg.queueAction(createIncomingActionWithPayload(CommonActionType.FOCUS_CELL, { cellId: arg.payload.data.newCellId, cursorPos: CursorPos.Current })); + queueIncomingActionWithPayload(arg, CommonActionType.INSERT_BELOW, { cellId: arg.payload.data.cellId, newCellId: arg.payload.data.newCellId }); + queueIncomingActionWithPayload(arg, CommonActionType.FOCUS_CELL, { cellId: arg.payload.data.newCellId, cursorPos: CursorPos.Current }); return arg.prevState; } export function insertAboveFirstAndFocusCell(arg: NativeEditorReducerArg): IMainState { - arg.queueAction(createIncomingActionWithPayload(CommonActionType.INSERT_ABOVE_FIRST, { newCellId: arg.payload.data.newCellId })); - arg.queueAction(createIncomingActionWithPayload(CommonActionType.FOCUS_CELL, { cellId: arg.payload.data.newCellId, cursorPos: CursorPos.Current })); + queueIncomingActionWithPayload(arg, CommonActionType.INSERT_ABOVE_FIRST, { newCellId: arg.payload.data.newCellId }); + queueIncomingActionWithPayload(arg, CommonActionType.FOCUS_CELL, { cellId: arg.payload.data.newCellId, cursorPos: CursorPos.Current }); return arg.prevState; } diff --git a/src/datascience-ui/native-editor/redux/reducers/execution.ts b/src/datascience-ui/native-editor/redux/reducers/execution.ts index f8d502613c69..2eb94ab6d993 100644 --- a/src/datascience-ui/native-editor/redux/reducers/execution.ts +++ b/src/datascience-ui/native-editor/redux/reducers/execution.ts @@ -10,7 +10,7 @@ import { CellState } from '../../../../client/datascience/types'; import { concatMultilineStringInput } from '../../../common'; import { createCellFrom } from '../../../common/cellFactory'; import { CursorPos, getSelectedAndFocusedInfo, ICellViewModel, IMainState } from '../../../interactive-common/mainState'; -import { createIncomingActionWithPayload, postActionToExtension } from '../../../interactive-common/redux/helpers'; +import { postActionToExtension, queueIncomingActionWithPayload } from '../../../interactive-common/redux/helpers'; import { Helpers } from '../../../interactive-common/redux/reducers/helpers'; import { Transfer } from '../../../interactive-common/redux/reducers/transfer'; import { CommonActionType, ICellAction, IChangeCellTypeAction, ICodeAction, IExecuteAction } from '../../../interactive-common/redux/reducers/types'; @@ -64,13 +64,11 @@ export namespace Execution { } export function executeCellAndAdvance(arg: NativeEditorReducerArg): IMainState { - arg.queueAction( - createIncomingActionWithPayload(CommonActionType.EXECUTE_CELL, { cellId: arg.payload.data.cellId, code: arg.payload.data.code, moveOp: arg.payload.data.moveOp }) - ); + queueIncomingActionWithPayload(arg, CommonActionType.EXECUTE_CELL, { cellId: arg.payload.data.cellId, code: arg.payload.data.code, moveOp: arg.payload.data.moveOp }); if (arg.payload.data.moveOp === 'add') { const newCellId = uuid(); - arg.queueAction(createIncomingActionWithPayload(CommonActionType.INSERT_BELOW, { cellId: arg.payload.data.cellId, newCellId })); - arg.queueAction(createIncomingActionWithPayload(CommonActionType.FOCUS_CELL, { cellId: newCellId, cursorPos: CursorPos.Current })); + queueIncomingActionWithPayload(arg, CommonActionType.INSERT_BELOW, { cellId: arg.payload.data.cellId, newCellId }); + queueIncomingActionWithPayload(arg, CommonActionType.FOCUS_CELL, { cellId: newCellId, cursorPos: CursorPos.Current }); } return arg.prevState; } diff --git a/src/datascience-ui/native-editor/redux/reducers/movement.ts b/src/datascience-ui/native-editor/redux/reducers/movement.ts index ccb1323905b1..df86f3e268ef 100644 --- a/src/datascience-ui/native-editor/redux/reducers/movement.ts +++ b/src/datascience-ui/native-editor/redux/reducers/movement.ts @@ -2,7 +2,7 @@ // Licensed under the MIT License. 'use strict'; import { CursorPos, IMainState } from '../../../interactive-common/mainState'; -import { createIncomingActionWithPayload } from '../../../interactive-common/redux/helpers'; +import { queueIncomingActionWithPayload } from '../../../interactive-common/redux/helpers'; import { Helpers } from '../../../interactive-common/redux/reducers/helpers'; import { Transfer } from '../../../interactive-common/redux/reducers/transfer'; import { CommonActionType, ICellAction, ICodeAction } from '../../../interactive-common/redux/reducers/types'; @@ -50,7 +50,7 @@ export namespace Movement { export function arrowUp(arg: NativeEditorReducerArg): IMainState { const index = arg.prevState.cellVMs.findIndex(c => c.cell.id === arg.payload.data.cellId); if (index > 0) { - arg.queueAction(createIncomingActionWithPayload(CommonActionType.SELECT_CELL, { cellId: arg.prevState.cellVMs[index - 1].cell.id, cursorPos: CursorPos.Bottom })); + queueIncomingActionWithPayload(arg, CommonActionType.SELECT_CELL, { cellId: arg.prevState.cellVMs[index - 1].cell.id, cursorPos: CursorPos.Bottom }); } return arg.prevState; @@ -59,7 +59,7 @@ export namespace Movement { export function arrowDown(arg: NativeEditorReducerArg): IMainState { const index = arg.prevState.cellVMs.findIndex(c => c.cell.id === arg.payload.data.cellId); if (index < arg.prevState.cellVMs.length - 1) { - arg.queueAction(createIncomingActionWithPayload(CommonActionType.SELECT_CELL, { cellId: arg.prevState.cellVMs[index + 1].cell.id, cursorPos: CursorPos.Bottom })); + queueIncomingActionWithPayload(arg, CommonActionType.SELECT_CELL, { cellId: arg.prevState.cellVMs[index + 1].cell.id, cursorPos: CursorPos.Bottom }); } return arg.prevState;