1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-08-13 22:12:50 +02:00

More clean up

This commit is contained in:
Laurent Cozic
2017-06-24 19:11:19 +01:00
parent 58791b1963
commit 03c9d55397
11 changed files with 28 additions and 344 deletions

View File

@@ -2,7 +2,6 @@ import React, { Component } from 'react';
import { View, Button, TextInput, Text } from 'react-native'; import { View, Button, TextInput, Text } from 'react-native';
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { Log } from 'lib/log.js' import { Log } from 'lib/log.js'
import { Registry } from 'lib/registry.js';
import { Setting } from 'lib/models/setting.js'; import { Setting } from 'lib/models/setting.js';
import { ScreenHeader } from 'lib/components/screen-header.js'; import { ScreenHeader } from 'lib/components/screen-header.js';
import { _ } from 'lib/locale.js'; import { _ } from 'lib/locale.js';
@@ -37,34 +36,34 @@ class LoginScreenComponent extends React.Component {
loginButton_press() { loginButton_press() {
this.setState({ errorMessage: null }); this.setState({ errorMessage: null });
return Registry.api().post('sessions', null, { // return Registry.api().post('sessions', null, {
'email': this.state.email, // 'email': this.state.email,
'password': this.state.password, // 'password': this.state.password,
'client_id': Setting.value('clientId'), // 'client_id': Setting.value('clientId'),
}).then((session) => { // }).then((session) => {
Log.info('Got session', session); // Log.info('Got session', session);
let user = { // let user = {
email: this.state.email, // email: this.state.email,
session: session.id, // session: session.id,
}; // };
Setting.setObject('user', user); // Setting.setObject('user', user);
this.props.dispatch({ // this.props.dispatch({
type: 'USER_SET', // type: 'USER_SET',
user: user, // user: user,
}); // });
this.props.dispatch({ // this.props.dispatch({
type: 'Navigation/BACK', // type: 'Navigation/BACK',
}); // });
Registry.api().setSession(session.id); // Registry.api().setSession(session.id);
//Registry.synchronizer().start(); // //Registry.synchronizer().start();
}).catch((error) => { // }).catch((error) => {
this.setState({ errorMessage: _('Could not login: %s)', error.message) }); // this.setState({ errorMessage: _('Could not login: %s)', error.message) });
}); // });
} }
render() { render() {

View File

@@ -3,7 +3,6 @@ import { View, Button, TextInput } from 'react-native';
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { Log } from 'lib/log.js' import { Log } from 'lib/log.js'
import { Note } from 'lib/models/note.js' import { Note } from 'lib/models/note.js'
import { Registry } from 'lib/registry.js'
import { ScreenHeader } from 'lib/components/screen-header.js'; import { ScreenHeader } from 'lib/components/screen-header.js';
import { Checkbox } from 'lib/components/checkbox.js' import { Checkbox } from 'lib/components/checkbox.js'
import { NoteFolderService } from 'lib/services/note-folder-service.js'; import { NoteFolderService } from 'lib/services/note-folder-service.js';

View File

@@ -1,7 +0,0 @@
function isNode() {
if (typeof process === 'undefined') return false;
if (!process.release) return false;
return process.release.name === 'node';
}
export { isNode };

View File

@@ -9,12 +9,9 @@
import { AppRegistry } from 'react-native'; import { AppRegistry } from 'react-native';
import { Log } from 'lib/log.js' import { Log } from 'lib/log.js'
import { Root } from 'lib/root.js'; import { Root } from 'lib/root.js';
import { Registry } from 'lib/registry.js';
function main() { function main() {
Registry.setDebugMode(true);
AppRegistry.registerComponent('AwesomeProject', () => Root); AppRegistry.registerComponent('AwesomeProject', () => Root);
Log.setLevel(Registry.debugMode() ? Log.LEVEL_DEBUG : Log.LEVEL_WARN);
console.ignoredYellowBox = ['Remote debugger']; console.ignoredYellowBox = ['Remote debugger'];
Log.info('START ======================================================================================================'); Log.info('START ======================================================================================================');
// Note: The final part of the initialization process is in // Note: The final part of the initialization process is in

View File

@@ -1,47 +0,0 @@
// Stores global dynamic objects that are not state but that are required
// throughout the application. Dependency injection would be a better solution
// but more complex and YAGNI at this point. However classes that make use of the
// registry should be designed in such a way that they can be converted to use
// dependency injection later on (eg. `BaseModel.db()`, `Synchroniser.api()`)
import { Database } from 'lib/database.js'
import { WebApi } from 'lib/web-api.js'
class Registry {
static setDebugMode(v) {
this.debugMode_ = v;
}
static debugMode() {
if (this.debugMode_ === undefined) return false;
return this.debugMode_;
}
static api() {
if (this.api_) return this.api_;
this.api_ = new WebApi('http://192.168.1.3');
return this.api_;
}
static setDb(v) {
this.db_ = v;
}
static db() {
if (!this.db_) throw new Error('Accessing database before it has been initialised');
return this.db_;
}
static setSynchronizer(s) {
this.synchronizer_ = s;
}
static synchronizer() {
if (!this.synchronizer_) throw new Error('Accessing synchronizer before it has been initialised');
return this.synchronizer_;
}
}
export { Registry };

View File

@@ -11,7 +11,6 @@ import { Note } from 'lib/models/note.js'
import { Folder } from 'lib/models/folder.js' import { Folder } from 'lib/models/folder.js'
import { BaseModel } from 'lib/base-model.js' import { BaseModel } from 'lib/base-model.js'
import { Database } from 'lib/database.js' import { Database } from 'lib/database.js'
import { Registry } from 'lib/registry.js'
import { ItemList } from 'lib/components/item-list.js' import { ItemList } from 'lib/components/item-list.js'
import { NotesScreen } from 'lib/components/screens/notes.js' import { NotesScreen } from 'lib/components/screens/notes.js'
import { NoteScreen } from 'lib/components/screens/note.js' import { NoteScreen } from 'lib/components/screens/note.js'
@@ -191,7 +190,6 @@ class AppComponent extends React.Component {
componentDidMount() { componentDidMount() {
let db = new Database(new DatabaseDriverReactNative()); let db = new Database(new DatabaseDriverReactNative());
//db.setDebugEnabled(Registry.debugMode());
db.setDebugMode(false); db.setDebugMode(false);
BaseModel.dispatch = this.props.dispatch; BaseModel.dispatch = this.props.dispatch;
@@ -200,7 +198,6 @@ class AppComponent extends React.Component {
db.open({ name: '/storage/emulated/0/Download/joplin-42.sqlite' }).then(() => { db.open({ name: '/storage/emulated/0/Download/joplin-42.sqlite' }).then(() => {
Log.info('Database is ready.'); Log.info('Database is ready.');
Registry.setDb(db);
}).then(() => { }).then(() => {
Log.info('Loading settings...'); Log.info('Loading settings...');
return Setting.load(); return Setting.load();
@@ -224,12 +221,10 @@ class AppComponent extends React.Component {
Log.info('Client ID', Setting.value('clientId')); Log.info('Client ID', Setting.value('clientId'));
Log.info('User', user); Log.info('User', user);
Registry.api().setSession(user.session); // this.props.dispatch({
// type: 'USER_SET',
this.props.dispatch({ // user: user,
type: 'USER_SET', // });
user: user,
});
Log.info('Loading folders...'); Log.info('Loading folders...');
@@ -270,10 +265,6 @@ class AppComponent extends React.Component {
// return this.api_; // return this.api_;
// let synchronizer = new Synchronizer(db, Registry.api());
// let synchronizer = new Synchronizer(db, dropboxApi);
// Registry.setSynchronizer(synchronizer);
// synchronizer.start();
}).catch((error) => { }).catch((error) => {
Log.error('Initialization error:', error); Log.error('Initialization error:', error);
}); });

View File

@@ -1,50 +1,11 @@
// A service that handle notes and folders in a uniform way
// TODO: remote this service
// - Move setting of geo-location to GUI side (only for note explicitely created on client
// - Don't do diffing - make caller explicitely set model properties that need to be saved
import { BaseService } from 'lib/base-service.js';
import { BaseModel } from 'lib/base-model.js'; import { BaseModel } from 'lib/base-model.js';
import { BaseItem } from 'lib/models/base-item.js'; import { BaseItem } from 'lib/models/base-item.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 { Log } from 'lib/log.js'; import { Log } from 'lib/log.js';
import { time } from 'lib/time-utils.js'; import { time } from 'lib/time-utils.js';
import { Registry } from 'lib/registry.js';
class NoteFolderService extends BaseService { class NoteFolderService {
static save(type, item, oldItem, options = null) {
let diff = null;
if (oldItem) {
diff = BaseModel.diffObjects(oldItem, item);
if (!Object.getOwnPropertyNames(diff).length) {
Log.info('Item not changed - not saved');
return Promise.resolve(item);
}
}
let ItemClass = BaseItem.itemClass(item);
let isNew = !item.id;
let output = null;
let toSave = item;
if (diff !== null) {
toSave = diff;
toSave.id = item.id;
}
return ItemClass.save(toSave, options).then((savedItem) => {
output = Object.assign(item, savedItem);
if (isNew && type == 'note') return Note.updateGeolocation(output.id);
}).then(() => {
// Registry.synchronizer().start();
return output;
});
}
static openNoteList(folderId) { static openNoteList(folderId) {
return Note.previews(folderId).then((notes) => { return Note.previews(folderId).then((notes) => {

View File

@@ -1,15 +0,0 @@
import { BaseService } from 'lib/base-service.js';
class SessionService extends BaseService {
login(email, password, clientId) {
return this.api_.post('sessions', null, {
'email': email,
'password': password,
'client_id': clientId,
});
}
}
export { SessionService };

View File

@@ -1,6 +0,0 @@
import { isNode } from 'lib/env.js';
const FormData = require('form-data');
const fetch = require('node-fetch');
export { FormData, fetch };

View File

@@ -1,13 +0,0 @@
import { Registry } from 'lib/registry.js';
class BaseService {
constructor() {}
api() {
return Registry.api();
}
}
export { BaseService };

View File

@@ -1,175 +0,0 @@
import { Log } from 'lib/log.js';
import { isNode } from 'lib/env.js';
import { stringify } from 'query-string';
if (isNode()) {
// TODO: doesn't work in React-Native - FormData gets set to "undefined"
// Needs to be in a variable otherwise ReactNative will try to load this module (and fails due to
// missing node modules), even if isNode() is false.
let modulePath = 'src/shim.js';
var { fetch, FormData } = require(modulePath);
}
class WebApiError extends Error {
constructor(msg) {
let type = 'WebApiError';
// Create a regular JS Error object from a web api error response { error: "something", type: "NotFoundException" }
if (typeof msg === 'object' && msg !== null) {
if (msg.type) type = msg.type;
msg = msg.error ? msg.error : 'error';
}
super(msg);
this.type = type;
}
}
class WebApi {
constructor(baseUrl) {
this.baseUrl_ = baseUrl;
this.session_ = null;
this.retryInterval_ = 500;
}
setSession(v) {
this.session_ = v;
}
session() {
return this.session_;
}
// "form-data" node library doesn't like undefined or null values
// so make sure we only either return an empty string or a string
formatFormDataValue(v) {
if (v === undefined || v === null) return '';
return v.toString();
}
makeRequest(method, path, query, data) {
let url = this.baseUrl_;
if (path) url += '/' + path;
if (query) url += '?' + stringify(query);
let options = {};
options.method = method.toUpperCase();
if (data) {
let formData = null;
if (method == 'POST') {
formData = new FormData();
for (var key in data) {
if (!data.hasOwnProperty(key)) continue;
formData.append(key, this.formatFormDataValue(data[key]));
}
} else {
options.headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
formData = stringify(data);
}
options.body = formData;
}
return {
url: url,
options: options
};
}
static toCurl(r, data) {
let o = r.options;
let cmd = [];
cmd.push('curl');
if (o.method == 'PUT') cmd.push('-X PUT');
if (o.method == 'PATCH') cmd.push('-X PATCH');
if (o.method == 'DELETE') cmd.push('-X DELETE');
if (o.method != 'GET' && o.method != 'DELETE') {
cmd.push("--data '" + stringify(data) + "'");
}
cmd.push("'" + r.url + "'");
return cmd.join(' ');
}
delay(milliseconds) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, milliseconds);
});
}
exec(method, path, query, data) {
return this.execNoRetry(method, path, query, data).then((data) => {
this.retryInterval_ = 500;
return data;
}).catch((error) => {
if (error.errno == 'ECONNRESET') {
this.retryInterval_ += 500;
console.warn('Got error ' + error.errno + '. Retrying in ' + this.retryInterval_);
return this.delay(this.retryInterval_).then(() => {
return this.exec(method, path, query, data);
});
} else {
this.retryInterval_ = 500;
reject(error);
}
});
}
execNoRetry(method, path, query, data) {
if (this.session_) {
query = query ? Object.assign({}, query) : {};
if (!query.session) query.session = this.session_;
}
let r = this.makeRequest(method, path, query, data);
Log.debug(WebApi.toCurl(r, data));
//console.info(WebApi.toCurl(r, data));
return fetch(r.url, r.options).then((response) => {
let responseClone = response.clone();
if (!response.ok) {
return responseClone.text().then((text) => {
throw new WebApiError('HTTP ' + response.status + ': ' + response.statusText + ': ' + text);
});
}
return response.json().then((data) => {
if (data && data.error) {
throw new WebApiError(data);
} else {
return data;
}
}).catch((error) => {
return responseClone.text().then((text) => {
throw new WebApiError('Cannot parse JSON: ' + text);
});
});
});
}
get(path, query) {
return this.exec('GET', path, query);
}
post(path, query, data) {
return this.exec('POST', path, query, data);
}
put(path, query, data) {
return this.exec('PUT', path, query, data);
}
patch(path, query, data) {
return this.exec('PATCH', path, query, data);
}
delete(path, query) {
return this.exec('DELETE', path, query);
}
}
export { WebApi };