diff --git a/.eslintignore b/.eslintignore
index 581d7b51b..09c0e6297 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -803,6 +803,9 @@ packages/app-mobile/components/screens/Note.js.map
packages/app-mobile/components/screens/UpgradeSyncTargetScreen.d.ts
packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js
packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js.map
+packages/app-mobile/root.d.ts
+packages/app-mobile/root.js
+packages/app-mobile/root.js.map
packages/app-mobile/services/AlarmServiceDriver.android.d.ts
packages/app-mobile/services/AlarmServiceDriver.android.js
packages/app-mobile/services/AlarmServiceDriver.android.js.map
diff --git a/.gitignore b/.gitignore
index f712b9018..e7e20f32c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -792,6 +792,9 @@ packages/app-mobile/components/screens/Note.js.map
packages/app-mobile/components/screens/UpgradeSyncTargetScreen.d.ts
packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js
packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js.map
+packages/app-mobile/root.d.ts
+packages/app-mobile/root.js
+packages/app-mobile/root.js.map
packages/app-mobile/services/AlarmServiceDriver.android.d.ts
packages/app-mobile/services/AlarmServiceDriver.android.js
packages/app-mobile/services/AlarmServiceDriver.android.js.map
diff --git a/packages/app-mobile/index.js b/packages/app-mobile/index.js
index c4425c28e..d68426687 100644
--- a/packages/app-mobile/index.js
+++ b/packages/app-mobile/index.js
@@ -7,7 +7,7 @@
// So there's basically still a one way flux: React => SQLite => Redux => React
import { LogBox, AppRegistry } from 'react-native';
-const { Root } = require('./root.js');
+const Root = require('./root').default;
// Seems JavaScript developers love adding warnings everywhere, even when these warnings can't be fixed
// or don't really matter. Because we want important warnings to actually be fixed, we disable
diff --git a/packages/app-mobile/root.js b/packages/app-mobile/root.tsx
similarity index 89%
rename from packages/app-mobile/root.js
rename to packages/app-mobile/root.tsx
index 914d0c5fb..971819dab 100644
--- a/packages/app-mobile/root.js
+++ b/packages/app-mobile/root.tsx
@@ -1,24 +1,43 @@
import setUpQuickActions from './setUpQuickActions';
import PluginAssetsLoader from './PluginAssetsLoader';
+import AlarmService from '@joplin/lib/services/AlarmService';
+import Alarm from '@joplin/lib/models/Alarm';
+import time from '@joplin/lib/time';
+import Logger, { TargetType } from '@joplin/lib/Logger';
+import BaseModel from '@joplin/lib/BaseModel';
+import BaseService from '@joplin/lib/services/BaseService';
+import ResourceService from '@joplin/lib/services/ResourceService';
+import KvStore from '@joplin/lib/services/KvStore';
+import NoteScreen from './components/screens/Note';
+import UpgradeSyncTargetScreen from './components/screens/UpgradeSyncTargetScreen';
+import Setting from '@joplin/lib/models/Setting';
+import RNFetchBlob from 'rn-fetch-blob';
+import PoorManIntervals from '@joplin/lib/PoorManIntervals';
+import reducer from '@joplin/lib/reducer';
+import ShareExtension from './utils/ShareExtension';
+import handleShared from './utils/shareHandler';
+import uuid from '@joplin/lib/uuid';
+import { loadKeychainServiceAndSettings } from '@joplin/lib/services/SettingUtils';
+import KeychainServiceDriverMobile from '@joplin/lib/services/keychain/KeychainServiceDriver.mobile';
+import { setLocale, closestSupportedLocale, defaultLocale } from '@joplin/lib/locale';
+import SyncTargetJoplinServer from '@joplin/lib/SyncTargetJoplinServer';
+
const React = require('react');
const { AppState, Keyboard, NativeModules, BackHandler, Animated, View, StatusBar } = require('react-native');
const shim = require('@joplin/lib/shim').default;
shim.setReact(React);
+const DropdownAlert = require('react-native-dropdownalert').default;
+const AlarmServiceDriver = require('./services/AlarmServiceDriver').default;
const SafeAreaView = require('./components/SafeAreaView');
const { connect, Provider } = require('react-redux');
const { BackButtonService } = require('./services/back-button.js');
const NavService = require('@joplin/lib/services/NavService.js');
-const AlarmService = require('@joplin/lib/services/AlarmService.js').default;
-const AlarmServiceDriver = require('./services/AlarmServiceDriver').default;
-const Alarm = require('@joplin/lib/models/Alarm').default;
const { createStore, applyMiddleware } = require('redux');
const reduxSharedMiddleware = require('@joplin/lib/components/shared/reduxSharedMiddleware');
const { shimInit } = require('./utils/shim-init-react.js');
-const time = require('@joplin/lib/time').default;
const { AppNav } = require('./components/app-nav.js');
-const Logger = require('@joplin/lib/Logger').default;
const Note = require('@joplin/lib/models/Note.js');
const Folder = require('@joplin/lib/models/Folder.js');
const BaseSyncTarget = require('@joplin/lib/BaseSyncTarget.js');
@@ -29,16 +48,11 @@ const NoteTag = require('@joplin/lib/models/NoteTag.js');
const BaseItem = require('@joplin/lib/models/BaseItem.js');
const MasterKey = require('@joplin/lib/models/MasterKey.js');
const Revision = require('@joplin/lib/models/Revision.js');
-const BaseModel = require('@joplin/lib/BaseModel').default;
-const BaseService = require('@joplin/lib/services/BaseService').default;
-const ResourceService = require('@joplin/lib/services/ResourceService').default;
const RevisionService = require('@joplin/lib/services/RevisionService');
-const KvStore = require('@joplin/lib/services/KvStore').default;
const { JoplinDatabase } = require('@joplin/lib/joplin-database.js');
const { Database } = require('@joplin/lib/database.js');
const { NotesScreen } = require('./components/screens/notes.js');
const { TagsScreen } = require('./components/screens/tags.js');
-const NoteScreen = require('./components/screens/Note').default;
const { ConfigScreen } = require('./components/screens/config.js');
const { FolderScreen } = require('./components/screens/folder.js');
const { LogScreen } = require('./components/screens/log.js');
@@ -47,31 +61,18 @@ const { SearchScreen } = require('./components/screens/search.js');
const { OneDriveLoginScreen } = require('./components/screens/onedrive-login.js');
const { EncryptionConfigScreen } = require('./components/screens/encryption-config.js');
const { DropboxLoginScreen } = require('./components/screens/dropbox-login.js');
-const UpgradeSyncTargetScreen = require('./components/screens/UpgradeSyncTargetScreen').default;
-const Setting = require('@joplin/lib/models/Setting').default;
const { MenuContext } = require('react-native-popup-menu');
const { SideMenu } = require('./components/side-menu.js');
const { SideMenuContent } = require('./components/side-menu-content.js');
const { SideMenuContentNote } = require('./components/side-menu-content-note.js');
const { DatabaseDriverReactNative } = require('./utils/database-driver-react-native');
const { reg } = require('@joplin/lib/registry.js');
-const { setLocale, closestSupportedLocale, defaultLocale } = require('@joplin/lib/locale');
-const RNFetchBlob = require('rn-fetch-blob').default;
-const PoorManIntervals = require('@joplin/lib/PoorManIntervals').default;
-const reducer = require('@joplin/lib/reducer').default;
const { defaultState } = require('@joplin/lib/reducer');
const { FileApiDriverLocal } = require('@joplin/lib/file-api-driver-local.js');
-const DropdownAlert = require('react-native-dropdownalert').default;
-const ShareExtension = require('./utils/ShareExtension.js').default;
-const handleShared = require('./utils/shareHandler').default;
const ResourceFetcher = require('@joplin/lib/services/ResourceFetcher');
const SearchEngine = require('@joplin/lib/services/searchengine/SearchEngine');
const WelcomeUtils = require('@joplin/lib/WelcomeUtils');
const { themeStyle } = require('./components/global-style.js');
-const uuid = require('@joplin/lib/uuid').default;
-
-const { loadKeychainServiceAndSettings } = require('@joplin/lib/services/SettingUtils');
-const KeychainServiceDriverMobile = require('@joplin/lib/services/keychain/KeychainServiceDriver.mobile').default;
const SyncTargetRegistry = require('@joplin/lib/SyncTargetRegistry.js');
const SyncTargetOneDrive = require('@joplin/lib/SyncTargetOneDrive.js');
@@ -87,15 +88,16 @@ SyncTargetRegistry.addClass(SyncTargetWebDAV);
SyncTargetRegistry.addClass(SyncTargetDropbox);
SyncTargetRegistry.addClass(SyncTargetFilesystem);
SyncTargetRegistry.addClass(SyncTargetAmazonS3);
+SyncTargetRegistry.addClass(SyncTargetJoplinServer);
const FsDriverRN = require('./utils/fs-driver-rn.js').FsDriverRN;
const DecryptionWorker = require('@joplin/lib/services/DecryptionWorker');
const EncryptionService = require('@joplin/lib/services/EncryptionService');
const MigrationService = require('@joplin/lib/services/MigrationService');
-let storeDispatch = function() {};
+let storeDispatch = function(_action: any) {};
-const logReducerAction = function(action) {
+const logReducerAction = function(action: any) {
if (['SIDE_MENU_OPEN_PERCENT', 'SYNC_REPORT_UPDATE'].indexOf(action.type) >= 0) return;
const msg = [action.type];
@@ -104,7 +106,7 @@ const logReducerAction = function(action) {
// reg.logger().debug('Reducer action', msg.join(', '));
};
-const generalMiddleware = store => next => async (action) => {
+const generalMiddleware = (store: any) => (next: any) => async (action: any) => {
logReducerAction(action);
PoorManIntervals.update(); // This function needs to be called regularly so put it here
@@ -167,9 +169,9 @@ const generalMiddleware = store => next => async (action) => {
return result;
};
-const navHistory = [];
+const navHistory: any[] = [];
-function historyCanGoBackTo(route) {
+function historyCanGoBackTo(route: any) {
if (route.routeName === 'Note') return false;
if (route.routeName === 'Folder') return false;
@@ -194,13 +196,14 @@ const appDefaultState = Object.assign({}, defaultState, {
noteSideMenuOptions: null,
});
-const appReducer = (state = appDefaultState, action) => {
+const appReducer = (state = appDefaultState, action: any) => {
let newState = state;
let historyGoingBack = false;
try {
switch (action.type) {
+ // @ts-ignore
case 'NAV_BACK':
{
@@ -224,7 +227,7 @@ const appReducer = (state = appDefaultState, action) => {
{
const currentRoute = state.route;
- if (!historyGoingBack && historyCanGoBackTo(currentRoute, action)) {
+ if (!historyGoingBack && historyCanGoBackTo(currentRoute)) {
// If the route *name* is the same (even if the other parameters are different), we
// overwrite the last route in the history with the current one. If the route name
// is different, we push a new history entry.
@@ -368,7 +371,7 @@ const appReducer = (state = appDefaultState, action) => {
const store = createStore(appReducer, applyMiddleware(generalMiddleware));
storeDispatch = store.dispatch;
-function resourceFetcher_downloadComplete(event) {
+function resourceFetcher_downloadComplete(event: any) {
if (event.encrypted) {
DecryptionWorker.instance().scheduleStart();
}
@@ -378,9 +381,10 @@ function decryptionWorker_resourceMetadataButNotBlobDecrypted() {
ResourceFetcher.instance().scheduleAutoAddResources();
}
-async function initialize(dispatch) {
+async function initialize(dispatch: Function) {
shimInit();
+ // @ts-ignore
Setting.setConstant('env', __DEV__ ? 'dev' : 'prod');
Setting.setConstant('appId', 'net.cozic.joplin-mobile');
Setting.setConstant('appType', 'mobile');
@@ -391,18 +395,18 @@ async function initialize(dispatch) {
await logDatabase.exec(Logger.databaseCreateTableSql());
const mainLogger = new Logger();
- mainLogger.addTarget('database', { database: logDatabase, source: 'm' });
+ mainLogger.addTarget(TargetType.Database, { database: logDatabase, source: 'm' });
mainLogger.setLevel(Logger.LEVEL_INFO);
if (Setting.value('env') == 'dev') {
- mainLogger.addTarget('console');
+ mainLogger.addTarget(TargetType.Console);
mainLogger.setLevel(Logger.LEVEL_DEBUG);
}
Logger.initializeGlobalLogger(mainLogger);
reg.setLogger(mainLogger);
- reg.setShowErrorMessageBoxHandler((message) => { alert(message); });
+ reg.setShowErrorMessageBoxHandler((message: string) => { alert(message); });
BaseService.logger_ = mainLogger;
// require('@joplin/lib/ntpDate').setLogger(reg.logger());
@@ -411,9 +415,9 @@ async function initialize(dispatch) {
reg.logger().info(`Starting application ${Setting.value('appId')} (${Setting.value('env')})`);
const dbLogger = new Logger();
- dbLogger.addTarget('database', { database: logDatabase, source: 'm' });
+ dbLogger.addTarget(TargetType.Database, { database: logDatabase, source: 'm' });
if (Setting.value('env') == 'dev') {
- dbLogger.addTarget('console');
+ dbLogger.addTarget(TargetType.Console);
dbLogger.setLevel(Logger.LEVEL_INFO); // Set to LEVEL_DEBUG for full SQL queries
} else {
dbLogger.setLevel(Logger.LEVEL_INFO);
@@ -452,7 +456,7 @@ async function initialize(dispatch) {
if (Setting.value('env') == 'prod') {
await db.open({ name: 'joplin.sqlite' });
} else {
- await db.open({ name: 'joplin-76.sqlite' });
+ await db.open({ name: 'joplin-100.sqlite' });
// await db.clearForTesting();
}
@@ -562,7 +566,7 @@ async function initialize(dispatch) {
reg.setupRecurrentSync();
PoorManIntervals.setTimeout(() => {
- AlarmService.garbageCollect();
+ void AlarmService.garbageCollect();
}, 1000 * 60 * 60);
ResourceService.runInBackground();
@@ -584,7 +588,7 @@ async function initialize(dispatch) {
reg.scheduleSync(1000).then(() => {
// Wait for the first sync before updating the notifications, since synchronisation
// might change the notifications.
- AlarmService.updateAllNotifications();
+ void AlarmService.updateAllNotifications();
DecryptionWorker.instance().scheduleStart();
});
@@ -654,7 +658,7 @@ class AppComponent extends React.Component {
BackButtonService.initialize(this.backButtonHandler_);
- AlarmService.setInAppNotificationHandler(async (alarmId) => {
+ AlarmService.setInAppNotificationHandler(async (alarmId: string) => {
const alarm = await Alarm.load(alarmId);
const notification = await Alarm.makeNotification(alarm);
this.dropdownAlert_.alertWithType('info', notification.title, notification.body ? notification.body : '');
@@ -666,7 +670,7 @@ class AppComponent extends React.Component {
if (sharedData) {
reg.logger().info('Received shared data');
if (this.props.selectedFolderId) {
- handleShared(sharedData, this.props.selectedFolderId, this.props.dispatch);
+ await handleShared(sharedData, this.props.selectedFolderId, this.props.dispatch);
} else {
reg.logger.info('Cannot handle share - default folder id is not set');
}
@@ -677,7 +681,7 @@ class AppComponent extends React.Component {
AppState.removeEventListener('change', this.onAppStateChange_);
}
- componentDidUpdate(prevProps) {
+ componentDidUpdate(prevProps: any) {
if (this.props.showSideMenu !== prevProps.showSideMenu) {
Animated.timing(this.state.sideMenuContentOpacity, {
toValue: this.props.showSideMenu ? 0.5 : 0,
@@ -707,14 +711,14 @@ class AppComponent extends React.Component {
return false;
}
- UNSAFE_componentWillReceiveProps(newProps) {
+ UNSAFE_componentWillReceiveProps(newProps: any) {
if (newProps.syncStarted != this.lastSyncStarted_) {
if (!newProps.syncStarted) FoldersScreenUtils.refreshFolders();
this.lastSyncStarted_ = newProps.syncStarted;
}
}
- sideMenu_change(isOpen) {
+ sideMenu_change(isOpen: boolean) {
// Make sure showSideMenu property of state is updated
// when the menu is open/closed.
this.props.dispatch({
@@ -759,8 +763,8 @@ class AppComponent extends React.Component {
menu={sideMenuContent}
edgeHitWidth={5}
menuPosition={menuPosition}
- onChange={(isOpen) => this.sideMenu_change(isOpen)}
- onSliding={(percent) => {
+ onChange={(isOpen: boolean) => this.sideMenu_change(isOpen)}
+ onSliding={(percent: number) => {
this.props.dispatch({
type: 'SIDE_MENU_OPEN_PERCENT',
value: percent,
@@ -773,7 +777,7 @@ class AppComponent extends React.Component {
- this.dropdownAlert_ = ref} tapToCloseEnabled={true} />
+ this.dropdownAlert_ = ref} tapToCloseEnabled={true} />
@@ -783,7 +787,7 @@ class AppComponent extends React.Component {
}
}
-const mapStateToProps = (state) => {
+const mapStateToProps = (state: any) => {
return {
historyCanGoBack: state.historyCanGoBack,
showSideMenu: state.showSideMenu,
@@ -799,7 +803,7 @@ const mapStateToProps = (state) => {
const App = connect(mapStateToProps)(AppComponent);
-class Root extends React.Component {
+export default class Root extends React.Component {
render() {
return (
@@ -808,5 +812,3 @@ class Root extends React.Component {
);
}
}
-
-module.exports = { Root };
diff --git a/packages/app-mobile/utils/shareHandler.ts b/packages/app-mobile/utils/shareHandler.ts
index 556086790..790a5943b 100644
--- a/packages/app-mobile/utils/shareHandler.ts
+++ b/packages/app-mobile/utils/shareHandler.ts
@@ -24,9 +24,9 @@ export default async (sharedData: SharedData, folderId: string, dispatch: Functi
// below will do nothing (because routeName wouldn't change)
// Then we wait a bit for the state to be set correctly, and
// finally we go to the new note.
- await dispatch({ type: 'NAV_BACK' });
+ dispatch({ type: 'NAV_BACK' });
- await dispatch({ type: 'SIDE_MENU_CLOSE' });
+ dispatch({ type: 'SIDE_MENU_CLOSE' });
const newNote = await Note.save({
parent_id: folderId,
diff --git a/packages/lib/BaseModel.ts b/packages/lib/BaseModel.ts
index 872523e5e..c5b56b862 100644
--- a/packages/lib/BaseModel.ts
+++ b/packages/lib/BaseModel.ts
@@ -66,7 +66,7 @@ class BaseModel {
public static TYPE_SMART_FILTER = ModelType.SmartFilter;
public static TYPE_COMMAND = ModelType.Command;
- protected static dispatch: Function = function() {};
+ public static dispatch: Function = function() {};
private static saveMutexes_: any = {};
private static db_: any;