From 3eac7d384f514bfee9d8fb415b15e9662da60d2e Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sat, 26 Mar 2022 11:49:23 -0500 Subject: [PATCH] fileStorage/sagas: remove editor init from fileStorage This is still a bit of a hack but is one step towards being able to remove the 'editor' context. --- src/editor/sagas.ts | 58 ++++++++++++++++++++++++++++++++++++++++ src/fileStorage/sagas.ts | 17 +----------- src/sagas.ts | 2 ++ 3 files changed, 61 insertions(+), 16 deletions(-) create mode 100644 src/editor/sagas.ts diff --git a/src/editor/sagas.ts b/src/editor/sagas.ts new file mode 100644 index 00000000..ba2596ad --- /dev/null +++ b/src/editor/sagas.ts @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2022 The Pybricks Authors + +import { monaco } from 'react-monaco-editor'; +import { eventChannel } from 'redux-saga'; +import { fork, put, race, select, take, takeEvery } from 'typed-redux-saga/macro'; +import { + fileStorageDidFailToReadFile, + fileStorageDidInitialize, + fileStorageDidReadFile, + fileStorageReadFile, +} from '../fileStorage/actions'; +import { RootState } from '../reducers'; + +function* handleDidCreateEditor(editor: monaco.editor.ICodeEditor): Generator { + // first, we need to be sure that file storage is ready + + const isFileStorageInitialized = yield* select( + (s: RootState) => s.fileStorage.isInitialized, + ); + + if (!isFileStorageInitialized) { + yield* take(fileStorageDidInitialize); + } + + // then we can load the most recently used file + // REVISIT: should this be here or elsewhere? + + yield* put(fileStorageReadFile('main.py')); + + const { succeeded } = yield* race({ + succeeded: take(fileStorageDidReadFile.when((a) => a.fileName === 'main.py')), + failed: take( + fileStorageDidFailToReadFile.when((a) => a.fileName === 'main.py'), + ), + }); + + // TODO: what to do in case of failure? + + if (succeeded) { + editor.setValue(succeeded.fileContents); + } + + // TODO: subscribe to actions that act on the editor +} + +function* monitorEditors(): Generator { + const ch = eventChannel((emit) => { + const subscription = monaco.editor.onDidCreateEditor(emit); + return () => subscription.dispose(); + }); + + yield* takeEvery(ch, handleDidCreateEditor); +} + +export default function* (): Generator { + yield* fork(monitorEditors); +} diff --git a/src/fileStorage/sagas.ts b/src/fileStorage/sagas.ts index b042db2e..5b643d39 100644 --- a/src/fileStorage/sagas.ts +++ b/src/fileStorage/sagas.ts @@ -6,9 +6,8 @@ import JSZip from 'jszip'; import localForage from 'localforage'; import { extendPrototype } from 'localforage-observable'; import { eventChannel } from 'redux-saga'; -import { call, fork, getContext, put, takeEvery } from 'typed-redux-saga/macro'; +import { call, fork, put, takeEvery } from 'typed-redux-saga/macro'; import Observable from 'zen-observable'; -import { EditorType } from '../editor/Editor'; import { pythonFileExtension, pythonFileMimeType } from '../pybricksMicropython/lib'; import { ensureError, timestamp } from '../utils'; import { @@ -269,20 +268,6 @@ function* initialize(): Generator { const fileNames = yield* call(() => files.keys()); - // TODO: we should not be loading main.py here - // HACK: This assumes that editor is loaded before storage! - const editor = yield* getContext('editor'); - - if (editor) { - const main = yield* call(() => files.getItem('main.py')); - - if (main) { - editor.setValue(main); - } - } else if (process.env.NODE_ENV !== 'test') { - console.error('editor was not loaded, so main.py was not loaded'); - } - yield* put(fileStorageDidInitialize(fileNames)); } catch (err) { yield* put(fileStorageDidFailToInitialize(ensureError(err))); diff --git a/src/sagas.ts b/src/sagas.ts index 7d9aef2c..aed961d2 100644 --- a/src/sagas.ts +++ b/src/sagas.ts @@ -7,6 +7,7 @@ import app from './app/sagas'; import blePybricksService from './ble-pybricks-service/sagas'; import ble from './ble/sagas'; import { EditorType } from './editor/Editor'; +import editor from './editor/sagas'; import errorLog from './error-log/sagas'; import explorer from './explorer/sagas'; import fileStorage from './fileStorage/sagas'; @@ -24,6 +25,7 @@ export default function* (): Generator { app(), blePybricksService(), ble(), + editor(), fileStorage(), lwp3BootloaderBle(), lwp3BootloaderProtocol(),