diff --git a/CliClient/app/main.js b/CliClient/app/main.js index 6fca24176c..1a979cd8ba 100644 --- a/CliClient/app/main.js +++ b/CliClient/app/main.js @@ -918,16 +918,14 @@ async function main() { const filePath = options.path; function makeResponse(response) { - const output = { + return { ok: response.statusCode < 400, path: filePath, text: () => { return response.statusMessage; }, - json: () => { return ''; }, + json: () => { return { message: response.statusCode + ': ' + response.statusMessage }; }, status: response.statusCode, headers: response.headers, - } - console.info(output); - return output; + }; } const requestOptions = { @@ -948,9 +946,7 @@ async function main() { response.pipe(file); file.on('finish', function() { - console.info('FINISH'); file.close(() => { - console.info('FINISH CLOSE'); resolve(makeResponse(response)); }); }); diff --git a/CliClient/app/main.sh b/CliClient/app/main.sh deleted file mode 100644 index 09890a9da9..0000000000 --- a/CliClient/app/main.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash - -# Because all the files in the "lib" directory are included as "lib/file.js" it -# means "lib" must be in NODE_PATH, however modifying the global NODE_PATH -# variable would be messy. So instead, the path is set temporarily just before running -# the app. To do this, this bash wrapper is needed (also a messy solution, but node -# path resolution is messy anyway). See https://gist.github.com/branneman/8048520 - -# https://stackoverflow.com/questions/59895/getting-the-source-directory-of-a-bash-script-from-within -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - CLIENT_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - SOURCE="$(readlink "$SOURCE")" - [[ $SOURCE != /* ]] && SOURCE="$CLIENT_DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -CLIENT_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - -NODE_PATH="$CLIENT_DIR:$NODE_PATH" node "$CLIENT_DIR/main.js" "$@" \ No newline at end of file diff --git a/CliClient/package.json b/CliClient/package.json index 034e9f496c..2b2535ac85 100644 --- a/CliClient/package.json +++ b/CliClient/package.json @@ -7,7 +7,7 @@ "url": "https://github.com/laurent22/joplin" }, "url": "git://github.com/laurent22/joplin.git", - "version": "0.8.29", + "version": "0.8.30", "bin": { "joplin": "./main_launcher.js" }, diff --git a/ReactNativeClient/android/app/src/main/AndroidManifest.xml b/ReactNativeClient/android/app/src/main/AndroidManifest.xml index 2b893b4189..8db097b2c4 100644 --- a/ReactNativeClient/android/app/src/main/AndroidManifest.xml +++ b/ReactNativeClient/android/app/src/main/AndroidManifest.xml @@ -24,7 +24,8 @@ android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize" - android:windowSoftInputMode="adjustResize"> + android:windowSoftInputMode="adjustResize" + android:launchMode="singleInstance"> diff --git a/ReactNativeClient/clean_build.bat b/ReactNativeClient/clean_build.bat index 34101f0045..79c0f18810 100644 --- a/ReactNativeClient/clean_build.bat +++ b/ReactNativeClient/clean_build.bat @@ -1,4 +1,6 @@ @echo off rmdir /s/q android\app\build rmdir /s/q android\build -rmdir /s/q android\.gradle \ No newline at end of file +rmdir /s/q android\.gradle +rmdir /s/q node_modules +npm install \ No newline at end of file diff --git a/ReactNativeClient/lib/components/screen-header.js b/ReactNativeClient/lib/components/screen-header.js index 37d359bc9b..35fdaabcba 100644 --- a/ReactNativeClient/lib/components/screen-header.js +++ b/ReactNativeClient/lib/components/screen-header.js @@ -88,7 +88,6 @@ ScreenHeaderComponent.defaultProps = { const ScreenHeader = connect( (state) => { - console.info('CONNECT', state.historyCanGoBack); return { historyCanGoBack: state.historyCanGoBack, }; diff --git a/ReactNativeClient/main.js b/ReactNativeClient/main.js index b10f85b318..fce5997504 100644 --- a/ReactNativeClient/main.js +++ b/ReactNativeClient/main.js @@ -13,7 +13,6 @@ import { Root } from './root.js'; function main() { AppRegistry.registerComponent('Joplin', () => Root); console.ignoredYellowBox = ['Remote debugger']; - Log.info('START ======================================================================================================'); // Note: The final part of the initialization process is in // AppComponent.componentDidMount(), when the application is ready. } diff --git a/ReactNativeClient/root.js b/ReactNativeClient/root.js index ee60bc74d4..0b53e323d7 100644 --- a/ReactNativeClient/root.js +++ b/ReactNativeClient/root.js @@ -109,9 +109,6 @@ const reducer = (state = defaultState, action) => { } newState.historyCanGoBack = navHistory.length >= 2; - - console.info(navHistory.length, newState.historyCanGoBack); - break; // Replace all the notes with the provided array @@ -218,112 +215,125 @@ const AppNavigator = StackNavigator({ Notes: { screen: NotesScreen }, Note: { screen: NoteScreen }, Folder: { screen: FolderScreen }, - //Folders: { screen: FoldersScreen }, Loading: { screen: LoadingScreen }, OneDriveLogin: { screen: OneDriveLoginScreen }, Log: { screen: LogScreen }, }); +let initializationState_ = 'waiting'; + +async function initialize(dispatch) { + if (initializationState_ != 'waiting') return; + + initializationState_ = 'in_progress'; + + shim.fetchBlob = async function(url, options) { + if (!options || !options.path) throw new Error('fetchBlob: target file path is missing'); + if (!options.method) options.method = 'GET'; + + let headers = options.headers ? options.headers : {}; + let method = options.method ? options.method : 'GET'; + + let dirs = RNFetchBlob.fs.dirs; + let localFilePath = options.path; + if (localFilePath.indexOf('/') !== 0) localFilePath = dirs.DocumentDir + '/' + localFilePath; + + delete options.path; + + try { + let response = await RNFetchBlob.config({ + path: localFilePath + }).fetch(method, url, headers); + + // Returns an object that roughtly compatible with a standard Response object + let output = { + ok: response.respInfo.status < 400, + path: response.data, + text: response.text, + json: response.json, + status: response.respInfo.status, + headers: response.respInfo.headers, + }; + + return output; + } catch (error) { + throw new Error('fetchBlob: ' + method + ' ' + url + ': ' + error.toString()); + } + } + + Setting.setConstant('env', __DEV__ ? 'dev' : 'prod'); + Setting.setConstant('appId', 'net.cozic.joplin'); + Setting.setConstant('appType', 'mobile'); + Setting.setConstant('resourceDir', RNFetchBlob.fs.dirs.DocumentDir); + + const logDatabase = new Database(new DatabaseDriverReactNative()); + await logDatabase.open({ name: 'log.sqlite' }); + await logDatabase.exec(Logger.databaseCreateTableSql()); + reg.logger().addTarget('database', { database: logDatabase, source: 'm' }); + + reg.logger().info('===================================='); + reg.logger().info('Starting application ' + Setting.value('appId') + ' (' + Setting.value('env') + ')'); + + let db = new JoplinDatabase(new DatabaseDriverReactNative()); + reg.setDb(db); + + BaseModel.dispatch = dispatch; + NotesScreenUtils.dispatch = dispatch; + BaseModel.db_ = db; + + BaseItem.loadClass('Note', Note); + BaseItem.loadClass('Folder', Folder); + BaseItem.loadClass('Resource', Resource); + BaseItem.loadClass('Tag', Tag); + BaseItem.loadClass('NoteTag', NoteTag); + + try { + if (Setting.value('env') == 'prod') { + await db.open({ name: 'joplin.sqlite' }) + } else { + await db.open({ name: 'joplin-53.sqlite' }) + + // await db.exec('DELETE FROM notes'); + // await db.exec('DELETE FROM folders'); + // await db.exec('DELETE FROM tags'); + // await db.exec('DELETE FROM note_tags'); + // await db.exec('DELETE FROM resources'); + // await db.exec('DELETE FROM deleted_items'); + } + + reg.logger().info('Database is ready.'); + reg.logger().info('Loading settings...'); + await Setting.load(); + + reg.logger().info('Loading folders...'); + let initialFolders = await Folder.all(); + + dispatch({ + type: 'FOLDERS_UPDATE_ALL', + folders: initialFolders, + }); + + dispatch({ + type: 'APPLICATION_LOADING_DONE', + }); + + if (initialFolders.length) { + const selectedFolder = await Folder.defaultFolder(); + if (selectedFolder) NotesScreenUtils.openNoteList(selectedFolder.id); + } + } catch (error) { + reg.logger().error('Initialization error:', error); + } + + initializationState_ = 'done'; + + reg.logger().info('Application initialized'); +} + class AppComponent extends React.Component { async componentDidMount() { - - shim.fetchBlob = async function(url, options) { - if (!options || !options.path) throw new Error('fetchBlob: target file path is missing'); - if (!options.method) options.method = 'GET'; - - let headers = options.headers ? options.headers : {}; - let method = options.method ? options.method : 'GET'; - - let dirs = RNFetchBlob.fs.dirs; - let localFilePath = options.path; - if (localFilePath.indexOf('/') !== 0) localFilePath = dirs.DocumentDir + '/' + localFilePath; - - delete options.path; - - try { - let response = await RNFetchBlob.config({ - path: localFilePath - }).fetch(method, url, headers); - - // Returns an object that roughtly compatible with a standard Response object - let output = { - ok: response.respInfo.status < 400, - path: response.data, - text: response.text, - json: response.json, - status: response.respInfo.status, - headers: response.respInfo.headers, - }; - - return output; - } catch (error) { - throw new Error('fetchBlob: ' + method + ' ' + url + ': ' + error.toString()); - } - } - - Setting.setConstant('env', __DEV__ ? 'dev' : 'prod'); - Setting.setConstant('appId', 'net.cozic.joplin'); - Setting.setConstant('appType', 'mobile'); - Setting.setConstant('resourceDir', RNFetchBlob.fs.dirs.DocumentDir); - - const logDatabase = new Database(new DatabaseDriverReactNative()); - await logDatabase.open({ name: 'log.sqlite' }); - await logDatabase.exec(Logger.databaseCreateTableSql()); - reg.logger().addTarget('database', { database: logDatabase, source: 'm' }); - - reg.logger().info('Starting application ' + Setting.value('appId') + ' (' + Setting.value('env') + ')'); - - let db = new JoplinDatabase(new DatabaseDriverReactNative()); - reg.setDb(db); - - BaseModel.dispatch = this.props.dispatch; - NotesScreenUtils.dispatch = this.props.dispatch; - BaseModel.db_ = db; - - BaseItem.loadClass('Note', Note); - BaseItem.loadClass('Folder', Folder); - BaseItem.loadClass('Resource', Resource); - BaseItem.loadClass('Tag', Tag); - BaseItem.loadClass('NoteTag', NoteTag); - - try { - if (Setting.value('env') == 'prod') { - await db.open({ name: 'joplin.sqlite' }) - } else { - await db.open({ name: 'joplin-53.sqlite' }) - - // await db.exec('DELETE FROM notes'); - // await db.exec('DELETE FROM folders'); - // await db.exec('DELETE FROM tags'); - // await db.exec('DELETE FROM note_tags'); - // await db.exec('DELETE FROM resources'); - // await db.exec('DELETE FROM deleted_items'); - } - - reg.logger().info('Database is ready.'); - reg.logger().info('Loading settings...'); - await Setting.load(); - - reg.logger().info('Loading folders...'); - let initialFolders = await Folder.all(); - - this.props.dispatch({ - type: 'FOLDERS_UPDATE_ALL', - folders: initialFolders, - }); - - this.props.dispatch({ - type: 'APPLICATION_LOADING_DONE', - }); - - if (initialFolders.length) { - const selectedFolder = await Folder.defaultFolder(); - if (selectedFolder) NotesScreenUtils.openNoteList(selectedFolder.id); - } - } catch (error) { - Log.error('Initialization error:', error); - } + await initialize(this.props.dispatch); } sideMenu_change(isOpen) {