1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Moved more widgets to redux

This commit is contained in:
Laurent Cozic 2017-10-07 23:17:10 +01:00
parent 6f34d717f8
commit dc219141fa
10 changed files with 153 additions and 37 deletions

View File

@ -19,6 +19,7 @@ const RootWidget = require('tkwidgets/RootWidget.js');
const WindowWidget = require('tkwidgets/WindowWidget.js'); const WindowWidget = require('tkwidgets/WindowWidget.js');
const NoteWidget = require('./gui/NoteWidget.js'); const NoteWidget = require('./gui/NoteWidget.js');
const FolderListWidget = require('./gui/FolderListWidget.js');
class AppGui { class AppGui {
@ -50,20 +51,22 @@ class AppGui {
this.rootWidget_ = new ReduxRootWidget(this.store_); this.rootWidget_ = new ReduxRootWidget(this.store_);
this.rootWidget_.setName('rootWidget'); this.rootWidget_.setName('rootWidget');
const folderList = new ListWidget(); const folderList = new FolderListWidget();
folderList.items = []; folderList.setStyle({ borderBottomWidth: 1 });
folderList.setItemRenderer((item) => {
return item.title;
});
folderList.setStyle({
borderBottomWidth: 1,
});
folderList.setName('folderList'); folderList.setName('folderList');
folderList.setVStretch(true); folderList.setVStretch(true);
folderList.on('currentItemChange', async () => { folderList.on('currentItemChange', async () => {
const folder = folderList.currentItem; const folder = folderList.currentItem;
this.app().switchCurrentFolder(folder); this.store_.dispatch({
await this.updateNoteList(folder ? folder.id : null); type: 'FOLDERS_SELECT',
folderId: folder ? folder.id : 0,
});
});
this.rootWidget_.connect(folderList, (state) => {
return {
selectedFolderId: state.selectedFolderId,
items: state.folders,
};
}); });
const noteList = new ListWidget(); const noteList = new ListWidget();
@ -84,27 +87,22 @@ class AppGui {
}); });
noteList.on('currentItemChange', async () => { noteList.on('currentItemChange', async () => {
let note = noteList.currentItem; let note = noteList.currentItem;
if (note) {
if (!('body' in note)) {
note = await Note.load(note.id);
}
noteList.setCurrentItem(note);
}
this.store_.dispatch({ this.store_.dispatch({
type: 'NOTES_SELECT', type: 'NOTES_SELECT',
noteId: note ? note.id : 0, noteId: note ? note.id : 0,
}); });
//await this.updateNoteText(note); });
this.rootWidget_.connect(noteList, (state) => {
return {
selectedNoteId: state.selectedNoteId,
items: state.notes,
};
}); });
const noteText = new NoteWidget(); const noteText = new NoteWidget();
noteText.setVStretch(true); noteText.setVStretch(true);
noteText.setName('noteText'); noteText.setName('noteText');
noteText.setStyle({ noteText.setStyle({ borderBottomWidth: 1 });
borderBottomWidth: 1,
});
this.rootWidget_.connect(noteText, (state) => { this.rootWidget_.connect(noteText, (state) => {
return { noteId: state.selectedNoteId }; return { noteId: state.selectedNoteId };
}); });
@ -265,7 +263,7 @@ class AppGui {
const consoleWidget = this.widget('console'); const consoleWidget = this.widget('console');
await this.updateFolderList(); //await this.updateFolderList();
term.grabInput(); term.grabInput();
@ -295,6 +293,13 @@ class AppGui {
termutils.showCursor(term); termutils.showCursor(term);
console.error(error); console.error(error);
} }
process.on('unhandledRejection', (reason, p) => {
term.fullscreen(false);
termutils.showCursor(term);
console.error('Unhandled promise rejection', p, 'reason:', reason);
process.exit(1);
});
} }
} }

View File

@ -1,7 +1,8 @@
import { createStore } from 'redux'; import { createStore, applyMiddleware } from 'redux';
import { reducer, defaultState } from 'lib/reducer.js'; import { reducer, defaultState } from 'lib/reducer.js';
import { JoplinDatabase } from 'lib/joplin-database.js'; import { JoplinDatabase } from 'lib/joplin-database.js';
import { Database } from 'lib/database.js'; import { Database } from 'lib/database.js';
import { FoldersScreenUtils } from 'lib/folders-screen-utils.js';
import { DatabaseDriverNode } from 'lib/database-driver-node.js'; import { DatabaseDriverNode } from 'lib/database-driver-node.js';
import { BaseModel } from 'lib/base-model.js'; import { BaseModel } from 'lib/base-model.js';
import { Folder } from 'lib/models/folder.js'; import { Folder } from 'lib/models/folder.js';
@ -40,6 +41,10 @@ class Application {
return this.logger_; return this.logger_;
} }
store() {
return this.store_;
}
currentFolder() { currentFolder() {
return this.currentFolder_; return this.currentFolder_;
} }
@ -369,6 +374,45 @@ class Application {
return this.activeCommand_; return this.activeCommand_;
} }
async refreshNotes() {
const state = this.store().getState();
let options = {
order: state.notesOrder,
uncompletedTodosOnTop: Setting.value('uncompletedTodosOnTop'),
};
const notes = await Note.previews(state.selectedFolderId, options);
this.store().dispatch({
type: 'NOTES_UPDATE_ALL',
notes: notes,
});
this.store().dispatch({
type: 'NOTES_SELECT',
noteId: notes.length ? notes[0].id : null,
});
}
generalMiddleware() {
const middleware = store => next => async (action) => {
this.logger().info('Middleware reducer action', action.type);
const result = next(action);
const newState = store.getState();
if (action.type == 'FOLDERS_SELECT') {
Setting.setValue('activeFolderId', newState.selectedFolderId);
await this.refreshNotes();
}
return result;
}
return middleware;
}
async start() { async start() {
let argv = process.argv; let argv = process.argv;
let startFlags = await this.handleStartFlags_(argv); let startFlags = await this.handleStartFlags_(argv);
@ -406,6 +450,10 @@ class Application {
this.dbLogger_.addTarget('file', { path: profileDir + '/log-database.txt' }); this.dbLogger_.addTarget('file', { path: profileDir + '/log-database.txt' });
this.dbLogger_.setLevel(initArgs.logLevel); this.dbLogger_.setLevel(initArgs.logLevel);
if (Setting.value('env') === 'dev') {
this.dbLogger_.setLevel(Logger.LEVEL_WARN);
}
const packageJson = require('./package.json'); const packageJson = require('./package.json');
this.logger_.info(sprintf('Starting %s %s (%s)...', packageJson.name, packageJson.version, Setting.value('env'))); this.logger_.info(sprintf('Starting %s %s (%s)...', packageJson.name, packageJson.version, Setting.value('env')));
this.logger_.info('Profile directory: ' + profileDir); this.logger_.info('Profile directory: ' + profileDir);
@ -417,7 +465,6 @@ class Application {
reg.setDb(this.database_); reg.setDb(this.database_);
BaseModel.db_ = this.database_; BaseModel.db_ = this.database_;
//BaseModel.dispatch = (action) => { this.baseModelListener(action) }
await Setting.load(); await Setting.load();
@ -439,14 +486,22 @@ class Application {
if (!this.currentFolder_) this.currentFolder_ = await Folder.defaultFolder(); if (!this.currentFolder_) this.currentFolder_ = await Folder.defaultFolder();
Setting.setValue('activeFolderId', this.currentFolder_ ? this.currentFolder_.id : ''); Setting.setValue('activeFolderId', this.currentFolder_ ? this.currentFolder_.id : '');
let store = createStore(reducer); this.store_ = createStore(reducer, applyMiddleware(this.generalMiddleware()));
BaseModel.dispatch = store.dispatch; BaseModel.dispatch = this.store().dispatch;
FoldersScreenUtils.dispatch = this.store().dispatch;
const AppGui = require('./app-gui.js'); const AppGui = require('./app-gui.js');
this.gui_ = new AppGui(this, store); this.gui_ = new AppGui(this, this.store());
this.gui_.setLogger(this.logger_); this.gui_.setLogger(this.logger_);
await this.gui_.start(); await this.gui_.start();
await FoldersScreenUtils.refreshFolders();
this.store().dispatch({
type: 'FOLDERS_SELECT',
folderId: Setting.value('activeFolderId'),
});
// if (this.autocompletion_.active) { // if (this.autocompletion_.active) {
// if (this.autocompletion_.install) { // if (this.autocompletion_.install) {
// try { // try {

View File

@ -0,0 +1,28 @@
const Folder = require('lib/models/folder.js').Folder;
const ListWidget = require('tkwidgets/ListWidget.js');
class FolderListWidget extends ListWidget {
constructor() {
super();
this.selectedFolderId_ = 0;
this.setItemRenderer((item) => {
return item.title;
});
}
get selectedFolderId() {
return this.selectedFolderId_;
}
set selectedFolderId(v) {
if (v === this.selectedFolderId_) return;
this.selectedFolderId_ = v;
const index = this.itemIndexByKey('id', this.selectedFolderId_);
this.currentIndex = index >= 0 ? index : 0;
}
}
module.exports = FolderListWidget;

View File

@ -0,0 +1,27 @@
const Note = require('lib/models/note.js').Note;
const ListWidget = require('tkwidgets/ListWidget.js');
class NoteListWidget extends ListWidget {
constructor() {
super();
this.selectedNoteId_ = 0;
this.setItemRenderer((item) => {
return item.title;
});
}
get selectedNoteId() {
return this.selectedNoteId_;
}
set selectedNoteId(v) {
if (v === this.selectedNoteId_) return;
this.selectedNoteId_ = v;
const index = this.itemIndexByKey('id', this.selectedNoteId_);
this.currentIndex = index >= 0 ? index : 0;
}
}
module.exports = NoteListWidget;

View File

@ -1,5 +1,3 @@
//import { Note } from 'lib/models/note.js';
const Note = require('lib/models/note.js').Note; const Note = require('lib/models/note.js').Note;
const TextWidget = require('tkwidgets/TextWidget.js'); const TextWidget = require('tkwidgets/TextWidget.js');
@ -25,7 +23,7 @@ class NoteWidget extends TextWidget {
async willRender() { async willRender() {
if (!this.note_ && this.noteId_) { if (!this.note_ && this.noteId_) {
this.note_ = await Note.load(this.noteId_); this.note_ = await Note.load(this.noteId_);
this.text = this.note_.body; this.text = this.note_.title + "\n\n" + this.note_.body;
} }
} }

View File

@ -19,10 +19,6 @@ import { FsDriverNode } from './fs-driver-node.js';
import { shimInit } from 'lib/shim-init-node.js'; import { shimInit } from 'lib/shim-init-node.js';
import { _ } from 'lib/locale.js'; import { _ } from 'lib/locale.js';
process.on('unhandledRejection', (reason, p) => {
console.error('Unhandled promise rejection', p, 'reason:', reason);
});
const fsDriver = new FsDriverNode(); const fsDriver = new FsDriverNode();
Logger.fsDriver_ = fsDriver; Logger.fsDriver_ = fsDriver;
Resource.fsDriver_ = fsDriver; Resource.fsDriver_ = fsDriver;

View File

@ -6,7 +6,7 @@ import { Log } from 'lib/log.js';
import { Tag } from 'lib/models/tag.js'; import { Tag } from 'lib/models/tag.js';
import { Note } from 'lib/models/note.js'; import { Note } from 'lib/models/note.js';
import { Setting } from 'lib/models/setting.js'; import { Setting } from 'lib/models/setting.js';
import { FoldersScreenUtils } from 'lib/components/screens/folders-utils.js' import { FoldersScreenUtils } from 'lib/folders-screen-utils.js'
import { Synchronizer } from 'lib/synchronizer.js'; import { Synchronizer } from 'lib/synchronizer.js';
import { reg } from 'lib/registry.js'; import { reg } from 'lib/registry.js';
import { _ } from 'lib/locale.js'; import { _ } from 'lib/locale.js';

View File

@ -4,6 +4,7 @@ class FoldersScreenUtils {
static async refreshFolders() { static async refreshFolders() {
let initialFolders = await Folder.all({ includeConflictFolder: true }); let initialFolders = await Folder.all({ includeConflictFolder: true });
this.dispatch({ this.dispatch({
type: 'FOLDERS_UPDATE_ALL', type: 'FOLDERS_UPDATE_ALL',
folders: initialFolders, folders: initialFolders,

View File

@ -124,6 +124,12 @@ const reducer = (state = defaultState, action) => {
newState.selectedNoteId = action.noteId; newState.selectedNoteId = action.noteId;
break; break;
case 'FOLDERS_SELECT':
newState = Object.assign({}, state);
newState.selectedFolderId = action.folderId;
break;
case 'SETTINGS_UPDATE_ALL': case 'SETTINGS_UPDATE_ALL':
newState = Object.assign({}, state); newState = Object.assign({}, state);

View File

@ -9,7 +9,7 @@ import { AppNav } from 'lib/components/app-nav.js'
import { Logger } from 'lib/logger.js' import { Logger } from 'lib/logger.js'
import { Note } from 'lib/models/note.js' import { Note } from 'lib/models/note.js'
import { Folder } from 'lib/models/folder.js' import { Folder } from 'lib/models/folder.js'
import { FoldersScreenUtils } from 'lib/components/screens/folders-utils.js'; import { FoldersScreenUtils } from 'lib/folders-screen-utils.js';
import { Resource } from 'lib/models/resource.js' import { Resource } from 'lib/models/resource.js'
import { Tag } from 'lib/models/tag.js' import { Tag } from 'lib/models/tag.js'
import { NoteTag } from 'lib/models/note-tag.js' import { NoteTag } from 'lib/models/note-tag.js'