You've already forked joplin
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:
@@ -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() {
|
||||||
|
@@ -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';
|
||||||
|
@@ -1,7 +0,0 @@
|
|||||||
function isNode() {
|
|
||||||
if (typeof process === 'undefined') return false;
|
|
||||||
if (!process.release) return false;
|
|
||||||
return process.release.name === 'node';
|
|
||||||
}
|
|
||||||
|
|
||||||
export { isNode };
|
|
@@ -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
|
||||||
|
@@ -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 };
|
|
@@ -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);
|
||||||
});
|
});
|
||||||
|
@@ -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) => {
|
||||||
|
@@ -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 };
|
|
@@ -1,6 +0,0 @@
|
|||||||
import { isNode } from 'lib/env.js';
|
|
||||||
|
|
||||||
const FormData = require('form-data');
|
|
||||||
const fetch = require('node-fetch');
|
|
||||||
|
|
||||||
export { FormData, fetch };
|
|
@@ -1,13 +0,0 @@
|
|||||||
import { Registry } from 'lib/registry.js';
|
|
||||||
|
|
||||||
class BaseService {
|
|
||||||
|
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
api() {
|
|
||||||
return Registry.api();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export { BaseService };
|
|
175
lib/web-api.js
175
lib/web-api.js
@@ -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 };
|
|
Reference in New Issue
Block a user