From 6f34d717f89f114d951686c680ffd0134e04c9ab Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Sat, 7 Oct 2017 22:01:03 +0100 Subject: [PATCH] Switching state handling to Redux --- CliClient/.gitignore | 3 ++- CliClient/app/app-gui.js | 30 +++++++++++++++++++--------- CliClient/app/app.js | 9 +++++++-- CliClient/app/gui/NoteWidget.js | 34 ++++++++++++++++++++++++++++++++ CliClient/build.sh | 4 ++++ ReactNativeClient/lib/reducer.js | 6 ++++++ 6 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 CliClient/app/gui/NoteWidget.js diff --git a/CliClient/.gitignore b/CliClient/.gitignore index faab3d6fa..1508cba48 100644 --- a/CliClient/.gitignore +++ b/CliClient/.gitignore @@ -16,4 +16,5 @@ tests/cli-integration/ *.mo *.*~ tests/sync -out.txt \ No newline at end of file +out.txt +linkToLocal.sh \ No newline at end of file diff --git a/CliClient/app/app-gui.js b/CliClient/app/app-gui.js index 3a5d779d7..51857ba21 100644 --- a/CliClient/app/app-gui.js +++ b/CliClient/app/app-gui.js @@ -14,20 +14,25 @@ const TextWidget = require('tkwidgets/TextWidget.js'); const ConsoleWidget = require('tkwidgets/ConsoleWidget.js'); const HLayoutWidget = require('tkwidgets/HLayoutWidget.js'); const VLayoutWidget = require('tkwidgets/VLayoutWidget.js'); +const ReduxRootWidget = require('tkwidgets/ReduxRootWidget.js'); const RootWidget = require('tkwidgets/RootWidget.js'); const WindowWidget = require('tkwidgets/WindowWidget.js'); +const NoteWidget = require('./gui/NoteWidget.js'); + class AppGui { - constructor(app) { + constructor(app, store) { this.app_ = app; + this.store_ = store; BaseWidget.setLogger(app.logger()); this.term_ = tk.terminal; this.renderer_ = null; this.logger_ = new Logger(); - this.rootWidget_ = this.buildUi(); + this.buildUi(); + this.renderer_ = new Renderer(this.term(), this.rootWidget_); this.renderer_.on('renderDone', async (event) => { @@ -42,8 +47,8 @@ class AppGui { } buildUi() { - const rootWidget = new RootWidget(); - rootWidget.setName('rootWidget'); + this.rootWidget_ = new ReduxRootWidget(this.store_); + this.rootWidget_.setName('rootWidget'); const folderList = new ListWidget(); folderList.items = []; @@ -85,16 +90,25 @@ class AppGui { } noteList.setCurrentItem(note); } - await this.updateNoteText(note); + + this.store_.dispatch({ + type: 'NOTES_SELECT', + noteId: note ? note.id : 0, + }); + //await this.updateNoteText(note); }); - const noteText = new TextWidget(); + const noteText = new NoteWidget(); noteText.setVStretch(true); noteText.setName('noteText'); noteText.setStyle({ borderBottomWidth: 1, }); + this.rootWidget_.connect(noteText, (state) => { + return { noteId: state.selectedNoteId }; + }); + const consoleWidget = new ConsoleWidget(); consoleWidget.setHStretch(true); consoleWidget.setName('console'); @@ -117,9 +131,7 @@ class AppGui { win1.addChild(vLayout); win1.setName('mainWindow'); - rootWidget.addChild(win1); - - return rootWidget; + this.rootWidget_.addChild(win1); } setupShortcuts() { diff --git a/CliClient/app/app.js b/CliClient/app/app.js index 665e6ef7f..8ac0bf6c8 100644 --- a/CliClient/app/app.js +++ b/CliClient/app/app.js @@ -1,3 +1,5 @@ +import { createStore } from 'redux'; +import { reducer, defaultState } from 'lib/reducer.js'; import { JoplinDatabase } from 'lib/joplin-database.js'; import { Database } from 'lib/database.js'; import { DatabaseDriverNode } from 'lib/database-driver-node.js'; @@ -415,7 +417,7 @@ class Application { reg.setDb(this.database_); BaseModel.db_ = this.database_; - BaseModel.dispatch = (action) => { this.baseModelListener(action) } + //BaseModel.dispatch = (action) => { this.baseModelListener(action) } await Setting.load(); @@ -437,8 +439,11 @@ class Application { if (!this.currentFolder_) this.currentFolder_ = await Folder.defaultFolder(); Setting.setValue('activeFolderId', this.currentFolder_ ? this.currentFolder_.id : ''); + let store = createStore(reducer); + BaseModel.dispatch = store.dispatch; + const AppGui = require('./app-gui.js'); - this.gui_ = new AppGui(this); + this.gui_ = new AppGui(this, store); this.gui_.setLogger(this.logger_); await this.gui_.start(); diff --git a/CliClient/app/gui/NoteWidget.js b/CliClient/app/gui/NoteWidget.js new file mode 100644 index 000000000..8dab0b708 --- /dev/null +++ b/CliClient/app/gui/NoteWidget.js @@ -0,0 +1,34 @@ +//import { Note } from 'lib/models/note.js'; + +const Note = require('lib/models/note.js').Note; +const TextWidget = require('tkwidgets/TextWidget.js'); + +class NoteWidget extends TextWidget { + + constructor() { + super(); + this.noteId_ = 0; + this.note_ = null; + } + + get noteId() { + return this.noteId_; + } + + set noteId(v) { + if (v === this.noteId_) return; + this.noteId_ = v; + this.note_ = null; + this.invalidate(); + } + + async willRender() { + if (!this.note_ && this.noteId_) { + this.note_ = await Note.load(this.noteId_); + this.text = this.note_.body; + } + } + +} + +module.exports = NoteWidget; \ No newline at end of file diff --git a/CliClient/build.sh b/CliClient/build.sh index cf6a07898..b33dac7d5 100755 --- a/CliClient/build.sh +++ b/CliClient/build.sh @@ -10,6 +10,10 @@ ln -s "$ROOT_DIR/../ReactNativeClient/lib" "$ROOT_DIR/app" npm run build +# Files under app/gui are in ES6 already but I cannot get Babel +# to ignore them, so copy them back to the build directory. +rsync -a "$ROOT_DIR/app/gui/" "$ROOT_DIR/build/gui/" + cp "$ROOT_DIR/package.json" "$ROOT_DIR/build" cp "$ROOT_DIR/app/autocompletion_template.txt" "$ROOT_DIR/build" diff --git a/ReactNativeClient/lib/reducer.js b/ReactNativeClient/lib/reducer.js index 05d75e719..9d8a825eb 100644 --- a/ReactNativeClient/lib/reducer.js +++ b/ReactNativeClient/lib/reducer.js @@ -118,6 +118,12 @@ const reducer = (state = defaultState, action) => { newState.historyCanGoBack = !!navHistory.length; break; + case 'NOTES_SELECT': + + newState = Object.assign({}, state); + newState.selectedNoteId = action.noteId; + break; + case 'SETTINGS_UPDATE_ALL': newState = Object.assign({}, state);