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:
parent
6f34d717f8
commit
dc219141fa
@ -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);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
28
CliClient/app/gui/FolderListWidget.js
Normal file
28
CliClient/app/gui/FolderListWidget.js
Normal 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;
|
27
CliClient/app/gui/NoteListWidget.js
Normal file
27
CliClient/app/gui/NoteListWidget.js
Normal 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;
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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';
|
||||||
|
@ -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,
|
@ -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);
|
||||||
|
@ -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'
|
||||||
|
Loading…
Reference in New Issue
Block a user